React - обновить состояние 2D-массива и заполнить его случайными числами, используя функцию .map и новый Array.fill. - PullRequest
0 голосов
/ 22 сентября 2018

Я работаю над приложением Джона Конвея «Игра в жизнь» и все еще изучаю React.

Вот что у меня есть .Игровое поле создано с использованием 2D-массива в состоянии моего App.js.Я использую новый Array и метод .fill в своем конструкторе, чтобы изначально создать квадраты доски.Позже в App.js у меня есть функция isSquareAlive, которая обрабатывает функциональность onClick и меняет соответствующие квадраты на другой цвет, когда пользователь нажимает на них (они «живы» в смысле Игры Жизни).

Теперь я хочу создать случайную доску, когда пользователь впервые загружает приложение, некоторые квадраты будут активными, а другие - нет.Я создал функцию случайного числа с именем getRandomNumber, которая создает 1 или 0. Теперь я хочу создать еще одну функцию, которая будет вызываться для componentDidMount, и эта функция создаст начальную игровую доску, когда пользователь загрузит приложение, и оно вызоветgetRandomNumber и заполните некоторые элементы 2d-массива (квадраты) единицами, а другие 0.Квадраты с 1 будут «живыми», а квадраты с 0 - нет.

Другими словами, я хочу, чтобы игровая доска генерировалась случайным образом каждый раз, когда пользователь загружает страницу.Как бы я это сделал?Вложенные функции .map, а затем отправка результатов getRandomNumber в новый Array.fill?

Вот мой App.js:

import React, { Component } from 'react';
import './App.css';
import GameBoard from './GameBoard.js';
import Controls from './Controls.js';
import update from 'immutability-helper';
import Info from './Info.js';

class App extends Component {
  constructor(props){
    super(props);

    this.state = {
      boardHeight: 50,
      boardWidth: 30,
      iterations: 10,
      reset: false,
      alive: false,
      board: [],
      randomNum: ''
    };

    this.state.board = new Array(this.state.boardHeight).fill(new Array(this.state.boardWidth).fill(0));
  }

  // Allows user to click button and change size of game board
  selectBoardSize = (width, height) => {
    this.setState({
      boardHeight: height,
      boardWidth: width,
      board: new Array(this.state.boardHeight).fill(new Array(this.state.boardWidth).fill(0))
    });
  }

  // Resets game board back to blank when user clicks reset button
  onReset = () => {
    this.setState({ board: new Array(this.state.boardHeight).fill(new Array(this.state.boardWidth).fill(0)) })
  }

  // Generates random number
  getRandomNumber = (max) => {
    return Math.floor(Math.random() * Math.floor(max));
  }

  /* This is the function I am trying to build and generate a random starting game board with
  componentDidMount = () => {
    // Stores random number 1 or 2
    const number = this.getRandomNumber(2);
    const data = this.state.board;

    // This is what I need help on
    const startingBoard = data.map((row, y) => {
                            row.map((ea, x) => {
                              return 1;
                            })
    })

    // After startingBoard is working I can set state with startingBoard
    this.setState({
      board: startingBoard
    });
  }
*/


  // Called when user clicks on specific square. Changes color of square depending on if it's alive or not
  isSquareAlive = (x, y) => {
    const data = this.state.board;
    const ySquare = y;
    const xSquare = x;

    const newData = data.map((row, y) => {
      return y === ySquare ? (
        row.map((cell, x) => x === xSquare ? (cell + 1) % 2 : cell)
      ) : (
        row
      )
    })

    this.setState({ board: newData });

  }



  render() {
    /*console.log('Random number is : ' + this.state.randomNum);*/
    return (
      <div>
      <div className="game-container">

      <GameBoard
        height={this.state.boardHeight}
        width={this.state.boardWidth}
        reset={this.onReset}
        board={this.state.board}
        alive={this.isSquareAlive}
        isAlive={this.state.alive}
      />

      <Controls
        selectBoardSize={this.selectBoardSize}
        iterations={this.state.iterations}
        onReset={this.onReset}
      />

      </div>

      <div className="info-container">
        <Info />
      </div>
      </div>
    );
  }
}

export default App;

Возвращение 1 в startingBoard было простоя являюсь нубом и пытаюсь заставить это что-то вернуть.

Просто повторюсь: доска создана так:

this.state.board = new Array(this.state.boardHeight).fill(new Array(this.state.boardWidth).fill(0));

Как я могу вставить случайные числа в двумерный массив?

1 Ответ

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

Вот упрощенное приложение.Я думаю, что это может работать, чтобы установить начальное значение для state.board в конструкторе.Это должно эффективно создавать новую доску каждый раз, когда пользователь запускает приложение.

import React, {Component} from 'react';

const createRandomBoard = (height, width) => {

  const randomCellValue = () => (Math.random() < 0.5 ? 1 : 0);

  // thank you @simonbor on StackOverflow:
  // /5677035/sozdat-massiv-so-sluchainymi-znacheniyami
  const createRow = () => Array.from({length: width}, randomCellValue);

  return Array.from({length: height}, createRow);
};


class App extends Component {
  constructor(props){
    super(props);
    const boardHeight = 50;
    const boardWidth = 30;

    this.state = {
      boardHeight,
      boardWidth,
      board: createRandomBoard(boardHeight, boardWidth),
    };
  }

  render() {

    return (
      <div>

      </div>
    );
  }
}

export default App;

Сядьте на stackblitz: https://stackblitz.com/edit/so-gol-answer?file=App.js

...