チェスピースが特定の動きをしないようにブロックされているかどうかを判断するには、次の方法が使用されます。このメソッドが呼び出された時点で、モーション自体(つまり、ビショップの対角線移動能力)は既に検証済みです。このメソッドは、そのピースが受けなければならない「パス」を調べます。このスニペットのロジックはどのように抽象化できますか?
わかりやすく、この方法は冗長性に満ちています。実際には、6つのほぼ同じfor-loopsがあります。その違いは、1)どの変数が反復を制御しているか、2)変数が増減しているかどうか、3)対角線方向の動きの場合は、 xとyの両方の変数を同時にインクリメント/デクリメントするステートメント。
私はこれらのステートメントを別の方法に抽象化しようと多くの試みを行ってきました。残念ながら、制限要因はボードにアクセスする必要がありました。[x] - ロジックを抽象化しようとしたとき、私はの視野を失います。変数はyを表し、xはどれですか。
これは私の質問です。Javaがこのロジックを抽象化し、この方法で冗長性を減らすか排除するためのツールはありますか?私は言語にはかなり新しいことを指摘しますので、意図的に、または単に鈍いとして、共通のイディオムを無視しないでください。勉強中です!
ありがとうございました。
private static boolean notBlocked(Piece[][] board, int xfrom, int yfrom, int xto, int yto) {
int x = xfrom;
int xstop = xto;
int y = yfrom;
int ystop = yto;
int xinc = (x < xstop) ? 1 : -1;
int yinc = (y < ystop) ? 1 : -1;
Piece to = board[yto][xto];
Piece from = board[yfrom][xfrom];
if (xfrom == xto) {
// x is constant, check in y direction
if (y <= ystop) {
for (; y <= ystop; y += yinc) {
if (board[y][x] != null && board[y][x] != to && board[y][x] != from) {
return false;
}
}
} else {
for (; y >= ystop; y += yinc) {
if (board[y][x] != null && board[y][x] != to && board[y][x] != from) {
return false;
}
}
}
} else if (yfrom == yto) {
// y is constant, check in x direction
if (x <= xstop) {
for (; x <= xstop; x += xinc) {
if (board[y][x] != null && board[y][x] != to && board[y][x] != from) {
return false;
}
}
} else {
for (; x >= xstop; x += xinc) {
if (board[y][x] != null && board[y][x] != to && board[y][x] != from) {
return false;
}
}
}
} else if (Math.abs(xfrom - xto) == Math.abs(yfrom - yto)){
// the move is diagonal
if (y <= ystop) {
for (; y <= ystop; y += yinc) {
if (board[y][x] != null && board[y][x] != to && board[y][x] != from) {
return false;
}
x += xinc;
}
} else {
for (; y >= ystop; y += yinc) {
if (board[y][x] != null && board[y][x] != to && board[y][x] != from) {
return false;
}
x += xinc;
}
}
}
return true;
}
EDIT:今より良い
うわー!
private static boolean notBlocked(Piece[][] board, int xfrom, int yfrom, int xto, int yto) {
Piece from = board[yfrom][xfrom];
Piece to = board[yto][xto];
// Determine the direction (if any) of x and y movement
int dx = (xfrom < xto) ? 1 : ((xfrom == xto) ? 0 : -1);
int dy = (yfrom < yto) ? 1 : ((yfrom == yto) ? 0 : -1);
// Determine the number of times we must iterate
int steps = Math.max(Math.abs(xfrom - xto), Math.abs(yfrom - yto));
if (xfrom == xto || yfrom == yto || Math.abs(xfrom - xto) == Math.abs(yfrom - yto)) {
for (int i = 1; i < steps; i++) {
int x = xfrom + i * dx;
int y = yfrom + i * dy;
if (isBlocked(board, from, to, x, y)) {
return false;
}
}
}
return true;
}
ありがとうございました!これは明らかに優れた見通しです。私は方向を感謝します。 –