Home

Mjaiボットを評価する

Mjaiボットを対戦させるサーバー mjai-test-server を作成し、これを使って既存のMjaiボットを対戦させ、その強さを評価しました。


評価方法

麻雀は運の要素が大きい競技です。 完全に同じプログラム同士を戦わせても、1000戦の対局では平均順位で2.45〜2.55程度のバラつきは出てしまいます。 そこで 電脳麻将 ではAIの評価に デュプリケート対局 と呼ばれる対局方法を導入しています。 デュプリケート対局とは「牌山を固定」した同じ条件で対局を行うことで「相対評価」で強弱を決定するという方法です。 まずベースとなる同じ4人のプレーヤーで一定数(1000戦程度)の対局を行います。 次にその中の1名を評価対象のプレーヤーと交代し、同じ条件で対局を行います。 これを評価対象者数分繰り返すことで、それぞれのプレーヤーを相対的に評価できるという訳です。

mjai-test-serverを使えば、以下でこれを実現できます。

$ mjai-test-server -i shan.json.gz -o manue.json mjai-diannao mjai-manue

牌山 shan.json.gz を使って mjai-diannao 3体と mjai-manue 1体でデュプリケート対局を行い、その結果の牌譜をmanue.json に保存します。

選手紹介

今回評価したボットは以下の6体です。

ボット 言語 GitHub アルゴリズム
mjai-diannao JavaScript kobalab/mjai-bot ルールベース
mjai-shanten Ruby gimite/mjai ルールベース
mjai-manue Ruby gimite/mjai-manue 期待値ベース
mjai-akochan C++ critter-mj/akochan 期待値ベース
mjai-akagi Rust + Python shinkuan/Akagi-MjaiBot-Mortal 機械学習(mortal_298k)
mjai-mortal Rust + Python Equim-chan/Mortal 機械学習(mortal-582500)

Mjaiボットのインストール

今回評価するMjaiボットのインストール方法を簡単に説明します*1。

mjai-diannao

電脳麻将のMjaiボットです。 nodeとnpmをインストール*2した上で、以下でインストールします。

$ npm i -g @kobalab/mjai-bot

mjai-shanten

本家Mjaiに同梱されているMjaiボットです。 rubyとgemをインストール*3した上で、以下でインストールします。

$ gem install mjai

mjai-manue

Mjaiの作者によるMjaiボットです。 gem でインストールします。

$ gem install mjai-manue

mjai-akochan

天鳳七段相当とされるAIです。 ボットはC++でビルドする必要があります*4。

GitHubからcloneします。

$ git clone https://github.com/critter-mj/akochan.git
$ cd akochan/

ビルドに boost が必要なのでインストールします*5。

$ sudo dnf install boost-system boost-devel

ボットのログ出力にバグらしきもの*6があるので修正 し、ビルドします。

$ cd ai_src
$ make -f Makefile_Linux 
$ cd ..
$ make -f Makefile_Linux

ボットは LD_LIBRARY_PATH=. ./system.exe mjai_client で起動しますが、mjai-akochan として起動したいので、以下のshellでラップしています*7。

#!/usr/bin/bash
[[ "$1" =~ ^mjsonp://[^:]+:([0-9]+)/[^/]+$ ]] && port="${BASH_REMATCH[1]}"
cd $HOME/Git/akochan/
LD_LIBRARY_PATH=. exec ./system.exe mjai_client $port

mjai-akagi

Mortalとは何か?については 電脳麻将でMortalと対戦する を参照してください。 Mortalのセットアップはやや複雑ですので、まずはビルド済みのライブラリを配布している Akagi-MjaiBot-Mortal を使うのが簡単です。 uv(Pythonパッケージ・プロジェクト管理ツール)をインストール*8した上で以下を行います。

GitHubからcloneします。

$ git clone https://github.com/shinkuan/Akagi-MjaiBot-Mortal.git
$ cd Akagi-MjaiBot-Mortal/

uv sync で環境構築します。

$ uv sync

Mortal系のボットを動作させるには、その頭脳にあたる「モデル」が必要です。 同梱されている mortal.pth はあくまで評価用であまり強くありません。 今回は mortal_298k を使うことにします。 mortal_298k.pth をダウンロードして、カレントディレクトリの mortal.pth を上書きします*9。

ボットは uv run python bot.py で起動しますが標準入出力でしか通信できないので mortal-wrapper の助けを借りて mjai-test-server と接続します。 これを mjai-akagi として起動したいので、以下のshellでラップしています*10。

#!/usr/bin/bash
[ $1 ] && url=$1 || url=mjsonp://127.0.0.1:11600/default
exec mortal-wrapper -v --akagi $url $HOME/Git/Akagi-MjaiBot-Mortal

mjai-mortal

最後に本家Mortalをセットアップします。 ビルドにはRustが必要ですので rustup が使えるようにしておいてください*11。

GitHubからcloneします。

$ git clone https://github.com/Equim-chan/Mortal.git
$ cd Mortal/

libriichi をビルドします。

$ source ~/.cargo/env
$ cargo build -p libriichi --lib --release
$ cp target/release/libriichi.so mortal/

uv で環境構築し、必要なパッケージをインストールします。

$ uv venv
$ uv pip install tqdm toml tensorboard
$ uv pip install torch

MortalのGitHubリポジトリは巨大な開発環境ですが、ボット起動環境は mortal/ ディレクトリにあります。 今回モデルは mortal-582500 を使います。 mortal_582500.pth をダウンロードして、mortal/ ディレクトリに配置します。 どのモデルを使用するかは config.toml で以下のように指定します。

[control]
state_file = 'mortal_582500.pth'

uv で起動しますが、これも mjai-mortal として起動したいので以下のshellでラップします*12。

#!/usr/bin/bash
[ $1 ] && url=$1 || url=mjsonp://127.0.0.1:11600/default
exec mortal-wrapper -v $url $HOME/Git/Mortal

対戦方法

まず mjai-diannao 4体でデュプリケート対局1000戦を行い、この成績を基準値とします。 その後、1席を評価対象のボットと置き換えて同じく1000戦ずつ対局を進めます。

対戦結果

8日間にわたって対局を行い、以下の結果を得ました。

  1. ^ AlmaLinuxにインストールしました
  2. ^ sudo dnf install -y nodejs
  3. ^ sudo dnf install ruby ruby-devel
  4. ^ おそらくC++(gcc)はインストール済みと思いますが、なければ sudo dnf groupinstall -y "Development Tools" でインストールするのがよいでしょう
  5. ^ Macの場合、修正 が必要になると思います
  6. ^ ポート番号の指定をログファイル名と取り違えてファイルを作ってしまうというもの
  7. ^ cd $HOME/Git/akochan/ の部分は環境に合わせてください
  8. ^ curl -LsSf https://astral.sh/uv/install.sh | sh
  9. ^ 残念ながら実行時にファイルの指定はできないようです
  10. ^ $HOME/Git/Akagi-MjaiBot-Mortal の部分は環境に合わせてください
  11. ^ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  12. ^ やはり mortal-wrapper の力を借ります。$HOME/Git/Mortal の部分は環境に合わせてください