在实例化同一类型的多个对象时,我遇到了一个奇怪的问题。
我正在尝试将新创建的对象解析为LinkedList queue
。所以出错的地方是,它应该在第一个if语句中将第一个对象tempBoardDirection
解析到队列中,然后将第二个对象tempBoardDirectionLeft
解析到队列中。
它出错的部分是它看起来更像是只是更改我的tempBoard
对象,因为当我打印字段时,我正在更改它,它总是在3个对象中相同。
我在哪里犯错,因为他们互相提及?
我试着在第一个if语句之前,之后和第二个if语句之后查看tempBoard.robots[0]
,这是数据:
java.awt.Point[x=0,y=1]
java.awt.Point[x=0,y=4]
java.awt.Point[x=0,y=0]
这不应该从java.awt.Point[x=0,y=1]
更改,因为我正在创建新对象并编辑其属性,而不是tempBoard
属性。
这是该函数的一个片段,可以解释它出错的地方:
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]);
}
以下是它失败的整个函数:
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");
}
更新1:
这是董事会课程,按要求我也应该放在这里。
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();
}
}
答案 0 :(得分:1)
我找到了解决方案。 问题是我需要在创建对象的新实例之前创建信息的副本。
我解决它的方法是创建一个新的超类,并按照这样做:
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;
}