javascript - 这行代码出了什么问题? ( react ,生命游戏)

标签 javascript reactjs conways-game-of-life

有一个我不明白的错误。当我按下 <button>50x70</button>然后按<button>run</button>我收到这个错误。 我不明白为什么,因为它适用于标准 50x50 板。

为什么这行代码会导致错误? neighbors+=board[x+i][y+j].value https://codepen.io/anon/pen/OjoZKX

TypeError: Cannot read property '0' of undefined
evaluateGen
C:/Www/Projects/gameoflife/src/App.js:65
  62 | 
  63 | for(let i=-1; i <= 1; i++){
  64 |   for(let j=-1; j<= 1; j++){
> 65 |     neighbors+=board[x+i][y+j].value
  66 |   }
  67 | }
  68 | neighbors-=board[x][y].value
View compiled
(anonymous function)
C:/Www/Projects/gameoflife/src/App.js:108
  105 | 
  106 | run(){
  107 |   this.interval = setInterval(() => {
> 108 |       const nextState = evaluateGen(this.state.board)
  109 |       this.setState({paused: false, generation: this.state.generation + 1, board: nextState})
  110 |     }, 50)
  111 | }

// creates the board with random 1/0 value.
const createBoard = function(width, height) {
  let board = []
  for(var x = 0; x < width; x++){
    board.push([])
    for(var y = 0; y < height; y++){
      if(x === 0 || y === 0) {
        board[x].push({value: 0})
      } 
      else if (x === width-1 || y === height-1){
        board[x].push({value: 0})
      }
      else {
        let number = Math.round(Math.random())
        board[x].push({value: number})
      }
    }
  }
  return board
}

//  Game Of Life rules.
const evaluateCell = function(x, cell){
  let value = x
  if(x < 2){
    value = 0
  }
  else if(x === 2){
    value = cell
  }
  else if(x === 3){
    value = 1
  }
  else if(x > 3){
    value = 0
  }
  else {
    console.log('error: default case evaluateCell()')
    value = 0
  }
  return value
}

// evaluates a generation of board state by going through each cell and counting neighbors and calling evaluateCell accordingly.
const evaluateGen = function(board){
  let nextGen = JSON.parse(JSON.stringify(board));
  
  for(let y = 1; y < board.length - 1; y++){
    for(let x = 1; x < board[y].length - 1; x++){
      
      let neighbors = 0
      
      for(let i=-1; i <= 1; i++){
        for(let j=-1; j<= 1; j++){
          neighbors+=board[x+i][y+j].value
        }
      }
      // remove current cell from neighbors.
      neighbors-=board[x][y].value
      let nextvalue = evaluateCell(neighbors, board[x][y].value)
      nextGen[x][y].value = nextvalue
    }
  }

  return nextGen
}






class App extends React.Component {
  
  constructor(){
    super()
    this.state = {
      width: 50,
      height: 50,
      board: createBoard(50, 50),
      paused: false,
      generation: 0
    }
  }

  generateBoard(width, height) {
    this.pause()
    const board = createBoard(width, height)
    this.setState({board, generation: 0, width, height })
  }
  
  pause(){
    clearInterval(this.interval)
    this.setState({paused: true})
  }

  run(){
    this.interval = setInterval(() => {
        const nextState = evaluateGen(this.state.board)
        this.setState({paused: false, generation: this.state.generation + 1, board: nextState})
      }, 50)
  }

  componentDidMount() {
    this.run()
  }


  componentWillUnmount() {
    clearInterval(this.interval)
  }


  render() {
    
    let {board, generation, width, height} = this.state
    return (
      <div className="App">
        <h3>generation:{generation}</h3>
        {board.map(x => x.map(item => {
          return (
            <div className={`state-${item.value}`}></div>
          )
        }))}
        <button onClick={()=> this.run()}>run</button>
        <button onClick={()=> this.pause()}>pause </button>
        <button onClick={()=> this.generateBoard(width, height)}>generate</button>
        <button onClick={()=> this.generateBoard(50, 70)}>50 x 70</button>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('root'))
.App div {
  width: 10px; height: 10px;
  outline: 1px solid black;
  
}
.App {
  display: flex;
  flex-wrap: wrap;
  width: 500px; height: 500px;
}

.state-1{
  background-color: red;
}
<div id='root'></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

最佳答案

我认为当您尝试计算边上瓷砖的邻居时会出现问题。因为您正在尝试访问不在网格上的图 block ,所以循环中的某些变量变得未定义。我建议添加一个 if 语句来检查这一点。像这样的东西:

if(x+i >= 0 && y+i >= 0){
    neighbors+=board[x+i][y+j].value
}

关于javascript - 这行代码出了什么问题? ( react ,生命游戏),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45900135/

相关文章:

javascript - 阻止 Chrome 提示从输入框保存密码?

javascript - React Web 应用程序遇到严重延迟

python - after 方法在 tkinter 中如何工作?

java - 调试生活游戏,Java

javascript - 由于 cors,将图像上传到 imgur 失败

javascript - 手机输入栏 : automatically push to top on select

javascript - 将 Vbscript 传递给 Javascript

reactjs - 使用 React Router 将类 active 添加到其他父 html 标签

javascript - 仅针对一种表单的单一 onChange

javascript (es6) forEach 中过滤器的返回值