天鳳の牌譜は http://tenhou.net/0/log/ から取得することができる。第五期 天鳳名人戦 最終節 最終戦 であれば以下のURLになる。
形式はXMLっぽいが、要素名自体がデータになっていたり入れ子構造がなかったりでXMLの特性を生かしているとは言いがたい。何よりぱっと見て対局内容を想像することができない。天鳳の牌譜で麻雀研究をしようとする場合、この複雑怪奇な牌譜形式が大きな障害になっていると思う*1。そこで天鳳の牌譜を電脳麻将の牌譜形式に変換するプログラムをPerlで作ってみた。
XMLをパーズする
標準入力から天鳳の牌譜全体を読み込んでパターンマッチングでパーズする。
for (join('', <>) =~ /<.*?>/g) { my ($elem, $attr) = /^<(\/?\w+)(.*?)\/?>$/; my %attr = $attr ? ($attr =~ /\s+(\w+)="(.*?)"/g) : (); # 以下は要素ごとの処理。 }
上記のコードで $elem
に要素名が、%attr
に key-value の形式で属性名と属性値が格納される*2。後は要素ごとに処理を行えばよい。
ドキュメントがある訳ではないのですべて推測だけど、各要素とその属性の意味は以下と思う。
SHUFFLE
乱数に関する情報。ここから牌山を一意に決定できるらしい。めくられなかった牌山を含めて対局を再現したい場合はこの情報を利用する必要があると思うが、私は興味がないので使用しない*3。
- seed
- 乱数の種。
- ref
- 空文字列。意味は不明。
GO
ルール(赤あり、喰いありなど)、卓(一般、上級、特上、鳳凰)などの情報。
- type
- 以下の8ビットのビットフィールドを10進化した値。
0x01 | 人間との対戦のとき 1 |
---|---|
0x02 | 赤牌なしのとき 1 |
0x04 | ナシナシのとき 1 |
0x08 | 東風戦のとき 0、東南戦のとき 1 |
0x10 | 三麻のとき 1 |
0x20 | 卓レベル(後述) |
0x40 | 速卓(持ち時間が短い)のとき 1 |
0x80 | 卓レベル(後述) |
卓レベルはおそらく歴史的経緯でビットが分かれ、かつ反転してしまっているが、0x00: 一般、0x80: 上級、0x20: 特上、0xA0: 鳳凰 の意味。「四特南喰赤」の場合、type="41" となる。
- lobby
- 大会ロビーのID。
UN
天鳳名、段位、レートなど対局者の情報。
TAIKYOKU
この要素以下が実際の対局ログとなる。
- oya
- 起家。どうやら常に 0 のもよう。席順がランダムなのでこれはこれであり。
INIT
局の開始情報。
- seed
- カンマ区切りで以下の情報が入っている。局順、本場、供託、開門のサイコロの値1、2、ドラ表示牌。局順は 0が東一局で1が東二局と進んでいく。西一局は8。サイコロの値はなぜか実際の値から1減算されているのでとり得る値は 0〜5。ドラ表示牌はすべての牌に一意に振られた数字(仮に牌番号と呼ぶ)で表されている*5。南三局1本場、供託リーチ棒2本、開門のサイコロの目は 2, 4、ドラ表示牌がの場合、seed="6,1,2,1,3,16" となる。
- ten
- 局開始時の持ち点 / 100。カンマ区切りで4人分まとめて設定されている。
- oya
- 親番の対局者の番号。起家が常に0なので、東一局は0となる。
- hai0 〜 hai3
- 配牌。13枚分の情報がカンマ区切りでドラ表示牌と同じ牌番号形式で設定されている。理牌はされていない。
(D|E|F|G)(0〜135)
打牌情報。D: 0番の対局者の打牌 〜 G: 3番の対局者の打牌。0 〜 135: 打った牌の牌番号。
N
副露情報。
- who
- 副露した対局者の番号。
- m
- 面子を表す数(仮に面子コードと呼ぶ)。解釈方法はとても複雑なので別途説明する。
DORA
開槓情報。
- hai
- 新ドラ表示牌の牌番号。
REACH
リーチ情報。リーチ宣言打牌の直前と直後に出現する。リーチ宣言牌で放銃しリーチ不成立の場合は、直後のタグは出現しない。
- who
- リーチした対局者の番号。
- step
- 1: リーチ宣言、2: リーチ成立。
- ten
- リーチ成立後の各対局者の持ち点 / 100。カンマ区切りで4人分まとめて設定されている。
AGARI
和了情報。ダブロンの場合は2回出現する。
- ba
- 積み棒と供託リーチ棒の数。
- hai
- 副露牌を除く手牌(兵牌)。和了牌も含む。カンマ区切り、牌番号形式。
- m
- 副露牌(暗槓含む)。カンマ区切り、面子コード形式。
- machi
- 和了牌。牌番号形式。
- ten
- 符、和了打点、満貫情報をカンマ区切りで連結して設定。ここでの和了打点はなぜか100で割られていない。満貫情報は以下。0: 満貫未満、1: 満貫、2: 跳満、3: 倍満、4: 三倍満、5: 役満。
- yaku
- 役満以外場合の和了役情報。役番号、翻数をすべてカンマ区切りで連結して設定されている。役番号は 0: 門前清自摸和 〜 54: 赤ドラ。具体的な値は別途説明する。
- yakuman
- 役満の場合の和了役情報。翻数は不要なので役番号のみがカンマ区切りで連結して設定されている。
- doraHai
- ドラ表示牌の牌番号をカンマで連結して設定。
- doraHaiUra
- 裏ドラ表示牌の牌番号をカンマで連結して設定。リーチしていない場合はこの属性はない。
- who
- 和了者の番号。
- fromWho
- 放銃者の番号。ツモ和了の場合は和了者の番号が設定される。
- sc
- 和了による点数移動の情報。対局者0の持ち点 / 100、収支 / 100 〜 対局者3の持ち点 / 100、収支 / 100 の8項目をカンマ区切りで連結して設定。
- owari
- オーラスの和了にだけある属性。終局時の持ち点、ウマを含めたポイント数をカンマ区切りで4人分連結して設定。