はじめに
私自身の復習兼、備忘録的な意味もあり、複数回の記事に渡って React を用いてマルバツゲーム(三目並べ)を開発していきたいと思います。
シリーズの一覧
- React入門1: 環境構築 [オンライン版]
- React入門2: 盤面の作成
- React入門3: インタラクションの実装
- React入門4: リファクタリング [リフトアップ編]
- React入門5: リファクタリング [インタラクション編]
- React入門6: 手番の実装 (今回)
- React入門7: ゲームの勝利判定
- React入門8: テキストの実装
- React入門9: タイムトラベル(1)
- React入門10: タイムトラベル(2)
- React入門11: タイムトラベル(3)
目的について
全体の目的
React公式のチュートリアルで公開されているマルバツゲームを 3x3 のマスで実装していきます。
今回の目的
マスが「X」だけでなく「O」も表示できるようにして、手番(ターン)を実装していきます。
手番の実装
次のページで、前回のソースファイルを確認できます。
- 前回の内容はコチラから!
「O」の表示
App.js の Board
コンポーネントに次の変更をしましょう。
- 手番を表す変数を作成する
-
state
型の変数xIsNext
を宣言する- 初期値を
ture
とする - set関数の名称を
setXIsNext
とする
- 初期値を
-
-
handleClick()
関数の変更-
xIsNext
変数で手番を制御する-
xIsNext
変数が真のときに、「X」を表示する -
xIsNext
変数が真ではないときに、「O」を表示する
-
- マスの表示を更新した後に手番を相手に譲る
- set関数で
xIsNext
の真偽値を反転させる
- set関数で
-
import { useState } from "react";
import "./styles.css";
function Square({ value, onSquareClick }) {
return (
<button className="square" onClick={onSquareClick}>
{value}
</button>
);
}
export default function Board() {
const [squares, setSquares] = useState(Array(9).fill(null));
const [xIsNext, setXIsNext] = useState(true);
function handleClick(i) {
const nextSquares = squares.slice();
if (xIsNext) {
nextSquares[i] = "X";
} else {
nextSquares[i] = "O";
}
setSquares(nextSquares);
setXIsNext(!xIsNext);
}
return (
<>
<div className="board-row">
<Square value={squares[0]} onSquareClick={() => handleClick(0)} />
<Square value={squares[1]} onSquareClick={() => handleClick(1)} />
<Square value={squares[2]} onSquareClick={() => handleClick(2)} />
</div>
<div className="board-row">
<Square value={squares[3]} onSquareClick={() => handleClick(3)} />
<Square value={squares[4]} onSquareClick={() => handleClick(4)} />
<Square value={squares[5]} onSquareClick={() => handleClick(5)} />
</div>
<div className="board-row">
<Square value={squares[6]} onSquareClick={() => handleClick(6)} />
<Square value={squares[7]} onSquareClick={() => handleClick(7)} />
<Square value={squares[8]} onSquareClick={() => handleClick(8)} />
</div>
</>
);
}
実行結果を次に示します。これで、マスをクリックすると、「X」と「O」が交互に表示されるようになりました。
表示処理の修正
現状のプログラムでは、マスの状態が空白である否かを確認せずに「X」と「O」を表示させています。従って、既にどちらかの印をつけたマスを、再びクリックすると内容を塗り替えることできるバグがあります。
これを修正するために、Board
コンポーネントの handleClick()
関数にて、クリックしたマスに印が既につけられている場合は、早期リターンをする処理を加えましょう。
function handleClick(i) {
if (squares[i]) {
return;
}
const nextSquares = squares.slice();
if (xIsNext) {
nextSquares[i] = "X";
} else {
nextSquares[i] = "O";
}
setSquares(nextSquares);
setXIsNext(!xIsNext);
}
これで、既に印があるマスに対してクリックをしても、表示が変更されることはありません。
おわりに
今回は、マスで手番を実装することで、プレイヤーの概念が生まれました。次のページに現段階のソースファイルを示します。
次回は、盤面の状況からゲームの勝者を判定するプログラムを開発していきます。React というよりは、どのようにアルゴリズムを導出するかを中心に記しています。