ASP.NET Core版 対人対戦できるぷよぷよをつくる(10)の続きです。

世の中にはゲームがうまい人もいれば壊滅的に下手な人もいます。鳩でもわかるC# 管理人は落ち物系ゲームが苦手です。そこで強い人を相手にしてもそこそこ楽しめるようにハンディキャップ戦ができるようにします。

どのようなハンディキャップを採用するか?

どのようなハンディキャップにするかですが、おじゃまレートを変更します。おじゃまレートはぷよを消したときにどれだけの数のおじゃまぷよを送り込めるかに影響をあたえます。得点÷おじゃまレートが相手に送り込むことができるおじゃまぷよの数です。少ない値のほうがより多くのおじゃまぷよを送りこめます。通常、おじゃまレートは70で、これまで作ってきたゲームもそのようになっています。

対戦して勝つと勝ち点がつきます。勝ち点が異なるプレイヤー同士が対戦するのであればランク差でおじゃまレートを異なる値に変更します。

具体的には

それ以降は 強い側のレートを5ずつ上げ弱い側のレートは30で変更しません。またハンディキャップ戦ができるのは両方のプレイヤーがログインをしているときだけです。少なくとも片方がログインしていない場合はハンディキャップなしの従来と同じ条件で対戦することになります。

これで強い人と対戦してそれなりに勝負ができるのかはわかりませんが(つまり暫定的)、当面これを採用します。

悲報!!勝てませんでした

初戦だけ相手がハンディキャップの内容を理解していないのをいいことに勝てましたが、それ以降はズタボロにやられました。我ながら弱すぎです。

対戦の長期化を防ぐ

それから弱い人同士だと大連鎖が実現しないのでなかなか勝負がつきません。そこでゲーム開始から時間が一定時間が経過するごとにおじゃまレートを減らしていきます。

以下はぷよぷよフィーバーにおけるマージンタイム到達後のおじゃまぷよレートの変動調査の結果です。これは「ぷよぷよフィーバー」のものなので初期値は70ではなく120です。開始からの経過時間が長くなるとたとえ1連鎖でも大量のおじゃまを送り込むことができてしまいます。

引用元:おじゃまぷよレートの変動調査

まったく同じものにしても面白くないので最初の90秒は初期値のままとし、それ以降は10秒経過するたびに5減らします。またどんなにレートが下がっても10未満にはならないようにします。レートが1まで下がると1連鎖で40個のおじゃまぷよが発生するのはさすがにやりすぎのような気がします。

それではさっそくそのように作りかえてみましょう。

ユーザーのレベルを取得する

まずログインユーザーを管理するクラスにそのプレイヤーはユーザー登録されている人なのか?登録されているのであればその人のレベルはどうなのかを取得するメソッドを追加します。

後日談:さっそくダメ出しが入りました。単純な勝ち数だけでは弱い人同士で何回も対戦すればそれだけでレベルがどこまでも上がってしまう。下げる処理も必要なのではないか?

この記事ではレベルは上がるだけという前提ですすめます。

エントリーしたらレベルに関する情報も必要なので、これを取得するためのメソッドを追加します。引数と一致するユーザーが記録されていないのであればレベルは-1とします。

エントリー時の処理

対戦をするときはエントリーボタンをクリックしますが、そのときにPuyoMatchHub.Enteryメソッドが呼び出されます。このときに上記のLoginModel.GetPlayerInfoメソッドで登録されているユーザーの名前と同じものがあればトークン、レベル、獲得総得点を取得します(ここで必要なのは前2者)。

ファイルの書き込み時と重なって例外が発生するかもしれないので例外処理をしています。例外が発生したらエントリーが失敗した旨を表示します。時間をずらせばできるはずです。

それからエントリーしたプレーヤー名と同じ名前だけどユーザー登録している人とは別人の可能性があります。これはトークンを比較すれば区別できます。ユーザー登録していないプレーヤーのレベルは-1として扱います。

エントリーしようとしているプレーヤーのレベルがわかったらPlayerInfoのコンストラクタにこれらとともに必要な引数を渡します。

PlayerInfoクラスにプロパティを追加する

PlayerInfoクラスにレベル関連のプロパティを追加します。またコンストラクタの引数を変更します。

おじゃまレートを変動制にする

これまではおじゃまレートは定数70でした。今回はそれを変更するので定数は廃止します。かわりに新たにレートプロパティを追加します。

長期戦になったらおじゃまレートを変更する

ゲームを開始するときにゲーム開始以降の経過秒数を格納する変数(_elapsedSeconds)に-90をセットします(90秒経過以降に10秒ごとであれば_elapsedSecondsが負数であるあいだはなにもしない)。

1秒経過するたびに_elapsedSecondsをインクリメントして0以上のときで10で割り切れるときはおじゃまレートを減らします。ただし10以下にはならないようにします。

新たに設定したおじゃまレートから送り込めるおじゃまぷよの数を計算する

連鎖が発生したらそれぞれのおじゃまレートから相手に送り込むことができるおじゃまぷよの数を計算します。

第2戦目以降の処理

ひとつの対戦が終了したら_elapsedSecondsとOjamaRates[]を初期値に戻します。

クライアントサイドへのデータの送信

PuyoMatchHub.Updateが呼び出されたら、これまで送信していたものに加えておじゃまレートとプレーヤーのレベルを送信します。

クライアントサイドの処理

サーバーサイドからデータを受信したらこれをグローバル変数に格納します。そして

Update関数が呼び出されたら保存しておいたグローバル変数を利用して描画処理をおこないます。