Алгоритм лабиринта: в какой строке кода указано, что когда мяч попадает в тупик, он возвращается назад?

#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) вы перебираете всех возможных соседей. поэтому, если алгоритм в любое время завершается неудачей, он возвращается и загружает новый узел