MaskinMichael
MaskinMichael

Reputation: 33

Changing values in an object makes changes to another

I'm working on generating a game tree.

My problem I enter is that when I copy an object to a new object, and then makes changes in the new object, the old object also changes it's values.

So it seems to be a reference problem.

But how do I make the new object an independent instance.

after creating this child object copied from parent, and then changing values in the child object, the parent object is also changed and in the end of the method it will print that the objects is equal.

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);
}

The expected result is that I can change the object Child without changing Parent

Upvotes: 3

Views: 4889

Answers (2)

Markus Steppberger
Markus Steppberger

Reputation: 638

But how do I make the new object an independent instance.

Remove the static keyword to make the fields inside the object independent from other objects.

If a field/variable is static it shares its value with all instances of the class. If you change one of them you change the value for all of the instances.

I think the main problem is your copying of State objects. You do not really copy anything you only pass the references to another instance.

You need a deepCopy method which also copies the instances of all the fields which itself have to copy themselfs.

Deep copying has to be made in all fields which are part of the new object. Here you have to copy the Board, the Player, the Move and so on. For the primitive data types your copy does work as it is.

Upvotes: 2

pethryth
pethryth

Reputation: 56

    // 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);
}

Your copy constructor doesn't make a copy. You provide references to another object, and they pointing to the same parent, depth, board, children, etc. You should create for every object another copy constructor upto primitive types. For example, if board contains two ints:

class Board {
int a;
int b;

public Board(Board board){
   this.a = board.a;
   this.b = board.b;
}

And just use this constructor:

this.board = new Board(state.board);

instead of:

this.board = state.board;

Upvotes: 0

Related Questions