Laravelで将棋アプリを作りたい（第四回）

[第一回：プロジェクト作成 ~ 盤面作成](https://qiita.com/motoshi_cocoa/items/4397885d12185b9adb5b)
[第二回：駒移動](https://qiita.com/motoshi_cocoa/items/2c7903299f9cd4f7c1ca)
[第三回：DB連携](https://qiita.com/motoshi_cocoa/items/2f3d631dab76b418c91b)

今回は歩配置と駒を取る挙動の実装

#目次
[0.前回からの修正](#0-前回からの修正)
[1.歩配置](#1-歩配置)
[2.手番を設定](#2-手番を設定)
[3.駒を取る動作](#3-駒を取る動作)
[4.ゲーム終了の設定](#4-ゲーム終了の設定)

#0. 前回からの修正

共通部分だった最新手の取得をメソッドにする（`getLastRecord`という名前でメソッドを作成)。
駒の番号を`$pieceId`として定義する。0→王将または玉将、1~9→歩

```php:ShogiController.php
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文を用いて以下のように定義。

```php:const.php
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`メソッドへのリンクのついた「歩」マスを作成する。

![スクリーンショット 2021-04-09 17.44.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594194/bb235d5e-b973-480e-1406-37172c35ca8a.png)


歩は1マス前方にしか進めないので、移動可能ます取得の処理を王将とは別に記述する。

```php:ShogiController.php
// 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から取得した手番をビューに渡し、ビューでは手番に一致しないマスはリンクを無効にする。

![スクリーンショット 2021-04-09 17.57.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594194/23684c5c-07f2-e5a9-e9c0-7891b86f4d7a.png)

#3. 駒を取る動作

移動する時はリクエストに`move`という名前をつけた時と同様に、移動先に相手の駒がある場合は`take`という名前をつけて、コントローラーで処理を分ける。

リクエストで`take`が渡ってきたら、以下の動作で駒を取る動作を実現する。

 1. 移動先のマスから取られる駒を割り出す。

 2. その駒の手番を100（先手の駒になる場合）または101（後手の駒になる場合）としてデータを更新する。通常時の駒の取得には手番は0か1で取得するので、これらは取得されなくなり、盤面から消える。

 3. 駒を移動させる。

#4. ゲーム終了の設定

王将または玉将が取られた時、ゲームを終了として、別ページにリダイレクトさせる。

![スクリーンショット 2021-04-09 18.08.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594194/c58f217a-af22-fc1e-e27f-050db645ff95.png)

修正後のindexメソッド

```php:ShogiController.php
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'));
    }
 ```

今回はここまで。

![スクリーンショット 2021-04-09 18.12.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594194/43bd525e-e44a-d3dc-008b-a6ff347d51c3.png)

[Github](https://github.com/motoshifurugen/laravel-shogi)