麻雀のあがり判定をゼロから書いて、天和コマンドを作ってみた
【車輪】麻雀のあがり判定をゼロから書いて、天和コマンドを作ってみた感想【再発明】
プログラミングの話ですが、麻雀の話です。
$ tenho
ってコマンドを打つと天和がアガれたら面白いんじゃないかと思って、作った
うごくやつができた
こんなん
なぜそんなことを
ruby -e "puts '🀀'.next" => "🀁"
みたいに文字が使えるし、CLIでも見栄えが良いかなと思ってた。
休日の車輪の再発明にはちょうど良さそう。
ロジックの方はおみくじ感覚でかんたんにできるかなと思ってた。
が、あがり判定っていうのはわりと難易度高かった。。
ロジックとか感想とか
以降、だらだらと感想とか書く。
$ tenho
の動き自体は、
- (34 * 4)のカード(牌)の束からランダムに14枚を取り出す。
- それがアガっていれば終了。上がっていなければもう一度14枚取り出す
という感じ。
ランダムに14枚取り出すのはArray#sample
的なものが使った(あ、rubyっす)。
やはりあがり判定がキーになる。
適当に書いた感じでも、1秒間に1500回以上のサンプリングとあがり判定ができたっぽい。意外と速くて満足してしまった : )。
それでも感覚的には天和上がるには200万回ぐらい必要(本当の確率は調べてない。。)なので、数分必要なのだが。。
自分が書く上でポイントだと思ったこと3つ。
3つのあがり系
周知の通り麻雀には3つのあがり形があって(すくなくとも天和の場合はこの3つでいいと思う)
というかんじになる。ここに気づくのがポイント。
スート
スート(トランプでいうところのハート・ダイヤ・クラブ・スペード)が4種類(萬・筒・索・字)。
字牌だけは、順子が作れないという特徴がある。
別のスート同士で順子や刻子や対子は構成できないので、必然的にカードをスート毎にグルーピングする必要が出てくる。
テスト書きながら書くと楽
こういうときのテストは書いてて楽しい
書きながら思ったこと
七対子だるいwwwww
七対子をどこで判定するかがだるい。
たとえば索子が8枚あるということがわかっているとき、それは(3+3+2)形でなかったとしても(2+2+2+2)形かもしれない。
七対子の判定の順序は、最初のほうにしたほうがパフォーマンスが良いかもしれない。
順子と刻子
順子と刻子の判定については難しいかなと思ってたら、そうでもなかった。
三連刻のかたち(444555666とか)の判定は、役を解釈しないかぎり(天和だけを考慮する場合)は気にしなくて良いので。
同様に役を解釈しないかぎりにおいては、七対子か二盃口か、みたいな判定も要らない。
今後書きたいこと
書いてると無性にオプション作りたくなる。いま思いついたのは以下。センス☓。
--[no-]normal
ノーマル型(33332型)を除外--[no-]chi-toitsu
七対子を除外--[no-]kokushi
国士無双を除外--limit [arg]
リミットを指定--sanma
サンマモード
あと他の言語で書いても面白いかもしれないと思ってる