【问题标题】:Chess, checking if path is free is not working correctly [closed]国际象棋,检查路径是否空闲无法正常工作[关闭]
【发布时间】:2018-01-08 15:38:07
【问题描述】:

我正在使用 Swing 在 Java 中下象棋,并且我已经想出了如何检查每个棋子的合法移动。那部分没有任何问题。但是现在,我在检查路径是否空闲时遇到了问题。例如,国际象棋中的所有棋子都不能跳过一个棋子,除非它是马。如果一个棋子挡住了主教的路径,它不能超过棋子。我调用了检查路径是否空闲的方法isVectorFree()。它适用于水平和垂直路径,但不适用于对角路径。

这是isVectorFree()的代码:

public boolean isVectorFree(int x1, int y1, int x2, int y2) {
    if (x1 == x2 && y1 > y2) { // horizontal north
        for (int i = y1 - 1; i > y2; i--) {
            if (piecePositions[i][x1] != null) {
                return false;
            }
        }
    } else if (x1 < x2 && y1 == y2) { // horizontal east
        for (int i = x1 + 1; i < x2; i++) {
            if (piecePositions[y1][i] != null) {
                return false;
            }
        }
    } else if (x1 == x2 && y1 < y2) { // horizontal south
        for (int i = y1 + 1; i < y2; i++) {
            if (piecePositions[i][x1] != null) {
                return false;
            }
        }
    } else if (x1 > x2 && y1 == y2) { // horizontal west
        for (int i = x1 - 1; i > x2; i--) {
            if (piecePositions[y1][i] != null) {
                return false;
            }
        }
    }
    else if (x1 < x2 && y1 > y2) { // diagonal northeast
        // these diagonals aren't working properly
        for (int row = x1 + 1; row < x2; row++) {
            for (int col = y1 - 1; col >= y2; col--) {
                if (piecePositions[row][col] != null) {
                    return false;
                }
            }
        }
    } else if (x1 < x2 && y1 < y2) { // diagonal southeast
        for (int row = x1 + 1; row < x2; row++) {
            for (int col = y1 + 1; col < y2; col++) {
                if (piecePositions[row][col] != null) {
                    return false;
                }
            }
        }
    } else if (x1 > x2 && y1 < y2) { // diagonal southwest
        for (int row = x1 - 1; row >= x2; row--) {
            for (int col = y1 + 1; col < y2; col++) {
                if (piecePositions[row][col] != null) {
                    return false;
                }
            }
        }
    } else if (x1 > x2 && y1 > y2) { // diagonal northwest
        for (int row = x1 - 1; row >= x2; row--) {
            for (int col = y1 - 1; col >= y2; col--) {
                if (piecePositions[row][col] != null) {
                    return false;
                }
            }
        }
    }
    return true;
}

此方法获取矩阵piecePositions中的棋子x坐标x1和y坐标y1以及所需的x坐标x2和所需的y坐标y2,以查看当前之间的路径是否坐标和所需坐标是免费的,但正如我之前所说,这不适用于对角线。具体来说,isVectorFree() 受到周围碎片的影响。在棋盘的起始位置,如果我将棋子移开为主教让路,即使道路现在对主教来说是空闲的,由于某种原因,它仍然无法在整个路径中移动。

我该如何解决这个问题?

【问题讨论】:

标签: java swing matrix chess


【解决方案1】:

您的嵌套 for 循环意味着您正在对角线方向(整个正方形)检查该方向的所有内容。所以,如果你在 (0,0) 并试图移动到 (3,3) 你的代码正在检查 (1,1), (1,2), (1,3), (2,1), ( 2,2)、(2,3)、(3,1)、(3,2) 和 (3,3)。您只想检查路径 (1,1), (2,2), (3,3)。

假设移动有效(即abs(y1 - y2) == abs(x1 - x2)),循环遍历差异而不是坐标本身:

} else if (x1 < x2 && y1 > y2) { // diagonal northeast
    for (int i = x2 - x1; i > 0; i--) {
        if (piecePositions[x1 + i][y1 - i] != null) {
            return false;
        }
    }
}

【讨论】:

  • 我同意您对我的 for 循环如何不起作用的评估,但您的代码似乎不起作用。使用后我仍然遇到与之前相同的问题。
  • 这是四个方向之一的示例,可用作您修复其他三个方向的模式。由于您的 (0,0) 在左上角,让我们从 (3,5) 移动到 (6,2)。 ix2-x1 开头,即 6-3==3。第一个循环,我们检查(x1+i,y1-i)(3+3,5-3)==(6,2)。然后我们递减i3-1==2,并检查(3+2,5-2)==(5,3),然后再减少i=1 并检查(3+1,5-1)==(4,4),我们就完成了。其他方向将需要更改,例如是加还是减 i,以及 i 是从 x1 - x2 还是 x2 - x1 开始。
【解决方案2】:

在特定的对角线上,每一行每一列都是唯一的,不是吗?

如果 (2,4) 在您的对角线上,则 (2,3) 不能在同一条对角线上。

现在查看您的 for 循环,对于每个行值,您会循环几个列。

你应该有一个循环,比如说索引 i,然后用 i 的值递增/递减 row 和 col。

【讨论】:

  • 谢谢,我刚刚从调试中意识到这一点。实际上,在我使用嵌套的 for 循环之前,我确实使用了一个循环来增加/减少行和列,但我不知道如何使循环在板的末端停止。我该怎么做?
  • if() 语句存在是有原因的
  • 由于 (x1,y1) 和 (x2,y2) 都在棋盘上,因此增量器 Math.abs(x2 - x1) 的范围不会让您离开棋盘。 (假设两个点确实在同一对角线上;即:Math.abs(x2-x1) == Math.abs(y2-y1),也许你应该检查一下。)
  • 没关系,我让它完美地工作。我不得不翻转 x 和 y 值。出于某种原因,到目前为止,我每次处理坐标时都必须这样做。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2022-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-24
  • 1970-01-01
  • 2015-01-02
  • 1970-01-01
相关资源
最近更新 更多