第一回:プロジェクト作成 ~ 盤面作成
第二回:駒移動
第三回:DB連携
今回は歩配置と駒を取る挙動の実装
#目次
0.前回からの修正
1.歩配置
2.手番を設定
3.駒を取る動作
4.ゲーム終了の設定
#0. 前回からの修正
共通部分だった最新手の取得をメソッドにする(getLastRecord
という名前でメソッドを作成)。
駒の番号を$pieceId
として定義する。0→王将または玉将、1~9→歩
public function getLastRecord($turn, $pieceId)
{
// 手番と駒の番号を引数にとり、最新手を返す。
$lastRecord = GameRecord::where('turn', $turn)->where('piece', $pieceId)->orderBy('id', 'desc')->first();
$record = (!empty($lastRecord['square'])) ? $lastRecord : config('const.start.' . $turn . '.' . $pieceId);
return $record;
}
#1. 歩配置
歩を配置する。現段階では初期値はconst.php
でfor文を用いて以下のように定義。
for ($i=1; $i<10; $i++) {
// 先手の歩
$start['start'][0][$i] = [
'turn' => 0,
'piece' => $i,
'square' => $i . 7
];
// 後手の歩
$start['start'][1][$i] = [
'turn' => 1,
'piece' => $i,
'square' => $i . 3
];
}
index.php
では王将と同様にselect
メソッドへのリンクのついた「歩」マスを作成する。
歩は1マス前方にしか進めないので、移動可能ます取得の処理を王将とは別に記述する。
// selectメソッド内で記述
// $select[2]は列番号、$select[3]は行番号
// 例)先手27歩の移動可能マスは26歩なので行番号を-1する。
if ($selectPiece['turn'] == 0) {
// 先手番の歩の移動可能マス取得
$ways[] = $select[2] . ((int)$select[3])-1;
} elseif ($selectPiece['turn'] == 1) {
// 後手番の歩の移動可能マスを取得
$ways[] = $select[2] . ((int)$select[3])+1;
}
#2. 手番を設定
先手後手交互に操作できるように手番を設定する。
コントローラーでDBから取得した手番をビューに渡し、ビューでは手番に一致しないマスはリンクを無効にする。
#3. 駒を取る動作
移動する時はリクエストにmove
という名前をつけた時と同様に、移動先に相手の駒がある場合はtake
という名前をつけて、コントローラーで処理を分ける。
リクエストでtake
が渡ってきたら、以下の動作で駒を取る動作を実現する。
-
移動先のマスから取られる駒を割り出す。
-
その駒の手番を100(先手の駒になる場合)または101(後手の駒になる場合)としてデータを更新する。通常時の駒の取得には手番は0か1で取得するので、これらは取得されなくなり、盤面から消える。
-
駒を移動させる。
#4. ゲーム終了の設定
王将または玉将が取られた時、ゲームを終了として、別ページにリダイレクトさせる。
修正後のindexメソッド
public function index(Request $request)
{
if ($request->isMethod('post')) {
// POSTでのアクセス時の処理
if (!empty($request->input('move'))) {
$data = new GameRecord;
$data->turn = $request->input('turn'); // 手番
$data->piece = $request->input('piece'); // 駒
$data->square = $request->input('move'); // 移動先マス
$data->save();
} elseif (!empty($request->input('take'))) {
// 取られた駒の保存処理
$takenData = new GameRecord;
$turn = ($request->input('turn') == '0') ? '1' : '0';
$takenData->turn = 100 + (int)$turn;
$takenPiece = GameRecord::where('turn', $turn)->where('square', $request->input('take'))->first();
$takenData->piece = $takenPiece['piece'];
$takenData->square = $request->input('take');
$takenData->save();
// 動く駒の保存処理
$data = new GameRecord;
$data->turn = $request->input('turn'); // 手番
$data->piece = $request->input('piece'); // 駒
$data->square = $request->input('take'); // 移動先マス
$data->save();
// 王(玉)が取られた時はゲーム終了
if ($takenData['piece'] == 0) {
$win = ($turn == '1') ? '先手' : '後手';
return view('shogi/result', compact('win'));
}
}
}
// 先手番の最新手を取得
$bKing = $this->getLastRecord(0, 0);
$bPawn = $this->getPawn(0);
// 後手番の最新手を取得
$wKing = $this->getLastRecord(1, 0);
$wPawn = $this->getPawn(1);
$nextTurn = $this->getNextTurn();
return view('shogi/index', compact('bKing', 'wKing', 'nextTurn', 'bPawn', 'wPawn'));
}
今回はここまで。