Category:伺か’

ゴーストともっと麻雀する

 - by Don

1月も半ば過ぎですが、あけましておめでとうございます。

今年もゴーストと麻雀する

素敵なフリーシェルを見つけて麻雀の相手をしてほしくなったので、ゴーストにしてみました。

ゴーストと麻雀をするの図

※ゴーストと麻雀する方法→ゴーストと麻雀を打てるようになった

麻雀をするだけのゴーストにするにはもったいない素敵なシェルですが、ご容赦くださいませ。

今年もまた素敵なゴーストでデスクトップが賑わうといいなーと思います。

ゴーストポップアップを動かしてみた

 - by Don

ゴーストポップアップSiReFaSoからデータを取得するよう改変してみました。

サンプル



  • Emily/Phase4.5

ダウンロード

オリジナルのゴーストポップアップとは若干使用法が異なります。詳しくは同梱のサンプルをご覧ください。

その他

今回のためにSiReFaSoの仕様をMarble Note JSON APIに合わせようと若干の修正を施しました。ただし、そもそもの仕様が全く異なるため部分的な互換性のみに留まっています。

Marble Noteほど高機能ではないですが、ゴースト配布サイトのプレビューに利用するなど、十分遊べるのではないかと思います。

そもそも\![embed,…]以外のことがあんまりわかってなかった

 - by Don

前回の記事で検証した仮説「呼び出されたイベントでScriptを返さなければ現在再生中のScriptは中断されない」、よくよく考えたら当たり前なことだと気がついた。

これ、ただのイベント割り込みだ。

ゴーストがランダムトーク中に0分になると、トークが中断して時報トークをする。これはトーク中に割り込まれたイベントOnMinuteChangeに対してScriptを返したため、現在再生中のScriptが中断して時報トークが再生されたからだ。

しかし、時報トークの無いゴーストでも等しくOnMinuteChangeイベントは通知されているのにトークは中断されない。OnMinuteChangeイベントに対して何もScriptを返していないため、現在再生中のトークを中断する必要が無いからだ。

\![raise,...]など自分でイベントをコールする系のScriptを使用した場合でも状況は一緒だ。自分でわざわざイベント割り込みを起こしたのだ。\![raise,...]を実行してその結果何かScriptが返されたなら、現在再生中のScriptは中断して当たり前だし、Scriptが返されなければ再生中のScript(トーク)は継続して当たり前だ。時報トークの割り込みと同じ。

\![embed,...]の使い方がわかった

 - by Don

今更ながら\![embed,…]の使い方を把握したので覚書です。

基本

単純な例

里々でやろうとするときは\![embed,…]の呼び出し先イベントは\eで閉じないよう留意しないといけない。

*
:あいうえお\![embed,OnHoge]さしすせそ

*OnHoge
:かきくけこ

#これを実行すると以下のようになって「あいうえおかきくけこ」と表示された時点で再生が終わる
#\0\s[0]\1\s[10]\0あいうえお\0\s[0]\1\s[10]\0かきくけこ\eさしすせそ\e

単語群なら前後に余計なスクリプトは付かない。

*
:あいうえお\![embed,OnHoge]さしすせそ

@OnHoge
かきくけこ

#これを実行すると以下のようになる
#\0\s[0]\1\s[10]\0あいうえおかきくけこさしすせそ\e

里々であれば以下のように書いても同じ結果が得られる。

*
:あいうえお(OnHoge)さしすせそ

@OnHoge
かきくけこ

#これを実行すると以下のようになる
#\0\s[0]\1\s[10]\0あいうえおかきくけこさしすせそ\e

これでは面白くないので、同じ結果が得られない例を挙げる。

SakuraScriptの再生と同期して呼び出しが実行される例

*
:時計の秒針を一秒おきに数えてみよう!
(現在秒)、\_w[1000](現在秒)、\_w[1000](現在秒)…。

これは期待した動作にならない。「13、14、15…。」みたいになってほしいが、「13、13、13…。」となってしまう。里々が全ての括弧を展開した結果のSakuraScriptをSSPに渡しているだけなので、SSPに届く頃にはすべて13になっている。

しかし、\![embed,…]を使えば期待した動作が可能となる。

*
:時計の秒針を一秒おきに数えてみよう!
\![embed,OnGetSecond]、\_w[1000]\![embed,OnGetSecond]、\_w[1000]\![embed,OnGetSecond]…。

@OnGetSecond
(現在秒)

この例だと「13、14、15…。」みたいに再生される。SakuraScriptの再生と同期してイベント呼び出しが実行され、返されたScriptをその場で埋め込みながら再生を続ける。すごい。

応用

複雑な例

\![embed,…]とはどんなものか、ということについては上述の例さえわかれば十分である。それ以上でもそれ以下でもない。\![embed,…]はそんなに難しいものではない。

\![embed,…]ワカラナイ、というのは往々にして\![embed,…]以外のところに原因がある。例えば、UKADOCの説明には以下のように書いてある。

プロパティシステムの内容によって分岐など、イベントを実行して情報を取得する仕様を、1回のスクリプト実行で有効に使用するための仕様。

何言ってるかワカラナイ。

プロパティシステムというのは、SSPが知っている情報を教えてもらうための仕様だ。例えば現在時を教えてもらうには以下のように書く。

*
\![get,property,OnGetHour,system.hour]

*OnGetHour
:現在(R0)時です。

里々なら里々自身の力で(現在時)と書けば取得できるけど、簡単な例として。

ここで重要なのが、情報を取得するためには別イベントをコールする必要があるということだ。(R0)に入っている情報を(またはそれを使用/加工した文字列を)\![get,property]を実行した直後に埋め込んで再生したい場合もあるのかもしれない。そういうことができますよ、と\![embed,…]の説明には書いてある。

例えば以下のように書いてもkero側のScriptは再生されない。

*
:\![get,property,OnGetHour,system.hour]
:もうそんな時間か。#←これは再生されない

*OnGetHour
:現在(R0)時です。

イベントを呼び出す系のSakuraScriptは、それが実行された時点でそのイベントにおける再生は強制終了されるのが特徴である。

…と思っていた。昨日までは。例外があったのだ。知らなかった。

\![get,property]した後もScriptの再生が続く例

答えを言ってしまうと、以下のように書けばUKADOCの説明にあるようなことが可能となる。

*
:現在\![get,property,OnGetHour,system.hour]\![embed,OnShowHour]時です。
:もうそんな時間か。#←これが再生される!

*OnGetHour
$現在の時間【タブ】(R0)

@OnShowHour
(現在の時間)

\![get,property]した後もScriptの再生が続く条件は、呼び出したイベントで「何も返さない」ことである。

上記の例では(R0)の情報を変数に保存してはいるものの、再生するScriptは何もない。この場合、例外的に呼び出し元のScriptは再生を続けるのだ。知らなかった。

変数に保存したは良いが、再びSSPに処理が戻ってScriptの再生中である。保存した情報を再びSHIORI側で処理し、Scriptを生成し、呼び出し元に埋め込みたい。そこで\![embed,…]の登場だ。

\![embed,…]は極めて単純な仕様であり難しいことはない。\![get,property]の仕様が謎すぎるんだ。「何も返さない」場合のみScriptの再生を続けるとか誰が知ってるんだ。

補足

イベントを呼び出す系のSakuraScriptの代表と言えば\![raise,...]だ。きっと\![get,property]と同様な仕様となっているに違いない。

*
:艦隊のアイドル、\![raise,OnNakachan1]那珂ちゃんだよー!\![raise,OnNakachan2]よっろしくー!

*OnNakachan1
#何も返さない

*OnNakachan2
カーン...カーン...カーン...

予想通りOnNakachan2でScript再生が中断され、カーンカーンとなる。

ちなみに\![raise,...]はMateriaでもサポートされており、Materiaで実行しても同じ結果となった。なので、SSPは本家の仕様を忠実に再現しているものといえる。

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

 - 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の場合は第一引数に指定することができ、両者の送信対象に関する仕様の差はなくなっています(私がぽなさんの背中を優しくツンツンしてそうして頂きました)。

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

SiReFaSoメンテ完了のお知らせ

 - by Don

予定していたSiReFaSoのメンテナンスが無事完了しました。2時間余りの間ご不便をお掛けしました。

今回再登録できなかったゴーストの一覧を以下のURLにまとめてあります。robots.txtによるアクセス拒否とMD5不一致が原因となっております。

今後

実はそう遠くない将来、もう1回メンテナンスの必要が出てくる予定です。現在利用している画像配信サーバが使えなくなるアナウンスがあったため、別の方法を検討します。現状の利便性を維持するのも厳しくなってきましたが、可能な限り続けていきたいと考えておりますので、今後ともよろしくお願い致します。

SiReFaSoメンテナンス予告(2013-08-17)

 - by Don

2013-08-17 (土) 15:00 にSiReFaSoのメンテナンスを行います。メンテナンス中は新規登録が一時的に利用できなくなりますのでご了承ください。また、登録されているゴーストのデータを全削除し、登録し直す作業を行います。作業終了までゴーストの更新確認ができなくなりますので併せてご了承ください。

詳細

今回のメンテナンスは内部的なシステムの更新に留まるため、現行からの仕様上の変更はありません。メンテナンス後はこれまでと同様にご利用できます。

その他

試験運用時の登録作業中に以下のゴーストで登録エラーが発生し登録できないことを確認しました。

桜花亭の冒険者

MD5不一致: ttp://cardghost.web.fc2.com/myghost/sakuratei/ghost/master/descript.txt

原因: たぶんSister’s Complexのdescript.txtに入れ替わってる

ロスト・ユー・サムウェア

MD5不一致: ttp://earlduant.web.fc2.com/LostYouSomewhere/ghost/master/descript.txt

原因: ASCIIモードでFTP転送したかFC2サーバの御乱心

プラナリアン

MD5不一致: ttp://greenfish.futene.net/ghost/pla/ghost/master/descript.txt

原因: ASCIIモードでFTP転送したかNinjaサーバの御乱心

銀夜のソプラノ

MD5不一致: ttp://mft.pv.land.to/Ghost/Soprano/install.txt

原因: ASCIIモードでFTP転送したかland.toサーバの御乱心

人体視願/ヴィイ

MD5不一致: ttp://project-h.sakura.ne.jp/ghost/net_n/ghost/master/descript.txt

原因: ASCIIモードでFTP転送したかsakuraサーバの御乱心

+Schnee+

MD5不一致: ttp://telisiru.masa-mune.jp/update/ghost/master/descript.txt

原因: ASCIIモードでFTP転送したかNinjaサーバの御乱心

喫茶ねこねこ

404: ttp://twincat.island.ac/myghost/Twincat_Tearoom/shell/master/descript.txt

原因: たぶん誤削除

その他、ここには載せませんがrobots.txtでアクセス拒否の意思表示が見られたいくつかのサーバ上のゴーストも登録除外となります(前バージョンのSiReFaSoのバグにより誤登録されていました)。

DAU-Crawler/3.0 Release

 - by Don

DAU/Crawler

本日、SiReFaSoのコアエンジンであるDAU-Crawler/3.0をリリースしました。

DAU-Crawler/2.0からの変更点としては以下の通りです。内部的な処理の変更がメインで、外見上や仕様上の違いはありません。

  • Python 2.5からPython 2.7へ移行
  • Kay FrameworkをPython 2.7のものに差し替え
  • データストアAPIをDBからNDBへ移行
  • backendの処理をBackendsからModulesへ移行
  • 画像処理ライブラリをpypngからPILへ差し替え
  • robots.txtの解釈に関するバグの修正

SiReFaSoへの適用

SiReFaSoはまだDAU-Crawler/3.0への差し替えはしていません。しばらく別サーバで試験運用をしてから差し替えようと思います。

差し替え時にはDAU-Crawler/2.0の時と同様、全てのデータを削除した上で再度登録し直す作業が必要となります。メンテナンスには相当の時間がかかるため、スケジュールが決まり次第Disc-2に告知する予定です。

更新の目的

特に仕様上の変更は無いのですが(バグフィックスはあるけど)、Googleさんに「いつまでもPython 2.5使ってんじゃねーよ*すぞ(意訳)」って言われたので、ついでに色々まとめて更新したのでした。

SoSiReMiは?

SoSiReMiも更新しないといけませんが、こちらはまだメドが立っていません。SiReFaSoが片付いたら手を付けようと思います。