0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【React】公式のチュートリアルをやってみる~⑦勝利判定を追加

Posted at

【React】公式のチュートリアルをやってみる~⑥プレイヤーの追加 の続きです。
プレイヤーを交互に指定できたので、最後に、勝利判定ができるようにしてみましょう。

勝利判定を追加する

勝利を判定する関数を追加する

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;
}
  • 多次元配列linesに、縦・横・斜めのパターンを定義する
    • 例えば、[0,1,2]は、一番上の段の横
      ReactApp3.png
  • 縦・横・斜めのパターンに対して、for文で1つずつ、揃っているか確認する
    • 例えば、squares[0]と、squares[1]と、squares[2]が同じ値(=XまたはO)であれば、揃っていると判断する
    • 揃っている場合は、squares[0](=XまたはO)が返される
    • 揃っていない場合はnullを返す

ステータスに勝利を表示する

class Board extends React.Component {
  // コンストラクタ
  constructor(props) {
    super(props);
    this.state = {
      squares: Array(9).fill(null),
      xIsNext: true,
    }
  }
  ()

  render() {
+   const winner = calculateWinner(this.state.squares);
+   let status;
+   if (winner) {
+     status = 'Winner: ' + winner;
+   } else {
+     status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
+   }

-    const status = 'Next player: ' + (this.state.xIsNext ? '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>
    );
  }
}
  • 関数render内でcalculateWinner(squares)を呼び出して、どちらのプレーヤーが勝利したかどうか判定する

  • winnerがnullでない場合(=勝者がいる場合)は、ステータスに勝者を表示する
    ReactApp8.png

  • winnerがnullの場合(=勝者がまだいない場合)は、ステータスに次のプレイヤーを表示する
    ReactApp7.png

マス目の選択を制御する

class Board extends React.Component {
  // コンストラクタ
  ()
  handleClick(i) {
    const squares = this.state.squares.slice();
+   if (calculateWinner(squares) || squares[i]) {
+     return;
    }
    squares[i] = this.state.xIsNext ? 'X' : 'O';
    this.setState({
      squares: squares,
      xIsNext: !this.state.xIsNext,
    });
  }
  renderSquare(i) {
    return (
      <Square 
        value={this.state.squares[i]}
        onClick={() => this.handleClick(i)}
      />
    );
  }

  render() {
    ()
  }
}
  • 今の状態だと、ゲームの決着がついていてもマスを選択できてしまう、また、すでに埋まっているマスをクリックすると次のプレイヤーに変更されてしまう
    • ゲームの決着がついた場合、クリックされたマス目が埋まっている場合には、returnして処理を抜ける

ReactApp9.png
三目並べゲームが完成しました~~!
公式のチュートリアルにはタイムトラベル機能の実装もありましたが、ここでいったん終了にします。
ちょっとずつ実装しながらReactの基礎を学べたので、初心者にとっても良い教材でした。さすが公式様です。

参考文献

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?