java - 这段代码的逻辑如何抽象?

标签 java arrays for-loop boolean

下面的方法用于判断棋子是否被阻挡,无法进行某一步棋。在调用此方法时,运动本身(即 Bishop 沿对角线移动的能力)已经得到验证 - 然后此方法将查看棋子必须采取的“路径”。

令人痛苦的是,这种方法充满了冗余。事实上,有 6 个几乎相同的 for 循环,区别在于 1) 哪些变量控制迭代,2) 变量是递增还是递减,3) 在对角线运动的情况下,包含同时递增/递减 x 和 y 变量的语句。

我已经多次尝试将这些语句抽象为一个单独的方法。不幸的是,限制因素是需要访问 board[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;
}

最佳答案

考虑以正确方向的一步来编写此函数。假设您可以填写两个变量 dx 和 dy,它们代表每一步在 x 和 y 方向上移动的距离。您可以通过查看起始和结束 x 和 y 位置之间的差异来计算此值。一旦完成,您就可以编写一个 for 循环来尝试沿着该方向移动,检查每个步骤。例如:

for (int i = 1; i < numStepsRequired; i++) {
    int currX = x + i * dx;
    int currY = y + i * dy;
    if (board[currY][currX] != null) {
        return false;
    }
}

您还需要计算需要多少步,只要您计算 dx 和 dy,这也很简单。我将把它作为练习,因为这是很好的编程实践。

希望这有帮助!

关于java - 这段代码的逻辑如何抽象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9541169/

相关文章:

java - JavaFx 中的生产者-消费者应用程序(从任务到 "update"两个文本字段获取正确值的问题)

javascript - 如何对对象的值求和并将其放入数组中

我可以通过更好的数组操作来优化此代码吗?

java - 为什么CopyOnWriteArrayList的迭代器允许在增强型for循环中使用remove(),而它的迭代器不支持remove()操作?

java - 应用程序请求为空后使用 Autowired 获取实例

java - 线程中断时 finally 阻塞的行为

com/fasterxml/jackson/databind/ObjectMapper 与 Maven 的 java.lang.ClassNotFoundException/NoClassDefFoundError

python multiprocessing.Array : huge temporary memory overhead

java - 如何在类注册表中正确使用for循环?

java - 碰撞检测 - 任何语言