このページの目的は? †
RO でしばしば実施されている「Wizardry オマージュ」なイベント向けの、「宝箱の罠」対策ネタページです。
これに関しては、いわゆるWebサービスも存在しているのですが、
そちらでキータイプするのがめんどくさいので、Windowsアプリを作ってみました。
→ このアプリは、別開発の ChatAnalyzer に統合されました。
ROCALFO単体での今後バージョンアップの予定はありません。
以下、古い情報。
ROCALFO †
このイベントでは、宝箱を調べると「お」「け」というような形で「罠の名前の1文字〜数文字」がわかり、そこから罠の正確な名前を推測していくメカニズムが提供されています。
ROCALFO は、その推測を自動で実施してくれる Windows プログラムです。
Windows プログラムであるメリットを生かし、ROクライアントの /savechat 機能で出力されたテキストから自動判定するようにしているのが大きな特徴です。

ダウンロード †
動作設定のために †
準備1:ROクライアントの設定 †
ROクライアント上に、RO_CALFOとの連携用のチャットウィンドウを
作成する必要があります。
ROクライアントのチャット領域の右上のほうに小さな+アイコンが
あります。これを押すと、新しいメッセージウィンドウが生成されます

新しい窓には好きに名前をつけてかまいません(初期状態では Chat_NewTabxxx.txt のような感じのはず)
補足
正確には、この「専用ウィンドウ」を作る必要はなく、既存ウィンドウでも構いません。
ただし、友瀬の提供しているホムAI「Glenelg」を使用している場合は、人間がチャット入力した際に表示されるウィンドウは使用しないでください。 Glenelgは動作上、このチャットファイルを監視しているため、ROCALFOと互いに干渉してしまいます。
準備2:連携する chatファイルの確認 †
RO クライアント画面で、/savechat を実施してください。
ファイルエクスプローラーを開いて、チャットファイルのあるフォルダ
(人によりますが、Gravity\RO\chat というような場所)を見てください。
そこに、準備1で作成したウィンドウの名前がついたテキストファイルが
できていることを確認してください。
例:NewTab_2 というウィンドウを作っていたら、Chat_NewTab_2.txt
というファイルがあるはずです。
準備3:RO_CALFOの設定 †
RO_CALFOを起動してください。
「設定」タブを開くと、そこに「監視対象ファイル」という入力欄が
あります。[編集]ボタンを押して編集画面を開き、準備2で確認したファイルをフルパスで指定して
してください。
例えば:
C:\Gravity\Ragnarok\Chat\Chat_NewTab_2.txt
・・・というようにです。
準備4:RO_CALFO 動作を開始させる †
RO_CALFO の「調査結果」タブに移動。
「●監視開始」と表示されているステータスバーをクリックすると
「●監視中…」となります:この状態になると、RO_CALFOが動作を
開始します。
あとは、罠のヒントをROクライアント上で確認したら、そのままクライアントで /savechat すればOKです。
▼参考:技術的な話
▲参考:技術的な話
技術的な話。 †
チャットファイルからヒント行を切り出す仕組み †
基本的には、単にチャットファイルを検索しているだけです。
宝箱まわりのテキストは ROシステムが自動生成している定型フォーマットなので、わりと簡単です。
ファイル内の文字列を、最終行から順にさかのぼって・・・
- 『モンスターを全滅させた。宝箱が出現した』となっている行を、終端として利用します。
このログ以降〜最新行が、現在の宝箱用のヒント、ということです。
- 先頭が『……[』で始まる行が、いわゆるヒントの行。
- 複数プレイヤー==ヒント行も複数行ありうるので、とりあえずバッファにため込みます。
複数ヒントのマージ処理 †
今回の場合、ヒント・罠名に出てくる文字に「同じ文字が複数回入りうる」ことが面倒でした。
例えば、2人のヒントが以下だった場合。最終的なヒントはどうするか。
- して
- くししん
単純に足し算しちゃうと、「し」が多くなりすぎる。
「すでにあるものは足さない」という考え方だと、うまくやらないと2個目の「し」が載せられない。
人間だと直感的にできるものですが、プログラムにするにはアルゴリズムを考えないとならんので。
結局友瀬は、いろいろ考えて、以下のようなやりかたを実施しました。
もっとうまい手はあるかもしれんけど。
とりあえず、1回のヒント文字群は1文字ずつソートしておく。
ROから受けたヒントが「て」「ん」「し」なら、「してん」にソート。左ほど『若い』ようにしておくわけです。
で、1つの「マージ元」に対して、「追加ヒント」をマージするんだけど、ここが肝。
1手ずつ、動きを説明する。
- まず、「マージ元」および「追加ヒント」、それぞれ先頭の1文字目に注目する。
- 注目している1文字同士を、比較する。
- もし「一致」した場合、「すでに知っているヒント」。
「最終結果」にこの文字を追加して、「マージ元」と「追加ヒント」、それぞれ注目点を1つ後ろにずらす。
- これによって追加ヒントが全て終わったら、マージ元の現在位置から後ろの全てを「最終結果」に追加して、マージ終了。
- これによってマージ元が全て終わったら、追加ヒントの現在位置から後ろの全てを「最終結果」に追加して、マージ終了。
- 一致せず、かつマージ元のほうが「若い」場合、「マージ元だけが知っているヒント」。
マージ元の現在文字を「最終結果」に追加、マージ元の注目文字を1文字進めて、2に戻る。
- もちろん、ここでマージ元が最後になる可能性がある。
追加ヒントの現在位置から後ろの全てを「最終結果」に追加して、マージ終了。
- 一致せず、かつ追加ヒントのほうが「若い」場合、「追加ヒントだけが知っている」ヒント。
追加ヒントの現在文字を「最終結果」に追加、追加ヒントのの注目文字を1文字進めて、2に戻る。
- もちろん、ここで追加ヒントが最後になる可能性がある。
マージ元の現在位置から後ろの全てを「最終結果」に追加して、マージ終了。
具体的に実施した例。
マージ元:くししん
追加ヒント:して
→期待される最終結果:くししてん
上記ルールに従って、1文字ずつチェックしていく。
- マージ元「く」、追加ヒント「し」
- 上記「マージ元のほうが若い」ケース。
「く」を最終文字に追加して、マージ元注目点を2文字目に。
- 最終結果:く
- マージ元「し」、追加ヒント「し」
- 上記「一致」のケース。
「し」を最終文字に追加して、マージ元注目点を3文字目、ヒント注目点を2文字目に。
- 最終結果:くし
- マージ元「し(3文字目)」、追加ヒント「て」
- 上記「マージ元のほうが若い」ケース。
「し(3文字目)」を最終文字に追加して、マージ元注目点を4文字目に。
- 最終結果:くしし
- マージ元「ん」、追加ヒント「て」
- 上記「追加ヒントのほうが若い」ケース。
「て」を最終文字に追加して、追加ヒント注目点を1つ後ろに・・・で、追加ヒント終了。
マージ元の残りのヒントを全部マージして終了。
- 最終結果:くししてん
ヒントと罠とのマッチング †
上記ヒントのマージに近い形で「1文字ずつ」比較するように実装しました。
同じ文字が複数回続くケースも、上記と同じように「進める」感じで処理したわけです。
・・・なんですが。
改めて考えると、このマッチングは正規表現でできたな(笑)
そっちのほうがスマートだ(^^;;;
まあそんな感じ。