計算機上で向聴数を計算するアルゴリズムとして「(向聴数) = 8 - (面子の数)×2 - (面子候補の数)」という式を計算するものが紹介されることがあります.しかしながら,この計算アルゴリズムは端的に言って間違っています.tomohxx氏の記事「ブロック分解方式向聴数計算アルゴリズムの精度の検証」では,この計算式がコーナーケースで(ごく一般的な麻雀のルールにおける)向聴数とは異なった数値を返すということを指摘するだけでなく,向聴数と異なる数値を返す牌姿のケースの総数を数え上げ,さらには向聴数と異なる数値を返す牌姿のケースを分類するという大偉業を成し遂げています.
この「(向聴数) = 8 - (面子の数)×2 - (面子候補の数)」という計算は,向聴数と異なる数値を返すケースが牌姿全体の総数と比べて著しく少ない(上記tomohxx氏の記事を参照すること)ため,この計算が速度上の利点を持つならば近似アルゴリズムとしての意義もあります1.しかしながら,現状における最速クラスの向聴数計算アルゴリズム2と比較しても特にそういうことはありません.したがって,近似アルゴリズムとしての意義も無く,単に間違っていると断じても現状では問題ないと思われます.
しかしながら,この間違ったアルゴリズムが現状はびこっています.例えば,向聴数計算アルゴリズムとしてしばしば参照される「あらの(一人)麻雀研究所」がこの計算式で向聴数を計算できるとしています.また,向聴数計算アルゴリズムの実装として世界で最も広く利用されている Python の mahjong パッケージの向聴数計算もこのアルゴリズムであるため,特定の牌姿に対して向聴数でない数値を返します.学術論文においてこの計算式を向聴数計算アルゴリズムとして言及するものも散見されます3.
では,現状として,(各ルールにおいて)正しく向聴数を計算するアルゴリズムはどれを用いれば良いのかというと,筆者が知る限り以下の3つが挙げられます:
- 天鳳牌理のアルゴリズム(これまで ad-hoc なアルゴリズムだと考えられていたが,上記のtomohxx氏の記事により正しいことが間接に証明された),
- 枝刈り DFS,
- 01-BFS によるもの.
以上により,今後,計算機上で向聴数を計算する場合は,特定のケースで向聴数と異なる数値を返し,速度上の利点も特に無い,この「(向聴数) = 8 - (面子の数)×2 - (面子候補の数)」という計算アルゴリズムを採用することは避けたほうが良いと考えます.
-
計算機上における向聴数計算ではなく人間による向聴数計算の場合,この計算式の簡易性から存在意義は依然としてあると考えられます. ↩
-
例えば https://github.com/tomohxx/shanten-number, https://github.com/Cryolite/nyanten, https://github.com/Apricot-S/xiangting ↩
-
例えば https://ipsj.ixsq.nii.ac.jp/records/145803 や https://www.jstage.jst.go.jp/article/jsaikbs/124/0/124_28/_article/-char/ja/ ↩