问题描述
我正在编写一个基本的Java国际象棋游戏,并编写了以下类:游戏,玩家,棋盘,广场,棋子(每个特定棋子的超类),以及每个特定的棋子类(例如Pawn,Knight,Bishop等。 )
其中一个棘手的方法是根据是否导致移动的玩家受到检查来确定移动是否有效。 我的解决方案如下:
- 克隆当前董事会
- 移动
- 看看移动的球员是否在检查中
- 如果是的话,禁止移动; 否则,允许移动
我正在考虑如何从这里克隆: http://www.jusfortechies.com/java/core-java/cloning.php
: http://www.jusfortechies.com/java/core-java/cloning.php
现在,board对象由2d Square对象组成。 每个方形对象都有一个零件字段,该字段为空(在其上没有任何部分)或引用一个部件对象(在其上有一个部分)。 Board对象还有一个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个方块分别克隆板子,我的克隆尝试会不会搞乱?
1楼
我有另一种解决方案,看看你是否喜欢这个。
没有必要使用clone
!
我刚才写了一个中国象棋程序。
让我解释一下我做了什么:(这只是一个大纲,你必须自己做细节)
我的2D阵列Piece
S和按钮中的另一个2D阵列。
当用户点击Piece时,会调用Piece
类中的抽象方法getValidLocations
,并且此方法返回一组坐标以指示Piece
可以去哪里。
当用户点击按钮时,该块移动到按钮的位置。
坏消息是,我不知道如何下棋。
我只知道中国象棋,所以我不能告诉你如何编写getValidLocations
的算法,对不起!
2楼
不要使用clone()
。
它被破坏而是制作完整的电路板。
以下是
通过进行深度复制,每个部件都有不同的对象,因此移动它们不会弄乱另一个代表另一个移动的板中相应部件的状态。
在所有部分上创建一个copy()
方法以允许它们制作所有内部状态的有效副本可能是有意义的。
示例复制方法:
让我们假装你的Pawn
类有一个变量,如果它之前已经移动过。
这确定它是否可以移动2个空格或仅移动1个空格。
class Pawn{
private boolean hasMovedAlready=false;
...
public Pawn copy(){
return new Pawn(hasMovedAlready, ...);
}