Reputation: 47
I'm using a arraylist to add states(the board state for the 8 puzzle). My problem is when I get the children of the state it changes the values stored in my array list. I'm assuming this is because ArrayList just stores pointers to the objects and not the values themselves. In order to fix this I create a new object every time before I store it into the ArrayList but I'm still having the same problem.
I will also try to follow naming conventions more often thanks for the tip.
private ArrayList<int[][]>VisitedBoard;
if(RuleNumber ==2){
//Here is my problem. This will change what is stored in VistedBoards
NextState = new State(FireRule.Rule2(WM.get_Board()));//Fire Rule
for(int j=0;j<VisitedBoards.size();j++){
//Meaning this will always be true
if(Arrays.equals(VisitedBoards.get(j), NextState.get_Board())){
Loop =true; //Loop to previous state
}
if(j==VisitedBoards.size()-1 && Loop ==false){ //If the next state is not any previously visited
NotALoop =true;
VisitedBoards.add(NextState.get_Board());
WM.set_Board(NextState.get_Board());
}
}
}
public int[][] Rule2(int [][] Board){//The FireRule Class
Find_BlankLocation(Board);
int temp;
State NewState;
temp = Board[BlankLocation[0]-1][BlankLocation[1]];
Board[BlankLocation[0]-1][BlankLocation[1]] = 0;
Board[BlankLocation[0]][BlankLocation[1]] = temp;
NewState = new State(Board);
return Board;
}
public class State { //State class
private int[][] Board;
private int[][] Goal;
private Boolean GoalFound;
public State(int[][] Start, int[][] goal){
Board = Start;
Goal = goal;
GoalFound=false;
}
public State(int[][] NewState){
Board=NewState;
}
public int[][] get_Goal(){
return Goal;
}
public int[][] get_Board(){
return Board;
}
public void set_Board(int[][] board){
Board = board;
}
public Boolean get_GoalFound(){
return GoalFound;
}
}
Upvotes: 0
Views: 164
Reputation: 13
My advice is to create your own container object for their 2D array and implement deep copying.
For example:
package netbeans;
import java.util.Arrays;
public class Container
implements Cloneable
{
private int [] _data;
private int _sx;
private int _sy;
public int get(int x, int y)
{
try { return this._data[y*this._sx+x]; }
catch (Exception e) { throw new ArrayIndexOutOfBoundsException(); }
}
public void set(int x, int y, int value)
{
try { this._data[y*this._sx+x] = value; }
catch (Exception e) { throw new ArrayIndexOutOfBoundsException(); }
}
public Object Clone() { return new Container(this); }
public Container(int sizeX, int sizeY, int [] data)
{
this._sx = sizeX;
this._sy = sizeY;
this._data = data;
}
public Container(Container cont)
{
this._data = Arrays.copyOf(cont._data, cont._data.length);
}
}
Upvotes: 0
Reputation: 20875
Containers like ArrayList
work the same in all languages: they are called data structures because they organize storage/retrieval of objects. Obviously they don't store the fields of the objects themselves.
Trying to interpret your problem, maybe you don't want to share the boards between the list of visitedBoards
and WM
(whatever it means...). Then simply implement get_Board()
to return a copy of the array instead of the Board
object itself:
public int[][] get_Board(int[][] src) {
int[][] dst = new int[src.length][src[0].length];
for (int i = 0; i < src.length; i++) {
System.arraycopy(src[i], 0, dst[i], 0, src[i].length);
}
return dst;return dst;
}
Beside this, as others already told you, you'd really better to adopt the standard Java naming conventions, use meaningful names, and encapsulate your x
, y
and int[][]
in real application classes.
Upvotes: 1
Reputation: 22692
Every time you create a new instance of State, you pass it the same array (whatever is returned by WM.get_Board()
).
You then add that same array to VisitedBoards when you call VisitedBoards.add()
.
The fact that you're creating new State objects is irrelevant, because only the return value of NextState.get_Board()
gets added to the list.
As a result, the list VisitedBoards always contains several references to the exact same array.
As Raffaele has suggested, you'll be fine if you make sure get_Board()
returns a copy of the array in stead of a reference to the original (assuming that doesn't mess up logic that exists elsewhere).
The main thing I learned from this question is how important it is to follow naming conventions.
Your unconventional capitalization has made me dizzy!
Following these rules will make it much easier for others to understand your Java code:
Upvotes: 0
Reputation: 2845
Presumably, the new State
object contains a pointer to the same arrayList as before. You'll want to manually copy the array out to a new one (a "deep clone" or "deep copy" as it is called). You might find this useful: Deep cloning multidimensional arrays in Java...?
Upvotes: 0