砂上の考察

日々の考察を残し、できれば意見をもらい、また考察する。。。

LINE Botを使った対戦型ゲーム制作~バイオハザード7の「21」を対人ゲームに~

   この記事ではプログラミングほぼ初心者の筆者がLINE Botを利用した簡単なゲーム開発法を紹介しています。Pythonを少し勉強(classらへんまで)していればお好みでアレンジができると思います。バイオ7の「21」を友人と遊びたい人は後半に記載したコードをコピペして遊べると思います。

1.経緯

・LINE Botを用いた理由

   ゲームの実装方法はいろいろあります。例えばスマートフォン向けにApp StoreGoogle Playなどにリリースする方法や、ブラウザアプリを開発し公開する方法などがあります。前者はリリースに審査があったり、お金がかかったりし、筆者のような初心者が少し試したり、友人と少し遊ぶ程度に用いるには大変で、後者はレンタルサーバーなどわからないことが多く、ハードルが高かったため、他の方法を模索した結果、友人を含め、多くの人が利用しているLINEのBotで簡単に実装できたため、それを紹介したいと思います。

バイオハザード7の「21」を再現した理由LINE Bot

   カプコンの人気シリーズの1つであるバイオハザードシリーズの作品の一つのバイオハザード7のDLCの1つである「Banned Footage Vol.2」には「21」というブラックジャックのようなゲームが収録されています。このゲームの詳細は下に書きますが、結論を先に言うと、対人戦がないのがもったいないと感じたからです。考えたら勝率をかなり向上できる点が一番おもしろい点で、対人戦なら割と心理戦ができそうなゲームなので、対人戦があったら面白いだろうなとずっと思っていました。

   「21」は相手とライフをかけて勝負するゲームで、先にライフがなくなったら負けとなります。山札からカードを引き、手札の合計がゴール値(通常は21)以下で大きいほうが勝ちで、一方がゴール値を超えバーストしていたらバーストしていない方の勝ち、両者バーストした場合、合計が小さいほうが勝ちとなり、負けた方は賭けていたライフ分ライフが減り、合計が同値の場合引き分けとなり、どちらのライフも減りません。山札は1~11の11枚しかなく、始めに2枚ずつ配られ、自分のターンのとき、山札からカードを引くか、引かないでチェックするか以外にスペシャルカード(SPカード)を使用するかの3択があります。スペシャルカードは何種類もあり、賭けるライフの数を増やしたり、ゴール値を21から15や25に変えるなどがあります。お互いの1枚目のカード以外は相手にも見えるようになっています。両者チェックしたら合計が比較され、勝敗が判定されます。

2.参考資料

   実装方法の根幹は下のサイトのほとんど丸パクリになるので、ここでは簡単に説明だけします。実装したい人はこのサイトを見て挑戦してみてください。筆者のコードも4章で記載していますが、違う部分がいくつかあります。

 

LINE Botで友だちと遊べるリバーシ開発(1) 手順書

LINE Botで友だちと遊べるリバーシ開発(2) 手順書

 

   詳しくは上の参考サイトにわかりやすく記載されているので簡単に流れを説明すると、GoogleのアカウントやLINE API、ngrokのアカウントがない人は作成し、LINE APIのChannel SecretとChannel Access Token、ngrokのAuthtokenを取得し、Google Colabのコードにコピペし、Google Colabのコードをいくつか実行し、WebhookのURLを取得し、LINE APIにそのURL(のhttpをhttpsに変更したもの)を所定の箇所にコピペし、残りのプログラムを実行すると実装できます。

   浅い知識で仕組みのイメージを書くと、ngrokによってGoogle ColabがあるURLでネットに公開され、LINE Botにメッセージを送るなどのイベントが発生したときにLINE APIがそのURL当てにメッセージを送りそのことを伝え、来たメッセージにGoogle Colab上で処理が行われ、結果を返すといった感じです。
(間違っていたらすみません。。。)

   他にも公式のドキュメントに基本的には全て書かれているので、調べて応用してみてください。筆者は特定の相手にメッセージを送るコードを公式ドキュメントを参考に導入しました。

Messaging APIリファレンス | LINE Developers

3.作成したゲーム

   作成したゲームを紹介します。正直PCでプレイしないと改行が多くて見づらすぎる(改善法模索中。。。)ので、その画面を見せたいと思います。プログラミングしたことがある多くの人が全角が混ざって止まるといったことを経験したことがあると思いますが、それが面倒なのでルールやヘルプは英語でつたない書いています。コード中にある(おそらくすべての)日本語は先に紹介したサイトの方が書いたものです。

   一応ルールは下図のようにruleと送ると出てきます。(つたない英語なうえにわかりにくい説明かもしれません。。。)

   また、指定されている有効なメッセージはhelpと送信することで下図のように表示されます。SPカードの説明はここにしか書かれていないです。

   指定されていないメッセージや場合によっては有効でないメッセージには"invalid message"と返し、自分のターンでないときに、helpやrule、showなどのいつでも有効な特定のメッセージ以外のメッセージには"Not Your Turn"と返すようになっています。

遊び方

1. 部屋を作る / 部屋に入る

   下図のようにrandom、make room、または部屋番号を入力することでゲームがスタートします。

   下図の左のようにrandomを送った場合randomを送った人から順に2人ずつがペアとなりゲームが始まります。そのため、奇数人がrandomと送った場合、最後の人は誰かがrandomと送るまで待つことになります。

   下図の真ん中のようにmake roomと送ると部屋番号が送られ、その番号を送信した最初の人とマッチングするようになっています。部屋番号はある範囲内でランダムな数字となっています。

   対戦相手が部屋を作った場合は、下図の右のように番号を送信することで部屋に入れ、対戦がスタートします。

2. 自分のターンにdraw、check、またはSPカードの番号を送信する

   下図のように自分のターンのときは、カードを引く場合はdraw、引かない場合checkを送ると、相手のターンになります。また、SPカードの番号を送信すると、そのSPカードを持っている場合はカードが消費され、そのカードの効果が発揮されます。相手にはカードを使用したことが通知されます。SPカードを使ってもターンは終了しません。

3. 両者checkのみを送ったターンが連続したら勝敗が判定される

   どちらもSPカードを使用しないで、checkのみをした場合、ゲームの勝敗が判定され、一方のライフがなくなった場合は、下図の右のようにマッチの勝敗が決定され、どちらもライフがある場合は下図の左のように次のゲームが始まります。

 

   byeと送ることでrandomと送ったときの待機状態から抜けられ、対戦中に送ると降参になります。また、30分間どちらからも何も送られなかった場合、マッチが消えるようになっています。

4.ソースコード

   下のリンクからコードを見ることができます。LINE APIのChannel SecretとChannel Access Token、ngrokのAuthtokenを取得し、Google Colabのコードの各種設定の各''内にコピペして使えます。「21」をプレイしたことがないとわかりづらい上に、あまり説明がうまくかけていないと思うので参考程度にして、お好みでアレンジしてみてください。

Google Colab
※新しいタブで開き、自分のドライブに保存してください。

   コードの解説はいろいろ実装し、複雑に絡んでいて難しいので、先に紹介した参考サイトと大きく異なる点を紹介します。

  • グループに追加しない
  • いくつかの操作後に相手にも特定のメッセージが届く

   ゲームの性質上、自分の手札を隠す必要があるため、紹介したサイトと異なり、グループラインに追加するわけではなく、Botとの個チャで対戦する形式にしています。そのため、メインプログラムの570行目(Google ColabならCtrl+m+lで操作中のセルの行数を表示できます)の変数idに送信者固有の番号を格納し、479行目らへんであらかじめ定義した関数を用いて、その送信者がすでにゲームに参加しているかしていないか識別し、参加している場合には参加しているゲームの情報を得るといったようなアプローチをしています。いくつものペアが同時にゲームすることも想定してこのようなプログラミングをしています。

   いくつかの操作では相手にもメッセージが送信されるようにしています。例えば、自分のターンが終了しシステム上相手のターンになった際に相手にメッセージが送信されないと、相手はいつターンが来るのかわからず、直接伝えるなどのめんどうが発生して困ったことになります。なので自分のターン終了時に自動的に相手にメッセージが届く必要があります。やり方としては、公式のドキュメントの「プッシュメッセージを送る」を参考に、先に書いた送信者固有の番号をあらかじめ格納しておき、

 line_bot_api.push_message(送信者固有の番号, TextSendMessage(text='送るメッセージ'))

ターン終了時に上のコードで相手にもメッセージが送信されるようにするといった手法です。紹介した筆者のコードではリストに固有の番号を保存しておき、プレイヤーにシステム上番号(0または1)を割り当てておき、"1-プレイヤー番号"で相手のプレイヤー番号になることを利用してコードを簡単にしています。

5.今後挑戦したいこと

   3章で紹介したようにとても見づらいゲームで現状わかりにくいです。この点を改善する方法として、Flex MessageやLINE Front-end Framework(LIFF)を用いるなどの手法があり、いろいろ勉強してわかりやすくしたいと思っています。さらにイベントなしでメッセージを送れるのかも気になっているのでここらへんも調べたいと思っています。これができればタイマーが実装でき、シンキングタイムを決められます。わかりやすいサイトややってみてわかったことなどがあればまたブログにまとめたいと思ってます。

   他にも機械学習系やVR系のことも勉強しているので、面白い発見などがあればブログにしたいと思います。特にVRに関してはUnityのCardboardを利用して簡単に作れることはわかったが、作りたいものがなかったため中断したので、なにか案があればぜひコメントしていただきたいです。

   この記事は筆者にとって最初の記事なので、色や図なども活用してうまく記事にする方法なども勉強して、筆者のようなほぼ初心者のプログラマーが軽くプログラミングして作れるものや役立つ知識などを共有出来たらなと思っています。

 

追記(2022-09-21)

   改善したものを下記のリンクから見れます。こちらもぜひ読んでみてください。 

 

sajyounokousatu.hatenablog.com