tomohxxの日記

麻雀プログラミング

牌の危険度予測ツール

牌の危険度予測ツールを開発しました。

github.com

ここで述べる危険度は以下の式で定義されます。この式はすべての聴牌形の出現確率が等しいという最も単純な仮定の下で危険度を求めます。


(\text{ある牌を待つ確率}) = \frac{(\text{その牌を待つ聴牌形の数})}{(\text{すべての聴牌形の数})}
\tag{1}

どのように聴牌形を数え上げるかについては以下のページを参照してください。大雑把には天和の確率を求めたり配牌時向聴数を求めたりすることと同じようなこと(動的計画法)をやっています。

tomohxx.github.io

この式では切り順や手出し・ツモ切りは考慮されません。上級者にはもの足りないかもしれませんが初・中級者には十分有用だと思われます。

簡単に使い方を説明します。例えば以下の場面で立直をかけている対面に対して牌の危険度を求めてみます。なお、このツールは対象者が聴牌しているという前提で牌の危険度を求めます。よって対象者が立直をかけているか、三副露以上している、連続でツモ切りしているというように聴牌していることを確信できる必要があります。

まず以下のファイルを作成します。

4
1m 1 1
2m 1 1
3m 4 0
4m 3 0
5m 3 0
6m 3 1
7m 3 0
8m 2 0
9m 2 1
1p 0 1
2p 2 0
3p 2 0
4p 3 0
5p 3 0
6p 4 0
7p 1 0
8p 1 1
9p 2 0
1s 3 0
2s 3 1
3s 3 0
4s 3 0
5s 3 0
6s 1 0
7s 1 1
8s 3 0
9s 2 0
1z 4 0
2z 1 0
3z 2 0
4z 3 1
5z 1 1
6z 1 1
7z 2 1

1行目に手牌の面子数を、2行目以降に各牌の残り枚数と振聴かどうかのフラグを入力します。このファイルをwall_river.txtという名前で保存します。次に以下のコマンドでDockerのイメージを作成、コンテナを作成・実行して危険度の計算とグラフの出力を行います。計算時間は環境によりますが私の環境では2~3ミリ秒です。

$ docker build . -t predictor
$ docker run -v $PWD/output:/output -v $PWD/wall_river.txt:/wall_river.txt --rm predictor

次のグラフが出力されます。

このグラフから36s、47m、3pから7pが危険だとわかります。中らずと雖も遠からずという感じでしょうか。


最後に補足事項があります。このツールで計算された牌の危険度が本当に正しいのか、つまり(1)式を正しく計算できているのか客観的に証明することができていません。アルゴリズムによって聴牌形を数え上げている人が他にいないことと、私自身これ以外の方法で聴牌形を数えたことがないためです。もちろんアルゴリズムは正しいと確信していますが実装に誤りがある可能性を否定できません。また証明しようにもどのようなテストケースを作成すればよいかという問題もあります。

統計やシミュレーションではなく、厳密に聴牌形を数え上げることで危険度を予測するというツールは他にはないはずです。統計やシミュレーションでは誤差が避けられませんがこのツールには誤差がないことが魅力ではないかと思います。厳密に危険度を議論したいという状況がどれくらいあるのかわかりませんが、そのようなときにはぜひ活用していただきたいと思います。