コマンドラインで動くようになったので、Web化してブラウザで遊べるようにしましょう。
Web化するときの問題点
Webの通信はステートレスです。Hit and Blowでは、「当てるべき数字」が問題になります。コンピュータが作った数字を当てるために何度も入力するので、当たるまで、その数字を覚えておかなければなりません。「当てる数字はxxxx」という状態(ステート)を保持しておく必要があります。
また、ゲームを進める上では、「どの数字だと 何 hit 何 blowか」という判定結果も表示したいです。履歴ですね。履歴ですから、今までプレーヤーが入力した数字とその判定結果を記録しておく必要があります。一方、ゲーム開始時点では、履歴はないはずですから、どこかのタイミングで履歴をクリアする必要があります。
セッション
リクエストをまたいで情報を伝えていくときに使う方法の1つが、セッションです。Hit and Blowでは、コンピュータが決めた数字をずっと伝えていく必要がありますし、プレーヤーが入力した数字とその判定結果も伝えていく必要があります。ですから、これらをセッションに格納します。
画面
Webの場合、基本的には、アクセスした結果を画面に表示します。Hit and Blowでは、プレーヤーが数字を入力(アクセス)しますから、受け取って判定して、その結果を表示させればよいでしょう。
最初(トップページ)にアクセスしたとき(ゲーム開始時点)はHTTP Method GETでの、数字を入力したときはHTTP Method POSTでのアクセスになりますので、ゲーム開始かプレー中かは、HTTP Methodで区別できます。
数字を当てた時はゲーム終了ですので、数字の入力欄は不要です。プレー中とは別の表示内容にします。トップページへのリンクを設けておけば続けてプレーできますし、そのリンクをクリックしたときはGETでのアクセスになるので、ゲーム開始だと判断できます。
Flaskを使う
FlaskはWebアプリケーションフレームワークです。Webでのお作法的なところはフレームワークに任せられるので、簡単に作れるようになります。安全に作れるかどうかは、使い方次第ですが。
ということで、Flaskを使ってWeb化したものが、こちら。
少しプログラムを見てみましょう。
ゲーム開始
ゲーム開始はトップページにHTTP Method GETでアクセスするので、
@app.route()
と付ければ、Webアクセスしたときの処理を行う関数になります。フレームワークって偉大。コンピュータに数字を作ってもらって、履歴(list型)は空っぽにしておきます。
画面の情報(HTML)を返す必要があるので、templatesディレクトリにあるindex.htmlを返すようにします。
プレー中(判定処理)
プレーヤーが入力した数字がPOSTで送られてくるので、
リクエスト先のpathが同じでも、methodによって処理する関数を分けられます。
数字の入力はhtmlのformで行われるので、request.form.get()
で取り出します。数字が入力されないまま送信される(ゲームとしては一手損する)こともあり得て、その場合、None
が返されます。空文字だったら型が同じで扱いやすいのに…。
ということで、(request.formget() or "")
です。None
はTrue
/False
の判定をすればFalse
になるので、or
の後ろにある""
が返されることになります。これで、常にstr型になります。
あとは、今までのinput_number()
と同じ処理を行って、4桁(4文字)の数字にします。数字かどうかのチェックはしていないので、4文字ですね。チェックはすべきでしょう。今回は手抜きです。
判定処理のjudge()
も変更しています。
今までは、数字が当たった時のメッセージをこの関数の中で表示していました。が、ゲーム終了の画面を用意することにしました。この関数で終了画面を返すのは、ちょっと欲張りすぎでしょう。judgeの名にふさわしく、hitとblowの数を返したいです。履歴のことを考えて、プレーヤーが入力した数字もいっしょに返しましょう。戻り値の型をtupleにして、プレーヤーの数字、hit数、blow数をまとめて返します。
judge()の戻り値にあるhitの数が4であれば、数字を当てられたということです。ゲーム終了ですので終了画面であるwin.htmlを返します。そうでなければ次の数字をプレーヤーに入力してもらうため、入力欄のあるindex.htmlを返します。
遊んでみる
プログラムを直接実行したときの処理も書いてあります。
ので、Visual Studio Codeでターミナルを開いて、
python3 main.py
と入力します。ブラウザで http://127.0.0.1:5000/ を開きましょう。数字を入力する欄のある画面が開くはずです。
数字を入力してJudgeボタンを押すと、判定結果が表示されます。
頑張って数字を当てましょう。