Я пытаюсь реализовать алгоритм обратного отслеживания DFS, который включает использование стека (а не рекурсивного алгоритма), найденного в Википедии. Я пытаюсь создать лабиринт из 0 и 1, где 1 представляют стену, а 0 представляют доступный путь. Для любого данного пространства в лабиринте, который не является стеной, всегда должен быть действительный путь, по которому он может быть достигнут из любой другой непустой ячейки.
Я начинаю с лабиринта, который представляет собой двумерный массив лабиринта размера [15] [20], и следую алгоритму, отмечая ячейки, которые должны быть помечены как посещенные соответствующим образом. Первоначально все ячейки (исключая внешние границы) помечаются как «не посещенные». Все ячейки инициализируются со значением '1', и ожидается, что алгоритм будет копать уникальные пути по всему лабиринту.
Ссылка на алгоритм (2-я реализация рекурсивного обратного отслеживания, использующая стек):
https://en.wikipedia.org/wiki/Maze_generation_algorithm
Код, который я написал:
public void innerMaze() {
List<Coordinate> listOfCoordinates = new ArrayList<>();
List<Coordinate> coordinatesToBeRemoved = new ArrayList<>();
Stack<Coordinate> DFS_Stack = new Stack();
Coordinate initialCell = new Coordinate(1, 1);
checkIfVisited.put(initialCell, true);
DFS_Stack.push(initialCell);
int randomInteger = 0;
int cx = 0;
int cy = 0;
int gx = 0;
int gy = 0;
while (!DFS_Stack.empty()) {
Coordinate currentCoordinate = DFS_Stack.pop();
cx = currentCoordinate.getX();
cy = currentCoordinate.getY();
if ((cx - 2) >= 1) {
Coordinate up = findCoordinate((cx - 2), cy);
up.setDirection('N');
listOfCoordinates.add(up);
}
if ((cx + 2) <= MAX_ROW) {
Coordinate down = findCoordinate((cx + 2), cy);
down.setDirection('S');
listOfCoordinates.add(down);
}
if ((cy - 2) >= 1) {
Coordinate left = findCoordinate(cx, (cy - 2));
left.setDirection('W');
listOfCoordinates.add(left);
}
if ((cy + 2) <= MAX_COL) {
Coordinate right = findCoordinate(cx, (cy + 2));
right.setDirection('E');
listOfCoordinates.add(right);
}
for (Coordinate s : listOfCoordinates) {
if (checkIfVisited.get(s) == true) {
coordinatesToBeRemoved.add(s);
}
}
listOfCoordinates.removeAll(coordinatesToBeRemoved);
if (!listOfCoordinates.isEmpty()) {
DFS_Stack.push(currentCoordinate);
randomInteger = ThreadLocalRandom.current().nextInt(0, listOfCoordinates.size());
Coordinate temp = listOfCoordinates.get(randomInteger);
char direction = temp.getDirection();
Coordinate newWall;
if (direction == 'N') {
newWall = findCoordinate((cx - 1), cy);
} else if (direction == 'S') {
newWall = findCoordinate((cx + 1), cy);
} else if (direction == 'W') {
newWall = findCoordinate(cx, (cy - 1));
} else {
newWall = findCoordinate(cx, (cy + 1));
}
System.out.println(newWall);
gx = newWall.getX();
gy = newWall.getY();
completeMaze[gx][gy] = 0;
checkIfVisited.put(temp, true);
checkIfVisited.put(newWall, true);
listOfCoordinates.clear();
DFS_Stack.push(temp);
}
}
}
В моей текущей реализации каждая ячейка будет представлять собой стену или путь, поэтому я изменил алгоритм немного приближается к тому, где удаление стены между двумя ячейками становится удалением стены на две ячейки, изменяя одну промежуточную стенку на стену. Пример моего вывода выглядит следующим образом:
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 0 1 1 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1
1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 1 1 0
1 1 1 1 0 1 0 1 1 1 1 1 1 1 0 1 0 1 0 1
1 0 1 1 1 0 1 1 1 0 1 0 1 1 1 1 1 1 1 0
1 1 0 1 1 1 1 1 0 1 1 1 0 1 0 1 1 1 0 1
1 1 1 0 1 0 1 0 1 1 1 1 1 1 1 0 1 0 1 1
1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1
1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0
1 1 0 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1
1 0 1 1 1 1 1 0 1 1 1 0 1 1 1 0 1 0 1 0
1 1 0 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1
1 1 1 0 1 0 1 1 1 0 1 0 1 0 1 1 1 0 1 0
1 1 0 1 0 1 1 1 0 1 0 1 1 1 0 1 0 1 0 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
На первый взгляд, двумерный индекс массива [1] [1] заключен в стены, поэтому это недоступная область. Это также очень согласуется с многочисленными казнями.
Буду признателен за любую помощь.