ゲームのロジック

完了

このユニットでは、"コネクト フォー" ゲームのしくみと、ゲームを作成するために知っておく必要のある Blazor のコンストラクトについて説明します。

コネクト フォー

"コネクト フォー" ゲームは、対戦相手より先に、4 つのゲーム ピースを横、縦、または斜めに並べるというものです。 このゲームを実装するときに考慮する必要があるのは、ゲーム ピースと対戦相手の現在の状態を追跡し、勝者をチェックすることです。 プログラミングのときは、ゲームのループ、つまり勝者を宣言できるようになるまで繰り返す必要がある一連のアクションを考えると役に立ちます。 次のようなものです。

  1. "リセット" 状態、つまりゲーム ピースのないクリーンなボードから始めます。
  2. ユーザーがゲーム ピースを配置します。
  3. 対戦相手がゲーム ピースを配置します。
  4. 勝者をチェックします。
    1. 勝者がいる場合は、勝者と終了ゲームを宣言するか、ゲームを再起動します。
    2. 勝者がいない場合は、ステップ 2 を繰り返します。

コードでの状態の表現

まず初めに、状態とは何でしょうか。 ゲームにおける状態とは、ゲーム内で行われていること、プレイヤーのポイントの数、ゲーム ピースが配置されている場所などのことです。

ゲーム開発での状態に関する重要なガイダンスは、状態を UI から分離しておくことです。このようにすると、メリットがいくつかありますが、中でも変更が容易になり、コードが読みやすくなります。

Blazor のコンテキストでは、これは、状態と状態に関するロジックを、次のように独自の C# クラスに配置する必要があることを意味します。

class State
{
    Player [] players;
    int gameRoundsPlayed;
    bool gameOver;

    State()
    {
        players = new Players[]
        {
            new Player() { Name= "Player", Points = 0 },
            new Player() { Name= "Opponent", Points = 0 }
        };
        gameRoundsPlayed = 0;
        gameOver = false;
    }

    void ResetGame() 
    {
        gameOver = false;
        players[0].Points = 0;
        players[1].Points = 0;
    }

    void EndGame()
    {
        gameOver = true;
        gameRoundsPlayed++;
        // award winner..
    } 
}

この State クラスには、ゲームをプレイしているユーザー、プレイされたゲーム ラウンドの数、ゲームがまだアクティブかどうかなどの情報が含まれます。

この State クラスのインスタンスを Blazor コンポーネント内で使って、ボードを描画し、ゲームの進行に合わせて他のアクションを実行できます。

OnInitialized でゲームの状態をリセットする

Blazor には、コンポーネントが初期化されるとき、それ以外のすべての処理が行われる前に呼び出されるメソッドがあります。 このメソッドは、ゲームを "リセット" 状態にする、つまりボードとプレイヤーを作成し、必要に応じて前のゲーム セッションのスコアをリセットするコードを配置するのに適しています。

コンポーネントのこの初期化を処理するメソッドは、OnInitialized と呼ばれます。

ゲームの状態のリセットを処理する OnInitialized メソッドは、次のようになります。

void OnInitialized() 
{
    state.ResetGame();
}

ここで厳密に何を行うかはあなた次第ですが、このコードからアイデアが得られるはずです。

イベントを使用したプレーヤーの対話式操作の処理

自分や相手が何かを行ったら、この対話式操作をキャプチャする必要があります。 ユーザーの対話式操作は、ゲームやアプリで応答するイベントとしてエンコードします。

たとえば、ボタンを選んだり、ドラッグ アンド ドロップ動作を実行してゲーム ピースを移動したりします。

コードでは次のようになります。

<span title="Click to play a piece" @onclick="() => PlayPiece(0)">🔽</span>

上記のコードでは、@onclick ディレクティブ属性は click イベントのハンドラーを指定しています。つまり、ユーザーがこの要素を選択しました。 イベントは、関数 PlayPiece(0) を呼び出すコード () => PlayPiece(0) によって処理されます。

状態の変更

ゲーム内で発生するアクションは、ゲームの状態に影響を与える必要があります。 PlayPiece() を呼び出す前述の例では、ボードのこの部分がピースによって占められるようになったことを示すように、状態を変更する必要があります。 つまり、この例の State クラスでは、次のようなゲーム ピースを表す方法が必要です。

class State 
{
    // other code omitted
    Piece [] pieces;

    State()
    {
        pieces = new Piece[25]; // 5x5 board
    }

    void PlayPiece(int position)
    {
        pieces[position] = true; // true = occupied
    }
}