Реагировать - перебирать вложенный массив и проверять значения индексов в массиве - PullRequest
0 голосов
/ 29 сентября 2018

Я изучаю React и работаю над проектом игры жизни Конвея.Проект в основном выполнен, но у меня возникли проблемы с реализацией игровой логики.У меня есть 2D массив, который представляет игровое поле.Каждый индекс в двумерном массиве представляет квадрат на доске.Я настроил его так, чтобы функциональные компоненты обрабатывали отображение доски и какие квадраты «живы» в смысле игры жизни.В моем App.js у меня есть функция componentDidMount, которая создает новую доску, заполненную случайными «живыми» квадратами, которая также вызывает функцию timer, которая создает новую доску каждые пару секунд.

Япытаясь использовать componentDidUpdate для проверки доски каждый раз, когда она меняется, и применять правила Игры Жизни:

Любая живая клетка с менее чем двумя живыми соседями умирает, как если бы она была под населением.

Любая живая клетка с двумя или тремя живыми соседями доживает до следующего поколения.

Любая живая клетка с более чем тремя живыми соседями умирает,как будто из-за перенаселения.

Любая мертвая клетка с ровно тремя живыми соседями превращается в живую клетку, как будто при размножении.

Моя логика - когда componentDidUpdate Запускается, я перебираю 2D-массив (игровую доску) и проверяю соседние квадраты, чтобы убедиться, что они заполнены.Затем примените правила игры и определите, живет ли этот конкретный квадрат, умирает или размножается.Затем, после проверки каждого квадрата и определения того, должен он жить или умереть, я обновлю состояние со значениями новой игровой доски.Затем timer запускается снова, создает следующий раунд, и componentDidUpdate снова оценит следующие изменения на доске.

Это не работает.Вот код для componentDidUpdate.Что не так с моим подходом?:

// Should apply Game of Life rules and decide with squares are alive/dead every time the board is updated
  componentDidUpdate = (prevProps, prevState) => {
    //console.log('PrevState is : ' + prevProps, prevState);
    const oldBoard = this.state.board;
    const newBoard = this.state.nextBoard;

    console.log('oldBoard ' + oldBoard);

/*    // Checks that board has changed and prevents infinite loop in componentDidUpdate
      for(let x = 0; x < this.state.boardHeight; x++) {
        for(let y = 0; y < this.state.boardWidth; y++) {
          let neighborCount = 0;
          // Game of Life logic pertaining to squares being alive/dead
          neighborCount += oldBoard[x - 1][y - 1];
          neighborCount += oldBoard[x][y - 1];
          neighborCount += oldBoard[x + 1][y - 1];
          neighborCount += oldBoard[x - 1][y];
          neighborCount += oldBoard[x + 1][y];
          neighborCount += oldBoard[x - 1][y + 1];
          neighborCount += oldBoard[x][y + 1];
          neighborCount += oldBoard[x + 1][y + 1];

          // If square has 2 live neighbors it stays alive
          if(neighborCount == 2) {
            newBoard[x][y] = oldBoard[x][y];
          }
          // If square has exactly 3 neighbors a new life square is born
          else if (neighborCount == 3) {
            newBoard[x][y] = 1;
          }
          // Is square has more than 3 live neighbors it dies
          else if(neighborCount > 3){
            newBoard[x][y] = 0;
          }
        }
      }

      if(newBoard !== oldBoard) {
        // after applying rules set the nextBoard
        this.setState({ board: newBoard });
      }
    */

  }

Вероятно, было бы проще просмотреть весь App.js в CodeSandbox .Я думаю, что моя логика верна, но, возможно, то, как я перебираю и оцениваю значения массивов, неверно, или, возможно, мое использование componentDidUpdate неверно.

1 Ответ

0 голосов
/ 29 сентября 2018

Я думаю, что ваша проблема в том, что вы сравниваете с newBoard, который вы никогда не устанавливали.Я считаю, что вы можете полностью вывести newBoard из состояния и начать проверять

const oldBoard = prevState.board;
const newBoard = this.state.board;

в вашей функции componentDidUpdate.

...