【Ruby】和了判定プログラムを作成する。(1)-基本的な流れ【麻雀】

和了を判定するまでの流れを書き出す。

作成している麻雀牌入れ替えパズルで使用する「和了り判定プログラム」を作成します。

このゲームだけでなく、普通の麻雀の和了り判定にも使えるプログラムになりますので、麻雀ゲームを作成したいと考えている方にも、参考になるかと思います。

麻雀の和了

麻雀の和了には、大きく分けて、

  1. 面子手
  2. 七対子
  3. 国士無双

の、3種類があります。

この中の「2.七対子」と「3.国士無双」は、例外的な和了り方で、なおかつ判定もそれほど難しくないのですが、主な和了り方である「1.面子手」の判定が複雑です。

まずは、面子手の和了判定に必要な要素を書き出していきます。

面子手の仕組み

面子手は、「4面子1雀頭」の組み合わせで成り立ちます。

「面子」は同じ牌3枚(刻子)、または連続する数牌3枚(順子)のことを指し、「雀頭」は同じ牌2枚のことを指します。

つまり、面子手は、四つの「順子」または「刻子」、そして一つの「雀頭」で構成されています。

和了り判定は、これらの要素ができているか否かの判定をしていき、面子にも雀頭にも使われていない牌が一枚もなければ、「和了り」という事になります。

和了判定の流れ

手牌データは次のような形になっています。

#牌の種類を配列で定義
hai_type=[
   1, 2, 3, 4, 5, 6, 7, 8, 9,	#萬子
  11,12,13,14,15,16,17,18,19,	#筒子
  21,22,23,24,25,26,27,28,29,	#索子
  31,33,35,37,                  #風牌
  41,43,45,                     #三元牌
]

#手牌(例)
tehai=[1,1,2,2,3,3,3,4,5,11,12,13,19,19]

入れ替えパズルで使用している裏牌は、和了りに不要な牌のため、今回は使用しません。

手牌を表す変数”tehai”は、以下の手牌になっています。

一萬:麻雀王国一萬:麻雀王国二萬:麻雀王国二萬:麻雀王国三萬:麻雀王国三萬:麻雀王国三萬:麻雀王国四萬:麻雀王国五萬:麻雀王国一筒:麻雀王国二筒:麻雀王国三筒:麻雀王国九筒:麻雀王国九筒:麻雀王国

この手牌は以下のような面子構成のため。「和了り」になっています。

一萬:麻雀王国二萬:麻雀王国三萬:麻雀王国 + 一萬:麻雀王国二萬:麻雀王国三萬:麻雀王国 + 三萬:麻雀王国四萬:麻雀王国五萬:麻雀王国 + 一筒:麻雀王国二筒:麻雀王国三筒:麻雀王国 + 九筒:麻雀王国九筒:麻雀王国

このtehaiデータの和了判定を行うようにします。

簡単な流れは、

  1. 雀頭判定
  2. 刻子判定
  3. 順子判定
  4. 4面子1雀頭になっていれば「和了り」

と、なります。

手牌データを判定しやすいように変換する。

以降の処理をやりやすくするため、手牌データを変換します。

上の配列”tehai”は「手牌14枚がどのような牌か?」を表した形になっています。

このままでは、以降の判定が複雑になるため、「どの牌を何枚持っているか?」を言う形の配列”tehai_check ”に変換します。

#手牌(例)
tehai=[1,1,2,2,3,3,3,4,5,11,12,13,19,19]

tehai_check = Array.new(46,0)    #要素数46(牌の種類数)かつ初期値0の配列
tehai.map {|v|tehai_check[v]+=1}

このコードを実行すると、配列”tehai_check”は以下のようになります。

#tehai_check
[
 0, 2, 2, 3, 1, 1, 0, 0, 0, 0, #萬子
 0, 1, 1, 1, 0, 0, 0, 0, 0, 2, #筒子
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, #索子
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, #風牌
 0, 0, 0, 0, 0, 0              #三元牌
 ]

この様にしておくと

  • 雀頭候補 → 2以上の値の要素
  • 刻子候補 → 3以上の値の要素
  • 順子候補 → 連続する3要素が1以上

と判定することができるため、以降の判定がしやすくなります。

次回は、雀頭判定を行います。

次回記事は、こちらです。↓

コメント

タイトルとURLをコピーしました