gallu’s blog

エンジニアでゲーマーで講師で占い師なおいちゃんのブログです。

ブラックジャックを設計してみる:本体

とりあえず「どのタイミングで通信を発生させて」「情報を保存するか」ってあたりがキモだと思うんで、その辺を中心に。
おいちゃんは、この手の物は割と「永続インスタンス」を使うほうなので、それで説明をしていきます。


とりあえず「ユーザを特定できる(authenticationは必要ないので、authorizationが出来る)」前提で。
PHPだと、session機能使うと楽ですな。


ユーザから「ページを表示する」リクエストが来ます。bj.phpとかいうプログラムと仮定しましょう。
今回は多分、bj.php?掛け金=金額、ってなリクエストが来ていると思われます。
session情報に「なにもない」場合、new gameってことで、インスタンスを作ります。
…細かい話を書くと「パラメタに掛け金があるから、newゲームだろう」って判断ではなくて「セッション情報にインスタンスがないから、newゲームだろう」って判断をするようにしてくださいませ。そうしないと「不利になったら掛け金をパラメタにぶちこむとゲームがリセット出来ちゃう」状況が出来上がるので。
ゲームの開始なので「掛け金」がrequestされているはずです。掛け金が0ならエラーreturnします。
とりあえず
・トランプ一式を、シャッフルした状態
で持っているクラス。
このクラスをnewします。


このクラスに、requestデータの「掛け金」を記録しておきます。


一端「親1人、子1人」と仮定。
先ほどのクラスには「親の手札」と「子の手札」がpushできる場所を確保しておきます。
んで
・山からカードを2枚引いて、親の手札に入れる
・山からカードを2枚引いて、子の手札に入れる
って操作をしておきます。


クラスの中は
・山札(52枚から4枚引かれてるので、48枚)
・親の手札(2枚)
・子の手札(2枚)
って感じ。
このインスタンスをセッションに保存しておきます(インスタンスの保存の仕方は、おまけ http://d.hatena.ne.jp/gallu/20140625/p5 を参照)。


レスポンスとしては
・子の手札2枚ともの、スートと数字の情報
・親の手札のうち、1枚目の、スートと数字の情報
を含む情報をレスポンスします。
これを「HTMLでreturn」しても「jsonでreturnして、HTML側のJSでレンダリング」しても、あんまり状況は変わらないのでお好みで。


以降、ユーザからのリクエストは、以下があり得るので以下のように処理します。

降りる(サレンダー (Surrender))

bj.php?mode=surrender
・掛け金の半額をコイン情報(今回は、Cookieに持っている事を想定しています)からさっぴく。端数は切り上げだよねぇw
・セッションのインスタンスを削除する(unsetなりNULLぶちこむなり)
・適当なHTMLでreturnする。まぁ「降りました」ってHTMLか、または「new gameをどんぞ」って画面だよね。

ヒット (Hit)

bj.php?mode=hit
「カードをもう一枚」という意思表示なので、以下のように処理します。
・セッションからインスタンスを取得
・子の手札にカードを1枚追加
・もしバスト(21を超える)になったら、「負け処理」に遷移する
・バストしてなければ、responseを返す。responseには「子の手札全ての、スートと数字の情報」「親の手札のうち、1枚目の、スートと数字の情報」が含まれる

スタンド (Stand)

bj.php?mode=stand
「カードを引かずにその時点の点数で勝負する。」という意思表示なので、以下のように処理します。
・親が、己のAIの設定に従ってカードを引く
・親がバストしていたら、「勝ち処理」に遷移する
・子 >= 親なら、「勝ち処理」に遷移する
・子 < 親なら、「負け処理」に遷移する

勝ち処理

インスタンスの「掛け金」を、ユーザのコインに足す
・セッションのインスタンスを削除する(unsetなりNULLぶちこむなり)
・適当なHTMLでreturnする。まぁ「勝ったよおめでとう!」ってHTMLか、または「new gameをどんぞ」って画面だよね。

負け処理

インスタンスの「掛け金」を、ユーザのコインから減算する
・セッションのインスタンスを削除する(unsetなりNULLぶちこむなり)
・適当なHTMLでreturnする。まぁ「あらら残念 orz」ってHTMLか、または「new gameをどんぞ」って画面だよね。


大体こんなもん?