Следующий метод используется, чтобы определить, заблокирована ли шахматная фигура для выполнения определенного хода.В тот момент, когда этот метод вызывается, само движение (т. Е. Способность епископа двигаться по диагонали) уже было проверено - этот метод затем будет смотреть на «путь», по которому должна идти фигура.
Какбольно ясно, этот метод полон избыточности.На самом деле существует 6 почти идентичных циклов for, различия в которых: 1) какие переменные контролируют итерацию, 2) увеличивается или уменьшается переменная, и 3) в случае диагонального движения включениеоператор для увеличения / уменьшения обеих переменных x и y одновременно.
Я делал многочисленные попытки абстрагировать эти операторы в отдельный метод.К сожалению, ограничивающим фактором была необходимость доступа к плате [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;
}
РЕДАКТИРОВАТЬ:
Ого ... теперь намного лучше!
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;
}