0
1

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 3 years have passed since last update.

Laravelで将棋アプリを作りたい(第二回)

Last updated at Posted at 2021-02-14

第一回:プロジェクト作成 ~ 盤面作成

今回は、駒移動

#目次
0.前回からの修正
1.駒を押したら、移動可能マスを選択できるようにする。
2.移動可能マスを押したら移動できるようにする。

#0. 前回からの修正

ビューに渡していた$appNameは必要ないので削除した。
駒の画像が読み込めないことが起こったため、画像ではなくテキストにした。
$r(列)$c(行)をくっつけた変数($r . $c)を新たに$square(マス)と定義した

#1. 駒を押したら、移動可能マスを選択できるようにする。

細かい要件は以下。今回は王将のみの実装

  • 駒を押したら、その駒の移動可能マスを探す。

  • 1.1. 駒をリンクにして、現在いるマス目を引数で渡す。

  • 1.2. そのマス目を元に、移動可能マスを割り出す。

  • 移動可能マスに色を付けてボタンにする。

  • 1.3. 移動可能マスでは表示を変える。

###1.1. 駒をリンクにして、現在いるマス目を引数で渡す。

indexページの駒をselectページへの引数を持ったリンクにする。

引数には駒名、列、行を「:」でつなげた文字列が入るようにする。

リンク部分

<a style="text-decoration:none" href="' . action('App\Http\Controllers\ShogiController@select', 'myKing:' . $r . ':' . $c) . '"></a>

修正後のindexページ

resources/views/index.blade.php
<!DOCTYPE html>
<html>
<head>
    <title>将棋アプリ</title>
    <link rel="stylesheet" href="{{ asset('css/style.css') }}">
</head>
<body>
    <div class="board">
        <?php
        for ($c = 1; $c < 10; $c++) {
            echo '<div class="column column' . $c . '" id="column' . $c . '">';
            for ($r = 9; $r > 0; $r--) {
                $square = $r . $c;
                if ($square == $MyKing) {
                    echo '<p class="piece row square' . $square . '" id="square' . $square . '"><a style="text-decoration:none" href="' . action('App\Http\Controllers\ShogiController@select', 'myKing:' . $r . ':' . $c) . '">王</a></p>';
                } else {
                    echo '<p class="row square' . $square . '" id="square' . $square . '">' . $square . '</p>';
                }
            }
            echo '</div>';
        }
        ?>
    </div>
</body>
</html>

selectビューを新たに作成

resources/views/shogi/select.blade.php
// 新規作成
<!DOCTYPE html>
<html>
<head>
    <title>将棋アプリ</title>
    <link rel="stylesheet" href="{{ asset('css/style.css') }}">
</head>
<body>
    <div class="board">
        <?php 
        for ($c = 1; $c < 10; $c++) {
            echo '<div class="column column' . $c . '" id="column' . $c . '">';
            for ($r = 9; $r > 0; $r--) {
                $square = $r . $c;
                if ($square == $MyKing) {
                    // 駒のあるマスには piece というクラスを追加
                    echo '<p class="piece row square' . $square . ' selected" id="square' . $square . '">王</p>';
                } else {
                    echo '<p class="row square' . $square . '" id="square' . $square . '">' . $square . '</p>';
                }
            }
            echo '</div>';
        } 
        ?>
    </div>
</body>
</html>

###1.2. そのマス目を元に、移動可能マスを割り出す。

コントローラーにselectメソッドを追加

app/Http/Controllers/ShogiController
    // 追加
    public function select($piece)
    {
        // $pieceには King:5:9 のように駒名、列、行が「:」でくっついた形が入る。
        $select = explode(":", $piece);
        $pieceName = $select[0];
        $row = $select[1];
        $column = $select[2];
        $MyKing = $row . $column;
        $ways = array();
        // 王将の移動可能マスを割り出して、$waysに追加する。
        for ($c = $column-1; $c < $column+2 ; $c++) {
            for ($r = $row-1; $r < $row+2 ; $r++) {
                $ways[] = $r . $c;
            }
        }
        // 重複削除
        $way = array_unique($ways);
        // 移動可能マスを $way という配列に入れてselectページに渡す
        return view('shogi/select', compact('MyKing', 'way'));
    }

selectメソッドへの引数つきのルートを追加

routes/web.php
// 追加
Route::get('shogi/select/{piece}', 'App\Http\Controllers\ShogiController@select');

###1.3. 移動可能マスでは表示を変える。

コントローラーから渡された引数を元にselectページの表示を条件分岐する。

マス目が$wayに含まれるときはclasswayを追加して、さらにgoボタンを表示させる。

resources/views/select.blade.php
<!DOCTYPE html>
<html>
<head>
    <title>将棋アプリ</title>
    <link rel="stylesheet" href="{{ asset('css/style.css') }}">
</head>
<body>
    <div class="board">
        <?php 
        for ($c = 1; $c < 10; $c++) {
            echo '<div class="column column' . $c . '" id="column' . $c . '">';
            for ($r = 9; $r > 0; $r--) {
                $square = $r . $c;
                if ($square == $MyKing) {
                    // 駒のあるマス selectedクラスを追加
                    echo '<p class="piece row square' . $square . ' selected" id="square' . $square . '">王</p>';
                } elseif (in_array($square, $way)) {
                    // 移動可能マス
                    echo '<p class="row square' . $square . ' way" id="square' . $square . '"><input type="button" value="go"/></p>';
                } else {
                    // それ以外のマス
                    echo '<p class="row square' . $square . '" id="square' . $square . '">' . $square . '</p>';
                }
            }
            echo '</div>';
        } 
        ?>
    </div>
</body>
</html>

追加したクラスを元にCSSを追加

public/css/style.css
// 追加
.selected {
    background-color: yellow;
}

.way {
    background-color: red;
}

.piece {
    font-size: 30px;
    font-weight: bold;
}

これで、indexで駒のリンクを踏むと、selectでは移動可能マスを選択できるようになった。

移動可能マスが表示されたselectページ

#2. 移動可能マスを押したら移動できるようにする。

細かい要件は以下。POST送信で移動先を教えるという流れにする。

  • どのgoボタンを押したか判別する。

    • 2.1. select ページに index 宛のフォームを作成する。
    • 2.2. どのボタンが押されたか区別できるように、押されたボタンには新たに「move」という名前をつける(JavaScript使用)
  • 押したボタンの位置にコマを移動する。

  • 2.3. 「move」と名前のついたボタンの情報から、移動先を決定する。

###2.1. select ページに index 宛のフォームを作成する。

moveformという名前のフォームを追加。csrf対策のために{{ csrf_field() }}も記述する必要がある。

<form action="/shogi" method="POST" name="moveform">
    {{ csrf_field() }}

hiddenタイプで $square の値を送る。
送信ボタンは、クリック時に movePiece という関数(後で作成)を実行するようにする。

echo '<input type="hidden" value="' . $square . '" name="square" id="data' . $square . '"></input>';
echo '<p class="row square' . $square . ' way" id="square' . $square . '"><input type="button" value="go" onclick="movePiece(' . $square . ')"/></p>';

別のJSファイルで記述する movePiece 関数を使えるようにするために、head内でJSを読み込む。

<script type="text/javascript" src="{{ asset('js/shogi.js') }}"></script>

以上によって修正したselectビュー

resources/views/select.blade.php
<!DOCTYPE html>
<html>
<head>
    <title>将棋アプリ</title>
    <link rel="stylesheet" href="{{ asset('css/style.css') }}">
    <script type="text/javascript" src="{{ asset('js/shogi.js') }}"></script>
</head>
<body>
    <div class="board">
        <form action="/shogi" method="POST" name="moveform">
            {{ csrf_field() }}
            <?php
            for ($c = 1; $c < 10; $c++) {
                echo '<div class="column column' . $c . '" id="column' . $c . '">';
                for ($r = 9; $r > 0; $r--) {
                    $square = $r . $c;
                    if ($square == $MyKing) {
                        // 駒マス
                        echo '<p class="piece row square' . $square . ' selected" id="square' . $square . '">王</p>';
                    } elseif (in_array($square, $way)) {
                        // 移動可能マス 送信されるデータはここにしかない
                        echo '<input type="hidden" value="' . $square . '" name="square" id="data' . $square . '"></input>';
                        echo '<p class="row square' . $square . ' way" id="square' . $square . '"><input type="button" value="go" onclick="movePiece(' . $square . ')"/></p>';
                    } else {
                        // それ以外のマス
                        echo '<p class="row square' . $square . '" id="square' . $square . '">' . $square . '</p>';
                    }
                }
                echo '</div>';
            }
            ?>
        </form>
    </div>
</body>
</html>

###2.2. どのボタンが押されたか区別できるように、押されたボタンには新たに「move」という名前をつける(JavaScript使用)

jsファイルはpublicフォルダに配置する。

クリックされたボタンのマス目を取得して、そのマス目と同じ番号のinputデータ(hiddenで作成した)に「move」という名前をつける。

public/js/shogi.js
// 新規作成
var movePiece = function (square) {
    // クリックされたボタンのマスを取得
    const data = document.getElementById('data'+square);
    // そのマスを「move」と名付ける
    data.name = 'move';
    // フォームのデータを送信する。
    document.moveform.submit();
}

###2.3. 「move」と名前のついたボタンの情報から、移動先を決定する。

indexへのPOST送信のルートを追加する。

routes/web.php
Route::post('shogi', 'App\Http\Controllers\ShogiController@index');

POST送信時のデータを使用するために、コントローラにRequestクラスの使用を記述。

app/Http/Controllers/ShogiController.php
// namespace App\Http\Controllers;の下に追加
use Illuminate\Http\Request;

indexメソッドで「move」がある場合は、それを王将の位置としてビューに渡す。
これで、王将が位置が変化したindexビューが表示される。

修正後のindexメソッド

app/Http/Controllers/ShogiController.php
    // POST送信のデータを引数で受け取る
    public function index(Request $request)
    {
        if ($request->isMethod('post')) {
            // POSTでのアクセス時の処理
            $MyKing = $request->input('move');
        } else {
            // GETでのアクセス時の処理
            $MyKing = '59';
        }
        return view('shogi/index', compact('MyKing'));
    }

これで、駒押す→移動可能マス表示→移動可能マス選択→移動 の繰り返しができるようになった。

移動できるようになった王将

今回はここまで。

Github

0
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?