我正在制作游戏树。
我输入的问题是,当我将一个对象复制到一个新对象,然后在新对象中进行更改时,旧对象也会更改它的值。
所以它似乎是一个参考问题。
但是如何使新对象成为一个独立的实例。
在创建从父对象复制的子对象,然后更改子对象中的值之后,父对象也会更改,并且在方法的末尾将打印对象相等。
private void generateSubTree(State parent, int depth) {
if (depth == 0) {
System.out.println("End of leaf..!");
return;
}
ArrayList<State> listOfStates = GameEngine.legalMoves(parent);
for (State s: listOfStates) {
Board tempBoard = new Board(parent.getBoard().getBoard());
BoardPiece pieceRef = new BoardPiece();
State child = new State(parent);
if(parent.getTurn() == 0) {
pieceRef = GameEngine.checkForPiece(child.getPlayer1(), s.getMove().getFromX(), s.getMove().getFromY());
pieceRef.updatePosition(s.getMove().getToX(), s.getMove().getToY());
tempBoard.updateBoard(child.getPlayer1(), s.getMove(), false);
} else {
pieceRef = GameEngine.checkForPiece(child.getPlayer2(), s.getMove().getFromX(), s.getMove().getFromY());
pieceRef.updatePosition(s.getMove().getToX(), s.getMove().getToY());
tempBoard.updateBoard(child.getPlayer2(), s.getMove(), false);
}
child.setBoard(tempBoard);
parent.addChild(child);
System.out.println("Is parent equal to child: " + child.equals(parent));
i++;
System.out.println("States generated: " + i);
generateSubTree(child,depth-1);
}
}
public class State{
private Board board;
private int turn;
private Move move;
private ArrayList<Move> legalMoves;
private int depth;
private int utilityVal;
private Player player1;
private Player player2;
private State parent;
private ArrayList<State> children;
public State() {
children = new ArrayList<>();
}
// Copy constructor
public State(State state) {
this.parent = state.parent;
this.depth = state.depth;
this.board = state.board;
this.children = state.children;
this.turn = 1 - state.turn;
this.player1 = state.player1;
this.player2 = state.player2;
// shallow copy
// this.subjects = student.subjects;
// deep copy - create new instance of HashSet
// this.subjects = new HashSet<>(state.subjects);
}
预期的结果是我可以在不更改Parent的情况下更改对象Child
// Copy constructor
public State(State state) {
this.parent = state.parent;
this.depth = state.depth;
this.board = state.board;
this.children = state.children;
this.turn = 1 - state.turn;
this.player1 = state.player1;
this.player2 = state.player2;
// shallow copy
// this.subjects = student.subjects;
// deep copy - create new instance of HashSet
// this.subjects = new HashSet<>(state.subjects);
}
您的复制构造函数不会复制。您提供对另一个对象的引用,它们指向相同的父对象,深度,板,子等。您应该为每个对象创建另一个复制构造函数,直到原始类型。例如,如果董事会包含两个整数:
class Board {
int a;
int b;
public Board(Board board){
this.a = board.a;
this.b = board.b;
}
并使用此构造函数:
this.board = new Board(state.board);
代替:
this.board = state.board;
但是如何使新对象成为一个独立的实例。
删除static
关键字以使对象内的字段独立于其他对象。
如果字段/变量是static
,则它与该类的所有实例共享其值。如果更改其中一个,则更改所有实例的值。
我认为主要的问题是你复制State
对象。您没有真正复制任何只将引用传递给另一个实例的内容。
你需要一个deepCopy
方法,它也复制自己必须复制自己的所有字段的实例。
必须在作为新对象一部分的所有字段中进行深度复制。在这里你必须复制Board
,Player
,Move
等。对于原始数据类型,您的副本可以按原样工作。