0

Whilst there have been numerous other questions on cloning, I've been reading their answers and as far as I'm aware I seem to have done most of what people have been saying.

In my Chequers Java game the board state is represented as a 2D Array containing objects of the Chequer class. In order to implement a MiniMax AI you need to create a search tree in order to traverse possible game states & evaluate them. For some reason my cloning technique has not worked.

What currently happens is that the MiniMax algorithm keeps moving Chequers around the primary game array, so once it decides on the best move to make, the Chequer is not there any more to move and a null pointer error is thrown.

I was wondering if any of you could take a look at my cloning and tell me where I'm going wrong:

Game Board Constructor:

public PlaySpace(Chequer[][] chequerBoard)
    {
        setState(chequerBoard);
    }

Set state method:

public void setState(Chequer[][] state)
    {
        Chequer[][] newBoard = new Chequer[8][8];
        for(int i = 0; i < state.length; i++){
            newBoard[i] = state[i];
        }
       chequerBoard = newBoard;
    }

Creating a new game board & cloning the current state's values to it:

PlaySpace child = new PlaySpace(board.returnState());
child.setState(board.returnState());
child.moveChequer(move.returnCurrentX(),move.returnCurrentY(),move.returnDestX(),move.returnDestY());

Thank you very much in advance! Please let me know if I can give any more information.

Cheers, Louis

lel23
  • 57
  • 7
  • could you eleborate where you´d think it will "clone" something? – SomeJavaGuy Nov 17 '15 at 14:43
  • 2
    In your constructor, you are overriding the parameter's value; you may as well not pass in the parameter at all. In your `setState` method, you are copying the references in `state` into a local variable, which then gets thrown away. – Andy Turner Nov 17 '15 at 14:43
  • Also i´d think that [a read through this](http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value) could potentially make you able to fix the mistakes by yourself. – SomeJavaGuy Nov 17 '15 at 14:49
  • Minor differences have been made in the edits thanks to your feedback: 1) chequerBoard = newBoard; added in set state. 2) constructor changed to simply call setState method. Still, the current board is being changed rather than a prospective cloned board during MiniMax search... thanks for your help so far! – lel23 Nov 17 '15 at 15:02

1 Answers1

2

You are not copying the 2 dimensional array. You have to remember that arrays in Java are objects, and arrays of arrays just contain references to array objects, they can contain references to the same array.

So basically you have 2 Chequer[][] arrays (newBoard and state) that both contain Chequer[] arrays . But you are not copying the Chequer[] array, you are assigning them from one Chequer[][] array into the other.

Here is an example of what happens:

Chequer[] array = new Chequer[8];

Chequer[][] arrayOfArrays1 = new Chequer[8][];
// Assign element 0 of arrayOfArrays1 with array
arrayOfArrays1[0] = array; 

Chequer[][] arrayOfArrays2 = new Chequer[8][];
// Assign element 0 of arrayOfArrays2 with arrayOfArrays1[0] == array
arrayOfArrays2[0] = arrayOfArrays1[0]; 

Now arrayOfArrays1[0] and arrayOfArrays2[0] both reference the same array object, and modifying array, will change it in both 2 dimensional arrays.

What you have to do is access the elements in the inner arrays with a 2 dimensional loop:

for (int y = 0; y < state.length; y++)
    for (int x = 0; x < state[y].length; x++)
        newBoard[y][x] = state[y][x];
Reboot
  • 1,716
  • 2
  • 14
  • 27