React实战:井字棋 游戏

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/b954960630/article/details/86710048

一、展示:

功能:轮番下棋,能判断谁输谁赢,记录每一步棋并跳转到该步
组件:Game、Board、Square
在这里插入图片描述
在这里插入图片描述

二、源码:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World</title>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/[email protected]/babel.min.js"></script>
    <link rel="stylesheet" type="text/css" href="./src/css/index.css">
  </head>
  <body>
    <div id="root"></div>
 
    
    <script type="text/babel">
      //*********************************************** Square ***********************************************
    function Square(props) {
      let {handleClickSquare, index} = {...props};
      return (
        <div 
          className='square'
          onClick={handleClickSquare}
        >
          {props.value}
        </div>
      );
    }

    //*********************************************** Board ***********************************************
    function Board(props) {
      let squares = Array(9).fill(null).map((item, index) => {
        return (
          <Square 
            key={index}
            value={props.squares[index]}
            handleClickSquare={() => props.handleClickSquare(index)}
          />
        );
      });

      return (
        <div className='game-board'>
          {squares}
        </div>
      );
    }

    //*********************************************** Game ***********************************************
    class Game extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          history:[{squares: Array(9).fill(null)}],
          stepNumber: 0,
          nextPlayer:true,
        };
      }

      handleClickSquare(index) {
        let {history, nextPlayer, stepNumber} = {...this.state},
            squares = history[stepNumber].squares.slice(0),
            historySlice = history.slice(0, stepNumber + 1);
        
        if(squares[index] || calculateWinner(history[history.length - 1].squares)) {
          return null;
        }
        squares[index] = nextPlayer ? 'X' : 'O';

        this.setState({
          history: historySlice.concat([{squares: squares}]),
          stepNumber: historySlice.length,
          nextPlayer: !nextPlayer,
        });
      }

      jumpTo(step) {
        this.setState({
          stepNumber: step,
          nextPlayer: (step % 2) === 0,
        });
      }

      render() {
        let {history, nextPlayer, stepNumber} = {...this.state},
            winner = calculateWinner(history[history.length - 1].squares),
            state,
            moves;

        moves = history.map((item,index) => {
          let desc = index ? 'Go to move # ' + index : 'start move';
          return (
            <li key={index}>
              <button onClick={() => this.jumpTo(index)}>{desc}</button>
            </li>
          );
        });

        if(winner) {
          state = 'winner is : ' + winner; 
        }else {
          state = 'Next is : ' + (nextPlayer ? 'X' : 'O');
        }

        return (
          <div className='game'>
            <Board 
              squares={history[stepNumber].squares}
              handleClickSquare={(index) => this.handleClickSquare(index)}
            />
            <div className='game-info'>
              <div>{state}</div>
              <ol>{moves}</ol>
            </div>
          </div>
        );
      }
    }

    ReactDOM.render(
      <Game />,
      document.getElementById('root')
    );

    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]
      ];
      for (let i = 0; i < lines.length; i++) {
        const [a, b, c] = lines[i];
        if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
          return squares[a];
        }
      }
      return null;
    }
    </script>
  </body>
</html>

./src/css/index.css:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
.game {
  display: flex;
  flex-direction: row;
  margin: 20px;
}
.game-board,
.game-info {
  display: inline-block;
}
.game-board {
  width: 102px;
  height: 102px;
}
.game-info {
  margin-left: 40px;
}
.square{
  width: 34px;
  height: 34px;
  line-height: 34px;
  text-align: center;
  font-size: 20px;
  border: 1px solid #999;
  float: left;
}

猜你喜欢

转载自blog.csdn.net/b954960630/article/details/86710048