Month: November 2013

ゴーストと麻雀を打てるようになった

 - by Don

1年前、「ゴーストと麻雀を打ちたかった」で書いたことができるようになりました。

ゴーストと麻雀する

麻雀ソフトの準備

「テナリ君」という麻雀ゲーム・ソフトがありますのでそれを入手します。

以下のアーカイブに入っているtenari.exeをオリジナルのEXEファイルに上書きします。

対戦相手の準備

とりあえず3体のゴーストを作ってみました。

先にゴーストを3体起動しておき、その後tenari.exeを実行すればイベント通知されます。

仕様

送信プロトコルは一部UMP(Universal Mahjong Protocol)を参考にしています。が、そもそも双方向じゃないし実装が難しい部分や通知情報が不十分な部分もあるので大分オレオレ仕様になっています。

概要

ID: OnMahjong
Reference0: バージョン(UKAJONG/0.1)
Reference1: サーバコマンド(gamestart|gameend|...)
Reference2以降: サーバコマンド追加情報

基本的にはこんなイベントが延々と通知されるだけです。Reference1には以下の様なコマンドがあります。

gamestart ゲーム(半荘)開始
Reference2: 席(東|南|西|北)
Reference3: プレイヤー名1
Reference4: プレイヤー名2
Reference5: プレイヤー名3
Reference6: プレイヤー名4
gameend ゲーム終了
Reference2: プレイヤー名1(バイト値,1)点数
Reference3: プレイヤー名2(バイト値,1)点数
Reference4: プレイヤー名3(バイト値,1)点数
Reference5: プレイヤー名4(バイト値,1)点数
kyokustart 一局が始まるときに送る
Reference2: 場風(東|南|西|北)
Reference3: 親(ex.プレイヤー名1)
Reference4: 本場(ex.1)
Reference5: 供託(ex.1000)
kyokuend 一局終了
point プレイヤーの点数を通知する
Reference2: プレイヤー名
Reference3: (=|+|-) =は点数の直指定、+-は増減を意味する
Reference4: 点数
haipai 配牌を配る
Reference2: プレイヤー名
Reference3: 配牌(ex.1m2m3m4p5p6p7s8s9s1z5z6z7z)
dora ドラ表示牌を送る
Reference2: 牌(ex.7z)
tsumo 自摸
Reference2: プレイヤー名(自分)
Reference3: 残り枚数
Reference4: 牌(ex.7z)
sutehai 捨牌
Reference2: プレイヤー名
Reference3: 牌(ex.7z)
say 発声
Reference2: プレイヤー名
Reference3: (chi|pon|kan|ron|tsumo|richi|tenpai|noten)
agari あがり
Reference2: プレイヤー名
Reference3: Reserved(符)(未実装)
Reference4: Reserved(役,ハン数)(未実装)
ryukyoku 流局

課題

現状のSSTPの仕様ではイベント通知に難があります。元々スクリプトの再生が目的だったものに取って付けたようなイベント通知機能が付加されたものがNOTIFY/1.1であり、しかもmateriaは複数ゴースト起動について想定していないため特定のゴーストを指定してイベントを通知することについてSSTPのプロトコルレイヤではカバーされていません(DirectSSTPを使えば送信相手を指定できますがWindows限定になってしまいます)。

2013-12-15 更新。不要なScript通知により台詞が潰れる問題を修正しました。SSP/2.3.13以降が必要となります。

あとはソフト側の問題ですが、実効速度が遅いですね。すぐに固まります。Ruby製であることと元々の麻雀AIのロジックにもよるので仕方ないですが。しかし今回定めた通知プロトコルは「仕様」であって、送信側は何であっても構いません。もっと実行速度が早いソフトでSSTP送信機能を追加したり、たくさんの種類の実装が生まれればより楽しいと思います。私はもう疲れたのでこれ以上はやらないかもしれません。

半ばあきらめていたことがある程度実現できたので大分満足しています。

複数のゴーストとコミュニケートする

 - by Don

うかべん 横浜#8の発表資料とヒノハルさんのテキスト実況を拝読しているところです。今回もためになる発表が多数行われたようで、こうした資料が公開されることはとてもありがたいことであると感じます。関係者の皆様、大変お疲れ様でした。

コミュニケートとraiseother

もっしょくしさんの発表資料「ゴースト間の交流について ~暦にしき宣伝添え~」は、ゴースト間での情報送受信を含む「絡み」について、利用できそうな現状の仕様をまとめた素敵な資料になっています。複数ゴーストの連携に関して興味のあるゴーストマスタさんは是非ご一読を。

その中で触れられていたコミュニケートとraiseotherの相違点の項目で、以下のように触れられていました。

コミュニケート
送信対象は一度に一人まで
raiseother
その場にいる全員に同時に発信できる(__SYSTEM_ALL_GHOST__)

実は現在(2013-11-03)、最新のSSP(2.3.12)では送信対象に関してコミュニケートもraiseotherと同等の仕様となっています。

via Satori/里々の小技 – PukiWiki

複数のゴーストに同時に話しかける

*AとBとCに話しかける
$Value0【タブ】A(sprintf,%c,1)B(sprintf,%c,1)C
:4人でマージャンしよー!

同時起動中のゴースト全員に話しかける

*全員に話しかける
$Value0【タブ】__SYSTEM_ALL_GHOST__
:みんなでじゃんけんしよー!

「複数の送信相手」を指定する場合はバイト値1区切り、「その場にいる全員」に送信する場合は「__SYSTEM_ALL_GHOST__」を使います。これはコミュニケートの場合はValue0ヘッダに、raiseotherの場合は第一引数に指定することができ、両者の送信対象に関する仕様の差はなくなっています(私がぽなさんの背中を優しくツンツンしてそうして頂きました)。

もしかしたら発表会場でぽなさんが指摘されたかもしれないですが念のため、現状の仕様はこのようになっていますので複数相手のコミュニケートも利用可能です。