電脳麻将 ver.0.3 で牌譜再生機能を追加した*1。牌譜再生を実現するにあたり、他のシステム(天鳳とか)の牌譜形式も参照したのだが、どうもしっくりこないので独自のJSON形式である。牌譜形式を定義した目的は2つあって、1つはもちろん牌譜再生だが、より重要な目的としてゲーム進行に使いたいというのがあった。
今回はとりあえず牌譜形式を説明する。ゲーム進行についてはまた別途。
牌譜全体
{ title: /* 牌譜のタイトル */ , player: /* 対局者情報 */ , qijia: /* 起家 */ , log: /* 半荘全体の記録 */ , defen: /* 半荘終了時の得点 */ , rank: /* 順位 */ , point: /* 獲得ポイント */ }
半荘全体の記録
[ [ /* 東一局の記録... */ ], [ /* 東二局の記録... */ ], ... [ /* 最終局の記録... */ ] ]
各局ごとの記録を配列として並べている。
摸打情報
配牌、自摸、打牌、副露、和了など。各情報の形式は以下の通り。
配牌 (qipai)
{ qipai: { zhuangfeng: /* 場風 */ , jushu: /* 局数 */ , changbang: /* 積み棒の数 */ , lizhibang: /* 立直棒の数 */ , defen: /* 対局者の得点 */ , baopai: /* ドラ表示牌 */ , shoupai: /* 手牌 */ } }
zhuangfeng
- 場風。(0: 東、1: 南、2: 西、3: 北)
jushu
- 局数。(0: 一局、1: 二局、2: 三局、3: 四局)
changbang
- 積み棒の数。
lizhibang
- その局開始時の立直棒の数。
defen
- その局開始時の対局者の持ち点の配列。その局の東家からの順。
baopai
- ドラ表示牌。
shoupai
- 配牌の配列。その局の東家からの順。
shoupai
は 麻雀の手牌の文字列表現 - koba::blog の手牌の形式にしたがう。ドラは「表示牌」であることに注意。現物としてしまうとドラが六萬の場合に表示牌が赤牌であったかが示せなくなってしまうというのがその理由。東一局の配牌は
{ qipai: { zhuangfeng: 0, jushu: 0, changbang: 0, lizhibang: 0, defen: [ 25000, 25000, 25000, 25000 ], baopai: 's7', shoupai: [ 'm178p36s15578z356', 'm177p225s069z1247', 'm299p1158s288z356', 'm44p1234089s3z222' ] } }
のような形式となる。
自摸 (zimo)
{ zimo: { l: /* 手番 */ , p: /* 牌 */ } }
l
- 手番。(0: 東家、1: 南家、2: 西家、3: 北家)
p
- 自摸牌。
{zimo:{l:0, p:'s1'}}
となる。
打牌 (dapai)
{ dapai: { l: /* 手番 */ , p: /* 牌 */ } }
l
- 手番。(0: 東家、1: 南家、2: 西家、3: 北家)
p
- 打牌。
'_'
、立直の場合は '*'
を付加する。東家が一索を自摸切り立直したときは {dapai:{l:0, p:'s1_*'}}
となる。
副露 (fulou)
{ fulou: { l: /* 手番 */ , m: /* 面子 */ } }
l
- 手番。(0: 東家、1: 南家、2: 西家、3: 北家)
m
- 副露した面子。
{fulou:{l:1, m:'s1-23'}}
となる。
槓 (gang)
{ gang: { l: /* 手番 */ , m: /* 面子 */ } }
l
- 手番。(0: 東家、1: 南家、2: 西家、3: 北家)
m
- 槓した面子。
{gang:{l:2, m:'p555=0'}}
のようになる。
槓自摸 (gangzimo)
{ gangzimo: { l: /* 手番 */ , p: /* 牌 */ } }
l
- 手番。(0: 東家、1: 南家、2: 西家、3: 北家)
p
- 自摸牌。
開槓 (kaigang)
{ kaigang: { baopai: /* 牌 */ } }
baopai
- 槓によって生じた新ドラ表示牌。
- 暗槓
- gang → gamgzimo → kaigang → dapai
- 大明槓
- fulou → gangzimo → dapai → kaigang
- 加槓
- gang → gangzimo → dapai → kaigang
という順序になる。
和了 (hule)
{ hule: { l: /* 手番 */ , shoupai: /* 手牌 */ , baojia: /* 放銃者 */ , fubaopai: /* 裏ドラ表示牌 */ , fu: /* 符 */ , fanshu: /* 翻数 */ , damanguan: /* 役満複合数 */ , defen: /* 和了打点 */ , hupai: [ { name: /* 役名 */ , fanshu: /* 翻数 */ }, ... { name: /* 役名 */ , fanshu: /* 翻数 */ }, ], fenpei: /* 局収支 */ } }
l
- 和了者。(0: 東家、1: 南家、2: 西家、3: 北家)
shoupai
- 和了者の手牌の文字列表現。ロン和了の場合、和了牌をツモした状態とする。
baojia
- 放銃者。ツモ和了の場合は
null
。 fubaopai
- 裏ドラ表示牌の配列。立直がない場合は
null
。 fu
- 符。役満の場合このメンバは存在しない。
fanshu
- 翻数。役満の場合このメンバは存在しない。
damanguan
- 役満複合数(ダブル役満の場合は2)。役満でない場合このメンバは存在しない。
defen
- 供託をのぞいた和了点。
hupai
- 和了役名と翻数のリスト。役満の場合翻数は
'*'
とする。 fenpei
- 供託を含めた局収支。その局の東家からの順。
ドラ表示牌:


















{ hule: { l: 3, shoupai: 'm78p405667s34577m9', baojia: null, fubaopai: ['s2','m4'], fu: 20, fanshu: 5, defen: 8000, hupai: [ { name: '立直', fanshu: 1 }, { name: '門前清自摸和', fanshu: 1 }, { name: '平和', fanshu: 1 }, { name: '赤ドラ', fanshu: 1 }, { name: '裏ドラ', fanshu: 1 }, ], fenpei: [ -4200, -2200, -2200, 9600 ] } }
となる。
ダブロンの場合は和了のレコードが続くことになる。
流局 (pingju)
{ pingju: { name: /* 流局理由 */ , shoupai: /* 手牌 */ , fenpei: /* 局収支 */ } }
name
- 流局理由。電脳麻将では次のいずれか。荒牌平局、流し満貫、九種九牌、四風連打、四家立直、三家和、四開槓。
shoupai
- 流局時の各々の手牌。ノー聴などの理由で手牌を開示しない場合は
''
とする。 fenpei
- ノー聴罰符などの局収支。その局の東家からの順。
{ pingju: { name: "荒牌平局", shoupai: [ 'm678p66s12,s6-78,s555=', 'm1177p456s340,z444=', '', 'm44p12340,z2222=,p999=' ], fenpei: [ 1000, 1000, -3000, 1000 ] } }
となる。