#javascript #algorithm
#javascript #алгоритм
Вопрос:
Я изучаю, как создать лабиринт с помощью Javascript. Я просмотрел следующий код. По сути, логика заключается в том, чтобы случайным образом выбрать квадрат (я жестко закодировал значение, чтобы лучше понять шаблон) и проверить, посещались ли его соседи или нет. Если это так, просто пропустите этого соседа и случайным образом выберите непросмотренный и повторите процесс, снова проверив его соседей…Я знаю, что когда цель попадает в тупик, она возвращается. Но я не нашел никакого кода, который заставляет мяч возвращаться. Пожалуйста, посмотрите Ссылку на Изображение здесь: 1 [(3, 3) — это тупик. Цикл for of проверил, что были посещены левый и верхний, а правый и нижний были вне границ. Моя проблема в том, что for(сосед соседей) {…} уже перебрал всех четырех соседей, и последняя итерация (в данном случае проверка левого квадрата) была пропущена, потому что она была посещена. Но после итерации я сразу же запускаю консоль log в первой строке цикла for of и, что удивительно, соседи изменились с [[4, 3, «вниз»], [2, 3, «вверх»], [3, 4, «вправо»], [3,2, «влево»]] в [[3, 3, «вниз»], [1, 3, «вверх»], [2, 4, «вправо»], [2, 2, «влево»]]. Но разве последняя итерация не была пропущена с ключевым словом continue, и итерация должна была закончиться? Почему у меня все еще есть еще четыре соседа для перебора? Это то место, где мяч возвращается назад?
Большое вам спасибо за ваше время! Большое спасибо!
Вот код:
const width = innerWidth;
const height = innerHeight;
const cellsHorizontal = 4; // columns
const cellsVertical = 4; // rows
const unitLengthX = width / cellsHorizontal;
const unitLengthY = height / cellsVertical;
const stepThroughCell = (row, column) => {
// If I have visited the cell at [row, column], then return
if (grid[row][column]) {
return;
}
// Mark this cell as being visited
grid[row][column] = true;
// Specify neighbors
const neighbors = [
[row 1, column, "down"],
[row - 1, column, "up"],
[row, column 1, "right"],
[row, column - 1, "left"],
];
// For each neighbor...
for (neighbor of neighbors) {
console.log(neighbors, row, column); // why we got another four neighbors after the last iteration was skipped?
const [nextRow, nextColumn, direction] = neighbor;
// see if that neighbor goes to a cell that doesn't exist
if (
nextRow < 0 ||
nextRow >= cellsVertical ||
nextColumn < 0 ||
nextColumn >= cellsHorizontal
) {
continue;
}
// If we have visited that neighbor, continue to next neighbor
if (grid[nextRow][nextColumn]) {
continue;
// the last iteration was skipped when the target hits a dead end, so the iteration was supposed to end? But the first line in the for of loop shows that there are another four neighbors, why?
}
// Remove a wall from either horizontals or verticals
if (direction === "left") {
verticals[row][column - 1] = true;
} else if (direction === "right") {
verticals[row][column] = true;
} else if (direction === "up") {
horizontals[row - 1][column] = true;
} else if (direction === "down") {
horizontals[row][column] = true;
}
// Visited that next cell
stepThroughCell(nextRow, nextColumn);
}
};
stepThroughCell(1, 1);
Ответ №1:
Это рекурсивный алгоритм, на самом деле вы вызываете «пошаговую ячейку» внутри самого if и продолжаете / возвращаетесь при успехе / неудаче, поэтому предположим, что в какой-то ситуации вы зашли в тупик, алгоритм будет продолжаться с последней контрольной точки, которая «пошаговая ячейка» вызывается для другого соседа.
Комментарии:
1. Спасибо за ваш ответ. Насколько я понимаю, последняя итерация была пропущена, потому что не было допустимых квадратов. Таким образом, в этом случае браузер пропустил итерацию и вернулся к началу цикла, прежде чем функция stepThroughCell была вызвана снова. Если функция не была вызвана, как нам заставить новых соседей проверять? Возможно, я не совсем понимаю, как работает цикл. Пожалуйста, дайте мне знать, если мое понимание неверно. Еще раз большое вам спасибо!
2. в этой части кода
for (neighbor of neighbors)
вы перебираете всех возможных соседей. поэтому, если алгоритм в любое время завершается неудачей, он возвращается и загружает новый узел