【发布时间】:2015-07-26 22:04:17
【问题描述】:
我正在编写一个基本的 Java 国际象棋游戏并编写了以下类:Game、Player、Board、Square、Piece(每个特定棋子的超类)和每个特定棋子类(例如 Pawn、Knight、Bishop等)
其中一个比较棘手的方法是根据是否导致移动的玩家被检查来确定移动是否有效。我的解决方案如下:
- 克隆当前板
- 行动
- 查看移动玩家是否在检查中
- 如果是,禁止移动;否则,允许移动
我正在了解如何从这里克隆:http://www.jusfortechies.com/java/core-java/cloning.php
现在,棋盘对象由 Square 对象的二维数组组成。每个方形对象都有一个片段字段,该字段要么为空(上面没有片段),要么引用片段对象(上面有片段)。棋盘对象还有一个 whiteKingSquare 和一个 blackKingSquare(两者都是 Square 对象),以便更快/更轻松地定位白王或黑王。
我在 Board 类中编写了以下方法:
public Object clone() throws CloneNotSupportedException {
Board clonedBoard = (Board) super.clone();
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
clonedBoard.myBoard[i][j] = new Square(this, i, j);
clonedBoard.whiteKingSquare = myBoard[7][4];
clonedBoard.blackKingSquare = myBoard[0][4];
}
}
return clonedBoard;
}
但是,因为 Board 引用了一个 8 x 8 的 Square 对象数组,所以我必须克隆每个对象。我在 Square 类中编写了这个方法:
public Object clone() throws CloneNotSupportedException {
return (Square) super.clone();
}
最后,我在 Piece 类中编写了这个方法:
public Object clone() throws CloneNotSupportedException {
return (Piece) super.clone();
}
关于问题:
- 这看起来大致正确吗?
- 我的 Square 对象也有一个 Board 字段,基本上可以让我 参考他们所属的董事会。这会不会影响我的尝试 通过让我的 64 个方块中的每一个分别克隆板来克隆?
【问题讨论】:
-
请参阅this incredibly simple solution 以克隆对象。第二个问题的答案:是的,它会干扰你的尝试,因为方块仍然有原始参考。
-
@pietv8x 谢谢;我需要为 Board 对象中引用的每个对象提供复制构造函数吗?
-
要么,要么坚持使用
clone()。例如,在我的 2048 游戏中,我采用了类似的方法来检查 AI 移动的有效性。请参阅this 方法。它非常有效地重新创建了所有图块,它是一个深层副本。 -
你为什么不记住某个变量中的前一个位置,如果移动不检查,只需将棋子放回前一个位置?我不知道您的代码,但在我看来,这似乎是最简单的解决方案。至少我会这样做,因为这是一次一步的游戏。
-
我认为你不应该使用克隆。我以前做过一个中国象棋程序。它的工作原理是这样的,如果用户选择了一个片段,然后点击监听器被执行。然后它调用一个名为 getValidLocations 的方法。它返回一个 xy 坐标数组,并将按钮放在这些线上。你明白我的意思吗?你不需要检查移动是否有效。