コンピュータ大富豪の対戦は、ゲーム進行をつかさどるマスタープログラムと、プレイヤーとなるプログラムが相互に通信することで進行します。
マスタープログラムはWebアプリケーションであり、別のWebサイトにホスティングされています。
大会参加者は、プレイヤープログラムを作成し、サーバに接続してください。ゲームが始まると、逐一ゲームの進行情況が送られてくるので、自分の手番がまわってきたら応答を返すだけです。
プレイヤープログラムの動作プラットフォームや言語等は何でも構いません。
ただし通信にはWebSocketを利用しますので、WebSocketライブラリが存在するプラットフォームの方が作りやすいです。
接続URL:
ws://neof5master.azurewebsites.net:80/play/{A|B}/{RoomID}?name={ProgramName}WebSocketにて上記URLに接続してください。
{A|B}
のところは、クラスAのプログラムなら "A" を、クラスBのプログラムなら "B" としてください。{RoomID}
には、対戦が行われる部屋のIDを渡してください。大会当日は、運営本部よりIDの連絡があります。{ProgramName}
のところは、プログラムの名前をURLエンコードして渡してください。
WebSocket で接続した後は、ゲームが始まるまで通信はありません。ゲームが始まると、サーバから逐一データが送られてきます。
データは JSON 形式で送受信します。1回の送受信データ(1回のOnMessage着信)で1つのメッセージが完結しています。1つのメッセージが複数回に分けて送信されることはありません。
WebSocket の OnMessage() では受信データの形式によりバイナリタイプとテキストタイプの2種類が定義されていますが、本プロトコルではテキストタイプの方だけを使用します。
サーバメッセージの内容は、以下のようなメンバを持っています。
ゲーム内で何か進展があると、その種類に応じてデータが送られてきますが、すべてに応答する必要はありません。
応答が必要なのは自分の手番が回ってきたときだけです。
それ以外は無視しても構いません。
本プロトコルでは1枚のカードを2文字で表します。1文字目はカードのスート(マークのこと)を表します。
クラブ: C ハート: H ダイヤ: D スペード: S
2文字目は、カードの数字を表します。
1: A (エース) 2: 2 3: 3 . . . 10: 0 11: J (ジャック) 12: Q (クイーン) 13: K (キング)
ジョーカーは特別に"JK"と表します。
ジョーカー: JK
プレイヤーの手札などいった複数枚のカードの組み合わせについては、1枚2文字ずつの表記をスペースで区切って表します。 たとえば、4枚のカードの組み合わせ「スペードの5」「ハートの1」「ダイヤの12」「ジョーカー」を表す場合は以下のようになります。
"S5 HA DQ JK"
サーバから送られてくるメッセージについて説明します。
本プロトコルは、なるべくステートレスに処理できるよう設計されています。
すなわち、ゲームの最新状況を把握するために、クライアントは逐一メッセージを受け取って自己の内部状態を更新する必要はありません。
(もちろん、それをしても構いません)
最後のメッセージ一つだけを解釈すれば、ゲームの最新局面とこれまでの情況がわかるようになっています。
ここからはサーバメッセージの完全なサンプルを見ながら、その内容について順に解説していきます。
サーバから割り当てられたプレイヤー番号を表します。接続順に0から振られ、接続中は変更されることはありません。
発生したイベントの種類を表します。以下の種類があります。
Kindの値 | 意味、イベントの内容 |
---|---|
Start | ゲーム開始 |
CardDistributed | 手札のカード(の一部)が配布された |
CardSwapped | 手札のカードが交換された(大富豪⇔大貧民、または富豪⇔貧民)なお、手札の交換は自動的に行われます。 |
Thinking | Teban で表すプレイヤーに手番がまわった |
ProcessTurn | あなたの手番が回ってきた (このイベントメッセージは応答が必須です) |
CardsArePut | Teban で表すプレイヤーがカードを出した(またはパスした) |
Kakumei | 革命または革命返しがおこった |
Nagare | 流れた |
Agari | Teban で表すプレイヤーが上がった |
Finish | ゲーム終了 |
Tweet | あるプレイヤーが何かをつぶやいたとき(本来のゲーム進行とは関係のない、演出のためのオプション機能) |
Exception | 例外が発生した場合 |
上記のうち、"Tweet"と"Exception"のときは、Message
メンバが含まれます。それ以外のときは、メッセージサンプルの通りのメンバが必ず含まれます。
現在の手番となっているプレイヤー番号を表します。
革命中かどうかを表す bool値です。
対戦中のプレイヤーに関する情報が配列でセットされています。 一つの要素は(プレイヤー情報)は以下のようなメンバを持つオブジェクトです。
Name | プレイヤー名が格納されています |
HavingCardCount | 持っているカードの枚数です。0になるとあがりです |
Ranking | ゲーム開始時の階級です(2:大富豪、1:富豪、0:平民、-1:貧民、-2:大貧民) |
OrderOfFinish | 上がった順番です(まだ上がっていない場合は 0) |
配列の並び順はプレイヤー番号の順であり、途中で変更されることはありません。
プレイヤーの現在の手札を表します。当然ながら他のプレイヤーの手札を見ることはできません。
現在場に出ているカードを配列で表します。配列の末尾が最後に出されたカードであり、Kind:"ProcessTurn"
の際の応答時には、
このカードより強いカードを手札の中から選択することになります
山にあるカードを表します。
初手から現在局面までのすべての手の履歴です。一つの手を例えば "2-[S3]"
のように表し、2番のプレイヤーがスペードの3を出した、という意味になります。
パスをした場合は、"2-PASS"
となります。流れた時は "/"
で表されます。プレイヤーが上がった時は、 "2-AGARI"
と表します。
これらを初手から順に配列として格納しています。
プレイヤープログラムから送ることが出来るメッセージは次の2種類です
サーバからのイベントメッセージ「ProcessTurn」に対する応答として送信する必要があります。 手札の中からどのカードを出すかを思考し、そのカードをデータとして送信します。 カードのデータは、前述のカード文字列として表現する必要があります。
なお、応答受付にはタイムリミットがあります。サーバが「ProcessTurn」イベントメッセージを送信してから 10秒以内に応答が受信できない場合、 タイムオーバーとなり強制的にパスとなります。
また、自分の手番でないときにこのメッセージを送信するとエラーメッセージが返され、受付されません。
メッセージフォーマットサンプル:このメッセージは任意のタイミングで送信することができます。 思考の過程で発見したことや、相手の手に対する反応など、プログラムにセリフしゃべらせることが出来ます。 対戦中の演出として観戦者を楽しませるようなセリフを組み込んでください!
メッセージフォーマットサンプル: