Java国际象棋:不确定如何正确克隆

时间:2015-07-26 22:04:17

标签: java oop

我正在编写一个基本的Java国际象棋游戏,并编写了以下类:游戏,玩家,棋盘,广场,棋子(每个特定棋子的超类),以及每个特定棋子类(如Pawn,Knight) ,毕晓普等。)

其中一个棘手的方法是根据是否导致移动玩家受到检查来确定移动是否有效。我的解决方案如下:

  1. 克隆当前主板
  2. make move
  3. 查看移动玩家是否在检查
  4. 如果是的话,
  5. 禁止移动;否则,允许移动
  6. 我从这里获取了如何克隆的提示: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();
    }
    

    问题:

    1. 这看起来大致正确吗?
    2. 我的Square对象也有一个Board字段,基本上可以让我 参考他们所属的董事会。这会搞砸我的尝试 通过让我的每个64个方块分别克隆板来克隆?

2 个答案:

答案 0 :(得分:7)

我有另一种解决方案,看看你是否喜欢这个。

无需使用clone!我刚才写了一个中国象棋程序。让我解释一下我做了什么:(这只是一个大纲,你必须自己做细节)

我有一个Piece的2D数组和另一个2D按钮数组。当用户单击Piece时,将调用getValidLocations类中的抽象方法Piece,此方法返回一组坐标以指示Piece可以去哪里。当用户点击按钮时,该片段将移动到按钮的位置。

坏消息是,我不知道如何下国际象棋。我只知道中国象棋,所以我不能告诉你如何编写getValidLocations的算法,抱歉!

答案 1 :(得分:4)

不要使用dos('lbrm.exe') 。它被破坏而是制作完整的电路板。这是discussion with Josh Bloch on copy constructor vs cloning

通过进行深层复制,每件作品都会有不同的对象,因此移动它们不会弄乱相应作品的状态,而是代表另一个棋盘。

在你的所有作品上制作clone()方法以允许他们制作所有内部状态的有效副本可能是有意义的。

示例复制方法:

让我们假装你的copy()类有一个变量,如果它之前已经移动过。这确定它是否可以移动2个空格或仅移动1个。

Pawn