IJCAI 2020 Mahjong AI Competition (0)

表題の麻将AIコンテストが開催されることを知った。

Committee には李文龙もいて、開催案内時に教えてくれよと思った。妻は「賞金を獲得する前提で」応援するとのことなのでビクビクしながら参加してみたいと思う。できればチームを組みたいが、足を引っ張ったら嫌なので、私から特定の方へのお誘いはしないことにする (賞金のことを考えると複数のチームが結託はしないまでも情報共有しつつ進めるというのもアリなのではないか)。アルゴリズムについて秘匿するべきところがあれば別として、公開されているレギュレーション・ソースコードなどの理解はオープンにしていきたい。

IJCAI2020麻将比赛复式赛制介绍

GitHub で中国語版が公開されている。対局はスイス式デュプリケートで1ゲーム24局 (?後述) からなる。1荘16局でないのは4対局者の座順すべてを1局ずつプレイするためである。この場合、門風・圏風には偏りが生じる気がする。デュプリケートのため4卓を同時に進行し、同じ卓ではなく、異なる卓の同じ座位についたプレイヤー間で総得失点を比較し、固定順位点 [4, 3, 2, 1] を得る。これを足しあわせて大会の順位が決まる。

細部の規定にも一般的なゲームと異なる点がある。まず花牌は使用しない。1匹配 (match) 4圏、1圏24局 (?前述) からなる。デュプリケート方式のため各プレイヤーに34枚の牌山が割り当てられ、配牌および摸牌はそこから順に行う。打牌を行ったプレイヤーの下家の山が残っていないとき、流局する (自分の山が残っていないとき、カンを行えるか否か、行える場合の流局タイミングは不明)。

Judge

C++ のコードが公開されているが読めなくて困っている。モジュールレベル (グローバル?) 変数が多くて primitive obsession な気もする。以下の行数は手で数えたが良いツールがありそうなので教えてほしい。

struct PlayerData; // 17行

Json::Value inputValue, outputValue;
PlayerData playerData[4];
string lastTile;
string lastOp;
string tileCHI;
bool lastBUGANG = false;
bool currBUGANG = false;
bool lastGANG = false;
bool currGANG = false;
bool lastANGANG = false;
bool currANGANG = false;

int roundStage = -2, lastRoundStage;
int quan;
vector<string> tileWall;
unordered_map<string, mahjong::tile_t> str2tile;
unordered_map<string, int> shownTile;
//记录已经明示的牌,用于和绝张

void playerError(int player, const string code); // 16行

//若finish=true,表示bot选择和牌,进入finish阶段
int checkHu(int player, bool finish); // 85行

//检查玩家输出是否为PASS
void checkInputPASS(const Json::Value &playerOutput, int player); // 8行

//检查玩家摸牌后的输出
void checkInputDRAW(const Json::Value &playerOutput, int player); // 68行

//检查其他玩家打出牌后,玩家的输出
//1检查和牌操作
void checkInputPLAY1(const Json::Value &playerOutput, int player); // 9行

//2检查碰牌、杠牌
bool checkInputPLAY2(const Json::Value &playerOutput, int player); // 61行

//3检查吃牌
bool checkInputPLAY3(const Json::Value &playerOutput, int player); // 45行

//检查玩家杠牌后的回应
//用于抢杠和
void checkInputGANG(const Json::Value &playerOutput, int player); // 12行

void roundOutput(Json::Value &outputValue); // 106行
void roundInput(Json::Value &inputValue); // 50行
int main(); // 130行

Sample

同じく C++ のコードが公開されているが読めなくて困っている。というのはさすがに嘘。大半が入出力とシミュレーション (どうやら1巡ごとにプログラムが起動されるらしい) に費やされているのがわかる。自分は摸打のみを行っていることを前提にしており、鳴きも他家のアクションも処理は一切されていない。毎巡、手牌を random_shuffle して先頭から切っている。

データセット

人間のプレイヤーによる対局のデータが百度クラウドストレージで提供されている。パスワード ('rm79') を入力するとファイル一覧を見ることができ、408.7MB の mjdata.zip と 163.6MB の mjdata.sfs が mjdata ディレクトリ内に格納されている。前者は JSON などが格納されていると思われるが後者は初めて見る拡張子だ。

大会プラットフォームである Botzone に登録すると、プラットフォーム上で行われた対局 (おそらく大半は bot で、人間も参加すること自体は可能?) のデータをダウンロードできる。

ここから先は

0字

¥ 1,024

この記事が気に入ったらサポートをしてみませんか?