简体   繁体   中英

Loading all values of 2d array in java

I'm attempting to create a 2d puzzle slider game. I created my own object called gamestate to store the parent gamestate and the new gamestate, as I plan on solving it using BFS. A sample array will look like

int[][] tArr = {{1,5,2},{3,4,0},{6,8,7}};

Which implies

[1, 5, 2, 3, 4, 0, 6, 8, 7]

To store this state I used the following for loop, which brings indexOutOfBounds exceptions .

public class GameState {
public int[][] state; //state of the puzzle
public GameState parent; //parent in the game tree

public GameState() {
    //initialize state to zeros, parent to null
    state = new int[0][0];
    parent = null;
}

public GameState(int[][] state) {
    //initialize this.state to state, parent to null
    this.state = state;

    parent = null;
}

public GameState(int[][] state, GameState parent) {
    //initialize this.state to state, this.parent to parent
    this.state = new int[0][0];
    for (int i = 0; i < 3; i++){
        for (int j = 0; j < 3; j++) {
            this.state[i][j] = state[i][j];
        }
    }

    this.parent = parent;
}

Any ideas on how to fix this?

  • For the GameState() constructor (default constructor):

Change this state = new int[0][0]; to this: state = new int[ 3 ][ 3 ]; . This way you initialize the array with capacity for (3)x(3) elements.

  • For the GameState(int[][] state, GameState parent) constructor:

Change this this.state = new int[0][0]; to this.state = new int[ state.length ][ state.length > 0 ? state[0].length : 0 state.length > 0 ? state[0].length : 0 ];

This way, you initialize the array with capacity for

( state.length )x( state[0].length or 0 if state.length is 0 ) elements.

Also, you must for loop until state.length with i and until state[i].length with j .

In GameState constructor, like this:

public GameState(int[][] state, GameState parent) {
    //initialize this.state to state, this.parent to parent
    this.state = new int[state.length][state.length > 0 ? state[0].length : 0];
    for (int i = 0; i < state.length; i++){
        for (int j = 0; j < state[i].length; j++) {
            this.state[i][j] = state[i][j];
        }
    }

    this.parent = parent;
}

Also, as a side note it is not [1, 5, 2, 3, 4, 0, 6, 8, 7] ,

but [[1, 5, 2], [3, 4, 0], [6, 8, 7]] .

The problem is in the initialisation part.

this.state = new int[0][0];

This code will create a zero sized two dimentional aray. That's why you get indexOutOfBounds exceptions when you try to set values in it.

If you want to initialize your array with zeros, the correct syntax is :

this.state = {{0,0,0},{0,0,0},{0,0,0}};

see the official documentation for full reference : https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html

In the 3rd constructor you're initializing this.state with an empty array. It has no elements and thus a length of 0 . Using a for loop to access any element of this array rises an ArrayIndexOutOfBoundsException .

Since you're passing in a state as parameter, you probably want to copy it's values to the field state .

You can do this like that:

public GameState(int[][] state, GameState parent) {
    this.state = new int[state.length][];
    for (int i = 0; i < state.length; i++) {
        if (state[i] != null) {
            this.state[i] = Arrays.copyOf(state[i], state[i].length);
        }
    }

    this.parent = parent;
}

You could of course call Arrays.of(state) but this wouldn't return a deep copy of state . For every i you would have this.state[i] == state[i] .


Further reading: How do I copy a 2 Dimensional array in Java?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM