前回記事は、こちらです。↓
順子を判定する。
今回は、順子判定を作成します。
順子は連続した数牌3枚
どの牌が何枚あるかを表した配列”tehai_check ”から順子を抜き出すプログラムは以下のようになります。
#tehai_check :要素数46(牌の種類数)かつ初期値0の配列
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 #三元牌
]
(1..27).each do |i|
tehai_check [i].times do
if tehai_check [i]>0&&tehai_check [i+1]>0&&tehai_check [i+2]>0 then
amtmp << [i,i+1,i+2]
tehai_check [i ]-=1
tehai_check [i+1]-=1
tehai_check [i+2]-=1
end
end
end
こちらのプログラムで(tehai_check[1..3])から(”tehai_check[27..29])まで順子になっていたら、抜き出すことができます。
途中でtehai_check[9..11]のように萬子と筒子など、2種類の牌の並びを判定している個所もでてきますが、tehai_check[10]とtehai_check[20]が必ず”0”になるダミーになっていますので、「順子ではない。」と判定できるようになっています。
以上をふまえて完成したプログラムがこちらです。
#雀頭候補毎にcheck
jt=[] #雀頭候補格納配列
tehai_check.each_with_index do |v,i|
if v>=2 then
jt << i
end
end
jt.each_with_index do |v,i|
tmp=tehai_check.dup #tehai_checkを複製
amtmp=[] #和了りの手牌を格納する配列
#刻子判定
kohtsu_list = [] #刻子候補リスト
#刻子をチェック
tmp.each_with_index do |vv,ii|
kohtsu_list << ii if vv>=3
end
#刻子候補洗い出し
kohtsu_ptn = []
num = 2**kohtsu_list.size
bit = kohtsu_list.size
if kohtsu_list.size != 0 then
kohtsu_ptn_bit=Array.new(num)
#ここからビット(2進数)を使用
(num-1).downto(0) do |i|
kpb_tmp=Array.new(bit - 1)
(bit-1).downto(0) do |ii|
kpb_tmp[ii]= i[ii]!=0 ? kohtsu_list[ii] : 0
end
kpb_tmp.delete(0)
kohtsu_ptn_bit[i]=kpb_tmp
end
#ここまで
end
#刻子パターンごとに刻子を抜く
kohtsu_ptn.each_with_index do |vv,ii|
tmp2=tmp.dup
amtmp2=amtmp.dup
vv.each do |vvv|
amtmp2 << [vvv,vvv,vvv]
tmp2[vvv]-=3
end
#和了判定(未実装)
#順子を抜く
(1..27).each do |iii|
tmp2[iii].times do
if tmp2[iii]>0&&tmp2[iii+1]>0&&tmp2[iii+2]>0 then
amtmp2 << [iii,iii+1,iii+2]
tmp2[iii ]-=1
tmp2[iii+1]-=1
tmp2[iii+2]-=1
end
end
end
#和了判定(未実装)
end
#順子を抜く(刻子なし)
(1..27).each do |iii|
tmp[iii].times do
if tmp[iii]>0&&tmp[iii+1]>0&&tmp[iii+2]>0 then
amtmp << [iii,iii+1,iii+2]
tmp[iii ]-=1
tmp[iii+1]-=1
tmp[iii+2]-=1
end
end
end
#和了判定(未実装)
end
次回は、特殊役である国士無双と七対子の和了判定のプログラムを作成したいと思います。
次回記事は、こちらです。↓
コメント