【Ruby】和了判定プログラムを作成する。(4)-順子判定【麻雀】

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

順子を判定する。

今回は、順子判定を作成します。

順子は連続した数牌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

次回は、特殊役である国士無双と七対子の和了判定のプログラムを作成したいと思います。

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

コメント

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