克隆/复制对象

时间:2013-04-13 19:09:50

标签: java clone

我正在用Java创建一个connect 4游戏,我正在尝试制作一个自定义对象(游戏板)的深层副本,然后修改该副本并将其作为mini max算法的一部分添加到列表中。

这是我用于复制的代码:

public void getPossibleBoards(Board board) {
    for(int i = 0; i < 7; i++) {
        if(!board.columns.get(i).isFull()) {    
            Board tmpBoard = board.copy(board);
            tmpBoard.columns.get(i).addCounter(turn);   
            boardList.add(tmpBoard);
        }
    }
}

public Board copy(Board other) {
    Board b = new Board(other);
    b.columns = other.columns;
    return b;
}

这需要主板(作为参数传递),循环通过板上的列,如果列未满,则创建一个新的板对象并将计数器放入空列,然后添加此新板反对列表供以后使用。

问题在于,当我复制电路板时,它会不断引用主板并对其进行修改,然后每个循环都会向列中添加一个计数器而不先清除电路板。

预期输出为:(玩家1为人,玩家2为计算机)

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 0 0 0
2 0 0 0 0 0 1

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 0 0 0
0 2 0 0 0 0 1

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 0 0 0
0 0 2 0 0 0 1

依此类推,直到7个循环结束。

实际输出:

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 0 0 0 
0 0 0 0 0 0 2 
2 2 2 2 2 2 1 

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 0 0 0 
0 0 0 0 0 0 2 
2 2 2 2 2 2 1 

依此类推,直到7个循环结束。

编辑:

我遇到了以下解决方案的问题,所以我决定尝试另一种方式,但得到了相同的结果,我不明白为什么。

我基本上是在构造函数中创建一个新的Board对象,我正在为它分配新的空白列,然后循环遍历main_board以获取每个槽的计数器颜色(存储为Slot类中的整数) ,并分别改变新的董事会。

if(!board.columns.get(i).isFull()) {    
    Board tmpBoard = new Board();

    for(int j = 0; j < 7; j++) {
        for(int k = 0; k < 7; k++) {
                    tmpBoard.columns.get(j).slots.get(k).setColour(board.columns.get(j).slots.get(k).getColour());
        }   
    }
}

董事会建设者

public Board() {
    for(int i = 0; i < 7; i++) {
        columns.add(new Column());
    }
}

编辑:没关系,上面的解决方案有效,只是我忘了在复制后添加一个新的计数器。

2 个答案:

答案 0 :(得分:4)

b.columns = other.columns;导致问题,因为您正在进行引用分配(即它没有像您期望的那样进行深层复制)。您可以使用System.arraycopy方法复制该数组。

我认为在您的情况下,您使用ArrayList来表示列/行,如果是这样,您可以使用:

Collections.copy(arrayList2,arrayList1);

或只是

new ArrayList<Integer>(oldList)

以创建副本。

答案 1 :(得分:0)

为什么Board将另一个Board作为构造函数参数?

您的问题是您没有复制列,只能在b.columns = other.columns方法中执行copy。如果更换了两块板中的一块,则两块板都会受到影响。复制时创建新的列实例,并深度复制列中的所有元素,直到到达不可变对象或基元。