用Java编程一个国际象棋游戏,gameOver布尔不起作用

用Java编程一个国际象棋游戏,gameOver布尔不起作用,java,chess,Java,Chess,我正在尝试用Java制作一个可以在控制台上玩的国际象棋游戏。对于每一步,游戏都会要求玩家提供一个棋子(例如第二行第三列的棋子为12)和最终位置(例如第四行第三列的棋子为32)。一切都很顺利,包括测试移动是否非法以及给定玩家是否处于检查状态,但我的gameOver布尔值似乎在要求第一次移动之前更改了我的棋盘数组的值 这是相关代码。根据我的主要方法: public static void main(String[] args) { int[][] board = { {12, 13, 1

我正在尝试用Java制作一个可以在控制台上玩的国际象棋游戏。对于每一步,游戏都会要求玩家提供一个棋子(例如第二行第三列的棋子为12)和最终位置(例如第四行第三列的棋子为32)。一切都很顺利,包括测试移动是否非法以及给定玩家是否处于检查状态,但我的gameOver布尔值似乎在要求第一次移动之前更改了我的棋盘数组的值

这是相关代码。根据我的主要方法:

public static void main(String[] args) {
    int[][] board = {   {12, 13, 14, 15, 16, 14, 13, 12},
                        {11, 11, 11, 11, 11, 11, 11, 11},
                        {0,  0,  0,  0,  0,  0,  0,  0},
                        {0,  0,  0,  0,  0,  0,  0,  0},
                        {0,  0,  0,  0,  0,  0,  0,  0},
                        {0,  0,  0,  0,  0,  0,  0,  0},
                        {21, 21, 21, 21, 21, 21, 21, 21},
                        {22, 23, 24, 25, 26, 24, 23, 22}
                    };
    Scanner scan = new Scanner(System.in);
    boolean oneTurn = true;
    while(!(gameOver(oneTurn, board))) {
        printBoard(board);
        System.out.println(((oneTurn) ? "1's" : "2's") +  " turn");
        System.out.print("What piece? ");
        int origin = scan.nextInt();
gameOver布尔值,用于测试当前玩家是否可以进行合法且不会检查玩家的任何移动:

public static boolean gameOver(boolean oneTurn, int[][] board) {
    for (int a = 0; a<8; a++) {
        for(int b = 0; b<8; b++) {
            for (int c = 0; c<8; c++) {
                for(int d = 0; d<8; d++) {
                    if(board[a][b] / 10 == (oneTurn ? 1 : 2) && !(illegal(oneTurn, 10*a+b, 10*c+d, board)) && !(illegalCheck(oneTurn, 10*a+b, 10*c+d, board))) return false;
                }
            }
        }
    }
    return true;
}
当我第一次运行程序时,我得到的第一个输出是:

    |  0 |  1 |  2 |  3 |  4 |  5 |  6 |  7 |
_____________________________________________

0   | 1R |    | 1B | 1Q | 1K | 1B | 1N | 1R |
_____________________________________________

1   | 1P | 1P | 1P | 1P | 1P | 1P | 1P | 1P |
_____________________________________________

2   |    |    |    |    |    |    |    |    |
_____________________________________________

3   |    |    |    |    |    |    |    |    |
_____________________________________________

4   |    |    |    |    |    |    |    |    |
_____________________________________________

5   |    |    |    |    |    |    |    |    |
_____________________________________________

6   | 2P | 2P | 2P | 2P | 2P | 2P | 2P | 2P |
_____________________________________________

7   | 2R | 2N | 2B | 2Q | 2K | 2B | 2N | 2R |
_____________________________________________

1's turn
What piece? 
gameOver发现的第一个合法移动是骑士移动,所以我认为这就是为什么骑士没有出现在第一个棋盘上。当我将printBoard方法置于布尔测试之前时,电路板可以完美打印


我最近才开始学习编程,所以我希望能得到任何关于为什么会发生这种情况的建议。这可能是我明显遗漏的东西。让我知道,如果有其他细节,我可以提供。谢谢大家!

如果您认为这是由于数组的副本造成的,请尝试非法检查中的
System.arraycopy

我建议使用调试器并设置一些断点,这样您就可以查看到底发生了什么,这样您就不会猜到了

有关使用java调试会话的详细信息:

当您编写

int[][] newBoard = board;
newBoard[dest / 10][dest % 10] = board[origin / 10][origin % 10];
newBoard[origin / 10][origin % 10] = 0;
您正在创建
newBoard
,作为对与
board
相同的数组对象的新引用,然后继续修改数组。您可以这样复制它:

int[][] newBoard = new int[8][];
for (int i = 0; i < newBoard.length; ++i)
    newBoard[i] = board[i].clone();
int[]newBoard=newint[8][];
对于(int i=0;i

Java的多维数组是对其他数组的引用数组(因为数组是对象),所以首先我们创建一个新的顶级数组,然后将辅助数组的副本分配给它。(关于
Object.clone()
Cloneable
有一系列规则,但这里您需要知道的是,克隆数组会生成具有相同值的新数组。对于多维数组,这是一个浅拷贝(拷贝指的是相同的子数组),因此我们不能只调用
board.clone()
然后用它完成。)

您的gameOver函数根本不可读。选择一些有意义的变量名而不尝试太花哨有多难?!!!还不错。只是没必要。还有,为什么它不可读?为什么它“太花哨”?请随意编辑,不要有绒毛。很抱歉不够清晰。我原以为这对我自己来说是一个快速学习的项目,只有我会读代码,但这个小问题让我很沮丧,不得不求助于外部资源。gameOver中的字母只是数组的索引(a行,b列到c行,d列)。illegalCheck可能是一个错误的变量名,但它测试从ab移动到cd是否会检查播放机;系统阵列副本(板,0,新板,0,板长度);但它不起作用。这是arraycopy的正确用法吗?谢谢你的帮助!谢谢你的提示。我绝对没有调试器方面的经验,但我会尝试一下。你知道布尔值是如何用不同的方法改变变量的吗?我的理解是,变量只能在它们自己的方法中更改,但在这种情况下,这似乎是不正确的。我还没有真正看完整的代码,如果您需要帮助,您可以创建一个复制相同行为的测试用例,如果需要,编辑您的问题并只发布测试用例。另外,我没有看到gameOver布尔变量,而是看到了一个具有该标识符的方法。做一个测试用例或者使用一个调试器,这应该是你最好的选择。谢谢你,我认为这个解决方案有效!因此,作为将来的参考,很明显,在整个程序中,每个顶级阵列都在访问相同的二级阵列。但是顶级数组是否也完全相同,或者我可以有两个名为board的数组,它们引用了不同的东西?您可以有两个名为
board
的引用,它们指向不同的数组,是的。(例如,如果一个类有一个名为
board
的字段,那么该类的每个实例都可以引用该字段中的不同数组。类似地,使用不同或递归方法的局部变量。)数组本身不知道引用指向它们的是什么。但是仅仅分配
board=…
不会创建新数组,除非
包含
new
或调用一个库函数来返回一个新数组。
int[][] newBoard = board;
newBoard[dest / 10][dest % 10] = board[origin / 10][origin % 10];
newBoard[origin / 10][origin % 10] = 0;
int[][] newBoard = new int[8][];
for (int i = 0; i < newBoard.length; ++i)
    newBoard[i] = board[i].clone();