我正在用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());
}
}
答案 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
。如果更换了两块板中的一块,则两块板都会受到影响。复制时创建新的列实例,并深度复制列中的所有元素,直到到达不可变对象或基元。