1

我正在用 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());
    }
}

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

4

2 回答 2

4

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

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

Collections.copy(arrayList2,arrayList1);

或者干脆

new ArrayList<Integer>(oldList)

为了创建一个副本。

于 2013-04-13T19:15:05.977 回答
0

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

你的问题是你不复制列,你只b.columns = other.columns在你的copy方法中做。如果两块板之一被改变,两块板都会受到影响。复制时创建一个新的列实例,并深度复制列中的所有元素,直到达到不可变对象或基元。

于 2013-04-13T19:14:45.123 回答