簡體   English   中英

這行代碼出了什么問題? (反應,人生游戲)

[英]What is going wrong on this line of code? (React, 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> 

我認為當您嘗試計算邊緣上的圖塊的鄰居時會出現問題。 因為您正在嘗試訪問不在網格上的圖塊,所以循環中的某些變量變得不確定。 我建議添加一個if語句來檢查這一點。 就像是:

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

您應該一直循環播放,直到x和y小於board.length-2,而不是board.length-1,因為您試圖確保它不會評估木板的邊緣。 我認為您犯了一個相當普遍的錯誤,即忘記了數組的長度會比數組的最大索引多一個。

例如,如果其中一行看起來像[4,6,2,3],則其.length為4,但是如果您嘗試訪問row [4],則會得到未定義。 如果循環直到外循環中的長度為1,然后再向內循環中的每個值加+1,則代碼將執行此操作(因為從i / j在-1與1之間循環,然后將該值添加到外部索引中)。

另外,我認為您已經在內部數組中反轉了這些變量-您在外部循環中使用y作為行循環變量,在循環中使用x作為列循環變量,但在內部循環中將它們反轉。 因此,如果不是正方形,它將最終碰到不存在的行。

您的總體代碼應如下所示:

const evaluateGen = function(board){
  let nextGen = JSON.parse(JSON.stringify(board));

  for(let x = 1; x < board.length - 2; x++){
    for(let y = 1; y < board[y].length - 2; y++){

      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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM