🐡

【React】チュートリアルやってみた④

2021/05/10に公開

環境

Windows10Pro

目次

①Reactのプロジェクトを作成し、Webからアクセスできることを確認する。
https://zenn.dev/taka_tech/articles/773da5de8c822a
②クリックしたマスに×を表示させる。
https://zenn.dev/taka_tech/articles/17600f9bc5d4b5
③手番を追加し、クリック時に〇と×が交互に表示されるようにする
https://zenn.dev/taka_tech/articles/e1c0b0b01e9b96
④勝利判定を実装する。←ここ
⑤履歴機能を実装する。
https://zenn.dev/taka_tech/articles/141760436bef12

最終目標

Reactチュートリアルの三目並べゲームを作成する
https://ja.reactjs.org/tutorial/tutorial.html

目標④

勝利判定を実装する。

実践

勝利判定を行うヘルパー関数を実装

以下のヘルパー関数をファイル末尾に実装する。

index.js
// 勝利判定ヘルパー関数
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];
        // 列の3箇所全ての記号が同じか比較
        if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
            // 記号を返す
            return squares[a];
        }
    }
    // 列に同じ記号が1つも並んでいない場合はnullを返す
    return null;
}

勝利者が決まった時にメッセージが変更されるようにする

Boardコンポーネントのrenderメソッドに先ほど作成したヘルパー関数を使って、勝利者を表示するように修正する。

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

勝利確定後にボードを扱えないようにする

BoardコンポーネントのhandleClickメソッドの処理で、すでに勝利者が確定しているもしくは、既にマスに〇か×が表示されている場合は、即リターンするように修正する。

index.js
    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,
        });
    }

Boardコンポーネントのコンストラクタでstateに真偽値をセットする処理を追加する。

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

ブラウザで試してみる

同じ記号が1列に並ぶとメッセージが変わり、クリックしても何も起きなくなることが確認できる。

Discussion