tomohxxの日記

麻雀プログラミング

Mjaiイベントログ管理ツールの開発

ここ2週間くらい、Mjaiイベントログ管理ツールMjai Recoderを作っています。Mjaiとは麻雀AI対戦環境のことです。

gimite.net

このブログでは過去に自作麻雀AIの評価に利用させてもらっています。gimiteさん、ありがとうございます。

Mjaiは対戦機能だけでなく各クライアントの平均順位とその信頼区間を計算するという成績管理機能が備わっています。ただ、クライアントの成績を知るとなると平均順位だけでは不満です。例えば和了率や放銃率、順位分布は知りたいところです。実のところこれらのデータを知りたければログファイル(*.mjson)を解析すれば簡単に済んでしまいます。過去の自作麻雀AIではPythonスクリプトファイルでログファイルを解析していました。

ではなぜ今回Mjaiイベントログ管理ツールを作るに至ったのかというと、複合イベントの割合を簡単に知ることができるようにするためです。例えば和了率を知りたければ(和了回数)/(局数)のように計算しますよね。またリーチ率を知りたければ(リーチ回数)/(局数)で計算します。ではリーチをかけた状態から和了した割合はどのように計算するでしょうか?(リーチから和了した回数)/(リーチ回数)で計算しますね。さて、(リーチから和了した回数)のような複数のイベントが組み合わさった変数を安易に受け入れてよいのでしょうか?和了、リーチ、鳴きといったイベントの組合せの数は有限ではあるものの、複合イベントが発生した割合を知るためにイベントの組合せに対応する変数を定義していくと、スクリプトファイルが読みにくくなりバグの混入の原因にもなりかねます。

そこで、複合イベントの割合を知るためにSQLを利用することにしました。事前にDBを用意しておいて、各イベントテーブルに各イベントが発生したときの状況を記録しておきます。(複合)イベントの割合を知るために関係するテーブルに問い合わせて発生回数を数えるようにします。SQLの内部結合、副問合せなどの構文を使えば、複合イベント用のテーブルを用意することなく発生回数を数えられるようになります。ただイベントの組合せによってはSQL文が難解になってしまう可能性があります。

今回開発したMjai Recoderは、Mjaiサーバー機能を提供しつつ生成されたログファイルを解析してイベントの発生状況をDBに記録するツールです。Mjai Recorederはあくまでイベントログ管理ツールなので、成績を知るためには別途DBのクライアントを用意してSQL文を実行する必要があります。ユースケースとして、シェルでSQL文を実行するのではなく、MetabaseのようなDBと連携してデータを可視化するツールを利用することを想定しています。

github.com

www.metabase.com

簡単に使い方を説明します。Mjai Recoderは以下のようなテーブルを管理します。

f:id:tomohxx:20210327232918p:plain
ER図

例えば和了率は次のSQL文で知ることができます。

select count(*) from winnings inner join players on winnings.actor = players.id where players.name = 'player_name';

今後はテーブルの数を増やしていろいろな複合イベントの割合を計算できるようにする予定です。