UECda C言語版サーバーとJava言語版サーバーの違いへの対処 - YuriCat/FujiGokoroUECda GitHub Wiki

0. 前書き

UECdaにおいてはこれまでC言語版サーバーとJava言語版サーバーの仕様の違い
プログラマの労力を吸い取って行く過去がありました。

本ページではデバッグの悲劇を繰り返さぬよう、2つのサーバーのどこが違うのか
どう対処すべきかについて大渡(YuriCat)なりの知見をまとめます。

なお本ページではC言語版サーバーの動作を標準とし、
(本稿執筆時点では重大なバグはあるが...)

基本的にはJavaサーバーにどう対処するかという文脈で記載します。

※あくまでJavaサーバーの話であり、Java標準ライブラリを使った思考エンジンの話はしません
そちらも注意するべき点はありましたが、もう忘れました。

なお以下に記した仕様の詳細には間違いが含まれるかもしれませんが、
対処方法は実際にFujiGokoroが実装している内容になります。

1. シングルジョーカーの提出方法が絞られる

8x15テーブルでシングルジョーカーを提出する際、
Cサーバーではどこかに2を立てればOKですがJavaサーバーでは
通常時 [0][14] ~ [3][14] 革命時 [0][0] ~ [3][0]のどこかに2を立てる   としなければリジェクトされます。

※ぱおーん氏の2012, 2013年優勝プログラムはこれにはまっていて、シングルジョーカーを残して負けることがあります。

2. シングルジョーカーがスート縛りの対象になる

8x15テーブルで役を提出する際、Cサーバーではシングルジョーカーのスートは考慮されませんが、
Javaサーバーはシングルジョーカーに対してもスート縛りを適用しようとする
(つまり、通信テーブル上の入っている位置のスートだと認識する)ため、
シングルジョーカーに対するスペ3返しが提出できなくなるという挙動を示します。
そのため、シングルジョーカーを提出する際には場に出ている役とは違うスートで提出することで
他プレーヤーのリジェクトを防げます。

3. 献上される札の優先順位が違う

カード交換のうち、貧民と大貧民が強いカードをあげる操作を以下献上と呼びます。
UECdaでは献上カードは、同じ強さの札があってもプレーヤーが選ぶことはできず、サーバーが自動的に決定します。

このときの優先順は、

Cサーバー 優先度 スペード ハート ダイヤ クラブ

Javaサーバー (Cと違うのですが、後で調べます...)

となっており違うルールとなっています。 この点に気をつけないと、相手手札を推定する際に、相手が持ちうるカードが無くなってしまうなどの問題が生じます。 (※FujiGokoroは2016年頃から、正直対応をさぼっています。そのためjavaサーバーではたまに落ちます)

なお、FujiGokoroの実装おける各カードの番号の並び順はCサーバーの交換の優先度が低い順にしています。

4. 献上の枚数が含まれた状態で手札枚数が通知される

UECdaでは献上は手札配布前に行われ、大富豪と富豪はどのカードをもらったのか知ることはできません。 

(貧民、大貧民は献上された札が残った状態で通知されるので知ることができます)

このとき、Cサーバーで受け取る各プレーヤーの手札枚数は貧民、大貧民からの献上によって増えた分を含まないのですが、
Javaサーバーは含むので注意が必要です。

UECdaでは手札は大富豪から席順に配られるので、

大富豪の手札が11枚であればCサーバー、13枚であればJavaサーバーとわかります

FujiGokoroではこの点によってCサーバーとJavaサーバーを見分けています。

自分の持つ盤面表現ではどちらかの表現に揃えておけば問題ないでしょう。

5. 試合進行ルールの違い

(記憶が定かではないのですが)根本的なルールの違いとして、8切りの発動タイミングか、
ジョーカーでのスート縛りがかかるかなどの違いがあった気がするのですが、検証してわかったら書きます。

ルールが違うので、クライアント内部で棋譜を記録していても、
一応サーバーから随時送られてくる現局面の情報も見ておかないと、
試合の流れが自分の想定と違っていたということが起こりえます。

以下、思い出したら追記します