theman1071 theman1071 - 7 months ago 13
Java Question

Instantiate multiple identical objects

I am having an wierd issue when instantiating multiple objects of the same type.

I am trying to parse a newly created object into a

LinkedList queue
. So the thing that goes wrong is, it is supposed to parse the first object
tempBoardDirection
into the queue in the first if statement, and afterwards parse the second object
tempBoardDirectionLeft
into the queue.


The part where it goes wrong is that it looks more like it is just changing my
tempBoard
object, because when I print the field out I am changing it it always the same in thoose 3 objects.

Where am I making the error since they are referring to each other?

I tried to look at the
tempBoard.robots[0]
, both before first if statement, after it and after second if statement and this was the data:



  • before first if statement -
    java.awt.Point[x=0,y=1]

  • After first if statement -
    java.awt.Point[x=0,y=4]

  • After second if statmenet -
    java.awt.Point[x=0,y=0]




This shouldn't be changed from
java.awt.Point[x=0,y=1]
, as I am creating new objects and editing their attributes, not
tempBoard
attributes.

This is a snippet of the function that should explain where it goes wrong:

while(!q.isEmpty()){
Board tempBoard = q.poll();

if(tempBoard.isGoal())
return tempBoard.moves;

Endpoints endpoint = tempBoard.possibleEndpointsForRobot(0);
System.out.println(tempBoard.robots[0]);

if(!visited[endpoint.right.x][endpoint.right.y]){
Board tempBoardDirection = new Board(tempBoard.board, tempBoard.robots, tempBoard.goal);
tempBoardDirection.moves = tempBoard.moves;
tempBoardDirection.moveRobot(0,Direction.Right);
visited[endpoint.right.x][endpoint.right.y] = true;
q.add(tempBoardDirection);
System.out.println("right: "+tempBoardDirection.robots[0]);
}

if(!visited[endpoint.left.x][endpoint.left.y]){
Board tempBoardDirectionLeft = new Board(tempBoard.board, tempBoard.robots, tempBoard.goal);
tempBoardDirectionLeft.moves = tempBoard.moves;
tempBoardDirectionLeft.moveRobot(0,Direction.Left);
visited[endpoint.left.x][endpoint.left.y] = true;
q.add(tempBoardDirectionLeft);
System.out.println("Left: "+tempBoardDirectionLeft.robots[0]);
}



Here is the whole function on where it fails:

public String computeSolution() throws Exception {
Queue<Board> q = new LinkedList<>();

q.add(this.board);
this.visited[this.board.robots[0].x][this.board.robots[0].y] = true;

int i = 0;

while(!q.isEmpty()){
Board tempBoard = q.poll();

if(tempBoard.isGoal())
return tempBoard.moves;

Endpoints endpoint = tempBoard.possibleEndpointsForRobot(0);
System.out.println(tempBoard.robots[0]);

if(!visited[endpoint.right.x][endpoint.right.y]){
Board tempBoardDirection = new Board(tempBoard.board, tempBoard.robots, tempBoard.goal);
tempBoardDirection.moves = tempBoard.moves;
tempBoardDirection.moveRobot(0,Direction.Right);
visited[endpoint.right.x][endpoint.right.y] = true;
q.add(tempBoardDirection);
System.out.println("right: "+tempBoardDirection.robots[0]);
}

if(!visited[endpoint.left.x][endpoint.left.y]){
Board tempBoardDirectionLeft = new Board(tempBoard.board, tempBoard.robots, tempBoard.goal);
tempBoardDirectionLeft.moves = tempBoard.moves;
tempBoardDirectionLeft.moveRobot(0,Direction.Left);
visited[endpoint.left.x][endpoint.left.y] = true;
q.add(tempBoardDirectionLeft);
System.out.println("Left: "+tempBoardDirectionLeft.robots[0]);
}

if(!visited[endpoint.up.x][endpoint.up.y]){
System.out.println("works up");
Board tempBoardDirection = new Board(tempBoard.board, tempBoard.robots, tempBoard.goal);
tempBoardDirection.moves = tempBoard.moves;
tempBoardDirection.moveRobot(0,Direction.Up);
visited[endpoint.up.x][endpoint.up.y] = true;
q.add(tempBoardDirection);
}

if(!visited[endpoint.down.x][endpoint.down.y]){
System.out.println("works down");
Board tempBoardDirection = new Board(tempBoard.board, tempBoard.robots, tempBoard.goal);
tempBoardDirection.moves = tempBoard.moves;
tempBoardDirection.moveRobot(0,Direction.Down);
visited[endpoint.down.x][endpoint.down.y] = true;
q.add(tempBoardDirection);
}
//System.out.println(tempBoard.moves);
i++;
}

System.out.println("num of loops: "+i);
throw new Exception("no solution");
}


UPDATE 1:

This is the Board class, as requested that I should place in here too.

public class Board {
public static final char GOAL_CHAR = 'G';
public static final char WALL_CHAR = '#';
public static final char EMPTY_CHAR = ' ';

public char[][] board;
public int size;
public Point[] robots;
public Point goal;
public String moves = "";
public boolean[][] visited;

public Board(char[][] board, Point[] robots, Point goal) {
this.board = board;
this.size = board.length;
this.robots = robots;
this.goal = goal;
this.visited = new boolean[this.size][this.size];
}


public Integer getCurrentRobotFromQueue(Queue q) {
return IntStream.range(0, robots.length).filter(i -> q.element().equals(robots[i])).findFirst().getAsInt();
}

public boolean isGoal() {
return this.robots[0].equals(this.goal);
}

public Endpoints possibleEndpointsForRobot(int robot) {
assert robot < robots.length;

Point up = pointAfterMovingRobot(robot, Direction.Up);
Point down = pointAfterMovingRobot(robot, Direction.Down);
Point left = pointAfterMovingRobot(robot, Direction.Left);
Point right = pointAfterMovingRobot(robot, Direction.Right);

return new Endpoints(up, down, left, right);
}

public Point pointAfterMovingRobot(int robot, Direction m) {
assert robot < robots.length;

Point pos = new Point(robots[robot]);
int drow = 0, dcol = 0;

if (m == Direction.Up) {
drow = -1;
} else if (m == Direction.Down) {
drow = 1;
}

if (m == Direction.Left) {
dcol = -1;
} else if (m == Direction.Right) {
dcol = 1;
}

while (withinBoard(pos.x+drow, pos.y+dcol) &&
(board[pos.x+drow][pos.y+dcol] == EMPTY_CHAR
|| board[pos.x+drow][pos.y+dcol] == GOAL_CHAR)) {
pos.translate(drow, dcol);
}

return pos;
}

public void moveRobot(int robot, Direction d) {
assert robot < robots.length;

Point from = robots[robot];
Point to = pointAfterMovingRobot(robot, d);
board[from.x][from.y] = EMPTY_CHAR;
robots[robot] = to;
board[to.x][to.y] = (char) ('0' + robot);

//add move to moves.

this.moves += robot+d.toString()+", ";
}

private boolean withinBoard(int x, int y) {
return x >= 0 && x < size && y >= 0 && y < size;
}

public String toString() {
StringBuilder sb = new StringBuilder(size * size);

for (int i = 0; i < board.length; i++) {
sb.append(board[i]);
sb.append(System.getProperty("line.separator"));
}

return sb.toString();
}
}

Answer

I found the solution. The problem was that I needed to create a copy of the information before I create a new instance of the object.

The way I solved it was by making an new superclass and do it like this:

public Board(Board tempBoard){
    this.board = new char[tempBoard.board.length][tempBoard.board.length];
    this.robots = new  Point[tempBoard.robots.length];
    System.arraycopy( tempBoard.board, 0, board, 0, tempBoard.board.length );
    System.arraycopy( tempBoard.robots, 0, robots, 0, tempBoard.robots.length );
    this.size = tempBoard.size;
    this.goal = tempBoard.goal;
    this.moves = tempBoard.moves;
}