У меня есть массив, называемый maze
который в теории должен быть модифицирован только в updateMaze()
. Это потому, что это конечный результат, который я хочу вывести на консоль. Проблема заключается в том, что tempMaze
изменен, а также изменен maze
. Это не должно произойти. Моя первая мысль заключалась в том, что они указывают на одну и ту же ссылку в памяти, однако я проверил, и это неверно. Я должен упомянуть, что я использовал clone()
при инициализации, чтобы сделать их содержимое похожим, и я не уверен, что это может быть проблемой или нет. (Хотя я думаю, что понимаю, что clone()
я недостаточно осведомлен, чтобы знать, является ли это проблемой или нет.) Мой код:
public class ThreadTheMaze {
ArrayList<Cell> result = new ArrayList<Cell>();
private String[][] maze;
private String[][] tempMaze;
private int initRowPosition;
private int initColPosition;
private int amtOfRows;
private int amtOfCols;
public ThreadTheMaze(int initRow, int initCol){
initRowPosition = initRow;
initColPosition = initCol;
result.add(new Cell(initRowPosition, initColPosition));
}
public void loadMaze(){
try{
Scanner in = new Scanner(new File("mazeData.txt"));
while (in.hasNextLine()){
amtOfCols = in.nextLine().length();
amtOfRows++;
}
in.close();
maze = new String[amtOfRows][amtOfCols];
in = new Scanner(new File("mazeData.txt"));
for (int r = 0; r < amtOfRows; r++){
String line = in.nextLine();
for (int c = 0; c < amtOfCols; c++){
maze[r][c] = line.substring(0,1);
line = line.substring(1);
}
}
tempMaze = maze.clone();
}catch (FileNotFoundException e){
System.err.print(e);
}
}
public void printMaze(){
for (int r = 0; r < amtOfRows; r++){
for (int c = 0; c < amtOfCols; c++){
System.out.print(maze[r][c]);
}
System.out.println();
}
}
public void updateMaze(){
for (int i = 0; i < result.size(); i++){
maze[result.get(i).getRow()][result.get(i).getColumn()] = "!";
}
}
/**
@return ArrayList of objects 'Cell' that are the solution to the maze. (Note: if no solution then returns empty ArrayList)
*/
public void solve(Cell cell){
tempMaze[cell.getRow()][cell.getColumn()] = "!";
ArrayList<Cell> neighbors = getNeighbors(cell);
if ((cell.getRow() == 0 || cell.getRow() == tempMaze.length-1) || (cell.getColumn() == 0 || cell.getColumn() == tempMaze[0].length-1)){
return;
}
if ((cell.getColumn() == initColPosition && cell.getRow() == initRowPosition) && neighbors.size() < 1){
return;
}
// If not in init position and has no neighbors then backtrack
if ((cell.getColumn() != initColPosition || cell.getRow() != initRowPosition) && neighbors.size() < 1){
result.remove(result.size()-1);
solve(result.get(result.size()-1));
}else if (neighbors.size() >= 1){ // If has neighbors then choose one and call the method again
result.add(neighbors.get(0));
solve(neighbors.get(0));
}
}
/**
@return ArrayList of objects 'Cell' that are empty and available to move to.
*/
private ArrayList<Cell> getNeighbors(Cell cell){
ArrayList<Cell> neighbors = new ArrayList<Cell>();
int row = cell.getRow();
int column = cell.getColumn();
int[][] moveLocs = {{row-1, column}, {row+1, column}, {row, column+1}, {row, column-1}};
for (int r = 0; r < moveLocs.length; r++){
int tRow = moveLocs[r][0];
int tCol = moveLocs[r][1];
if (isValid(tRow, tCol)){
Cell neighbor = new Cell(tRow, tCol);
neighbors.add(neighbor);
}
}
return neighbors;
}
public boolean isValid(int row, int col){
if(row < 0 || row >= amtOfRows){
return false;
}
if (col < 0 || col >= amtOfCols){
return false;
}
if (!tempMaze[row][col].equals(" ")){
return false;
}
return true;
}
}
Класс Cell
- это простой класс с некоторым простым методом get и set.
Я знаю, что это не самый краткий способ представить вам мой вопрос, но на самом деле я не могу определить место, где проблема может существовать. Благодарю.
clone()
неглубоко. Это означает, что следующее:
tempMaze = maze.clone();
только клонирует первый уровень 2D-массива. Другими словами, вы получаете новый массив, содержащий те же ссылки String[]
что и исходный массив.
Чтобы узнать, как это исправить, см. Раздел Как сделать глубокую копию массива 2d в Java?