有两个玩家参与之后,就需要判断胜负,以及游戏何时结束。
在 Board.js 文件中添加 calculateWinner 方法来计算判断游戏,传入 squares 是一个长度为 9 的数组。
function calculateWinner (squares) { const lines = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6] ] const len = lines.length for (let i = 0; i < len; i++) { const [a, b, c] = lines[i] if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) { return squares[a] } } return null }
然后,修改 render 方法,在这里面调用 calculateWinner() 方法来判断是否玩家有胜出,如果有的话,就展示获胜消息。
const winner = calculateWinner(this.state.squares) let status if (winner) { status = 'winner:' + winner } else { status = 'Next player:' + (this.state.isNext ? 'X' : 'O') }
每次点击格子都会触发 handleClick 事件,需要在这个事件里面调用 calculateWinner() 方法,如果有一方玩家已胜出,或者该 Square 已经被填充时,就不做处理直接返回了。
handleClick (i) { const squares = this.state.squares.slice() if (calculateWinner(squares) || squares[i]) { return } squares[i] = this.state.isNext ? 'X' : 'O' this.setState( { squares: squares, isNext: !this.state.isNext } ) }
实践一下效果:
完整代码如下:
import React, { Component } from 'react' import Square from './Square' class Board extends Component { constructor(props) { super(props) this.state = { squares: Array(9).fill(null), isNext: true } } handleClick (i) { const squares = this.state.squares.slice() if (calculateWinner(squares) || squares[i]) { return } squares[i] = this.state.isNext ? 'X' : 'O' this.setState( { squares: squares, isNext: !this.state.isNext } ) } renderSquare (i) { return <Square value={this.state.squares[i]} onClick={() => this.handleClick(i)} /> } render () { const winner = calculateWinner(this.state.squares) let status if (winner) { status = 'winner:' + winner } else { status = 'Next player:' + (this.state.isNext ? 'X' : 'O') } return ( <div> <div className="status">{status}</div> <div className="board-row"> {this.renderSquare(0)} {this.renderSquare(1)} {this.renderSquare(2)} </div> <div className="board-row"> {this.renderSquare(3)} {this.renderSquare(4)} {this.renderSquare(5)} </div> <div className="board-row"> {this.renderSquare(6)} {this.renderSquare(7)} {this.renderSquare(8)} </div> </div> ) } } export default Board function calculateWinner (squares) { const lines = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6] ] const len = lines.length for (let i = 0; i < len; i++) { const [a, b, c] = lines[i] if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) { return squares[a] } } return null }