【DXRuby】入れ替えパズルをつくってみる。(9)-点数計算プログラム

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

完成に向けて、ラストスパート!!

後は点数計算を加えるのみとなりました。完成へ向けてラストスパートです!!。

和了りの時のイメージ

和了った時に、次のような画面を表示するために、必要な要素をプログラムに追加していきます。

点数計算プログラム

まずは、点数計算プログラムです。このプログラムを、”point_check.rb”というファイル名で、メインプログラムと同じフォルダ(ディレクトリ)に保存してください。

def mentsu_type_check(m)
  mentsu = m
  if m.count==2 then
    return "雀頭"
  elsif m.all?{|x|x==m[0]} then
    return "刻子"
  else
    return "順子"
  end
end

def point_check(t,sw,rw,ah,th)
  yaku_list=[]
  tehai_list = t
  point_list = Hash.new
  if (sw==31) then
    point_list[ 20]=[0,   0, 2000, 3900, 7700,12000,18000,18000,24000,24000,24000,36000,36000,48000]
    point_list[ 25]=[0,   0, 2400, 4800, 9600,12000,18000,18000,24000,24000,24000,36000,36000,48000]
    point_list[ 30]=[0,1500, 2900, 5800,12000,12000,18000,18000,24000,24000,24000,36000,36000,48000]
    point_list[ 40]=[0,2000, 3900, 7700,12000,12000,18000,18000,24000,24000,24000,36000,36000,48000]
    point_list[ 50]=[0,2400, 4800, 9600,12000,12000,18000,18000,24000,24000,24000,36000,36000,48000]
    point_list[ 60]=[0,2900, 5800,12000,12000,12000,18000,18000,24000,24000,24000,36000,36000,48000]
    point_list[ 70]=[0,3400, 6800,12000,12000,12000,18000,18000,24000,24000,24000,36000,36000,48000]
    point_list[ 80]=[0,3900, 7700,12000,12000,12000,18000,18000,24000,24000,24000,36000,36000,48000]
    point_list[ 90]=[0,4400, 8700,12000,12000,12000,18000,18000,24000,24000,24000,36000,36000,48000]
    point_list[100]=[0,4800, 9600,12000,12000,12000,18000,18000,24000,24000,24000,36000,36000,48000]
    point_list[110]=[0,5300,10600,12000,12000,12000,18000,18000,24000,24000,24000,36000,36000,48000]

    yakumann = 48000
  
  else
    point_list[ 20]=[0,   0,1300,2600,5200,8000,12000,12000,16000,16000,16000,24000,24000,32000]
    point_list[ 25]=[0,   0,1600,3200,6400,8000,12000,12000,16000,16000,16000,24000,24000,32000]
    point_list[ 30]=[0,1000,2000,3900,7700,8000,12000,12000,16000,16000,16000,24000,24000,32000]
    point_list[ 40]=[0,1300,2600,5200,8000,8000,12000,12000,16000,16000,16000,24000,24000,32000]
    point_list[ 50]=[0,1600,3200,6400,8000,8000,12000,12000,16000,16000,16000,24000,24000,32000]
    point_list[ 60]=[0,2000,3900,7700,8000,8000,12000,12000,16000,16000,16000,24000,24000,32000]
    point_list[ 70]=[0,2300,4500,8000,8000,8000,12000,12000,16000,16000,16000,24000,24000,32000]
    point_list[ 80]=[0,2600,5200,8000,8000,8000,12000,12000,16000,16000,16000,24000,24000,32000]
    point_list[ 90]=[0,2900,5800,8000,8000,8000,12000,12000,16000,16000,16000,24000,24000,32000]
    point_list[100]=[0,3200,6400,8000,8000,8000,12000,12000,16000,16000,16000,24000,24000,32000]
    point_list[110]=[0,3600,7100,8000,8000,8000,12000,12000,16000,16000,16000,24000,24000,32000]

    yakumann = 32000
  end
  point = 0
  round_wind = Array.new
  round_wind[31]="東"
  round_wind[33]="南"
  round_wind[35]="西"
  round_wind[37]="北"
  
  #自風
  self_wind = Array.new
  self_wind[31]="東"
  self_wind[33]="南"
  self_wind[35]="西"
  self_wind[37]="北"
  # 役満判定
  tehai_list.each do |tehai|
    yaku=[]
    ##地和判定
    yaku << ["地和"] if th == true
    ##国士無双判定
    if tehai.count==2 then
      yaku << ["国士無双"]
    end
    ##緑一色判定
    if ((tehai.flatten-[22,23,24,26,28,43]).empty? == true) then
      yaku << ["緑一色"]
    end
    #清老頭判定
    if ((tehai.flatten-[1,9,11,19,21,29]).empty? == true) then
      yaku << ["清老頭"]
    end
    #大三元判定
    if ((tehai.include?([41,41,41]) && tehai.include?([43,43,43]) && tehai.include?([45,45,45])) == true) then
      yaku << ["大三元"]
    end
    #四喜和判定
    if ((tehai.include?([31,31,31]) && tehai.include?([33,33,33]) && tehai.include?([35,35,35])&& tehai.include?([37,37,37])) == true) then
      yaku << ["大四喜"]
    elsif(tehai.flatten.count{|x|x > 30 && x < 40} == 11) then
      yaku << ["小四喜"]
    end
    #九連宝燈判定
    if((tehai.flatten.all?{|x| x > 0 && x < 10}) || (tehai.flatten.all?{|x| x > 10 && x < 20}) || (tehai.flatten.all?{|x| x > 20 && x < 30})) then
      #処理
      cp_tehai = []
      tehai.each do |x|
        t=x.map{|y| y %10 }
        cp_tehai << t
      end
      break if cp_tehai.flatten.count(1) != 3 || cp_tehai.flatten.count(9) != 3  
      cp_tehai= cp_tehai.flatten - [1,9]
      tmp = true
      (2..8).each do |x|
        tmp = cp_tehai.include?(x)
        break if tmp == false
      end
      break if tmp == false
      yaku << ["九連宝燈"]
    end
    ##四暗刻判定(刻子4)
    if (mentsu_type_check(tehai[0])=="雀頭")&&(tehai[1..4].all?{|x|mentsu_type_check(x)=="刻子"}) then
      yaku << ["四暗刻"]
    end
    #字一色判定
    if (tehai.flatten.all?{|x| x > 30} == true) then
      yaku << ["字一色"]
    end

    yaku.count==1 ? yakumei= "役満" : yakumei="#{yaku.count}倍役満"
    yaku_list << [yaku , [yakumann * yaku.count , yakumei]] if yaku.count!=0
    
  end #tehai_list.each 役満判定

  if yaku_list.count!=0 then
    #点数が高い方を返す
    y = yaku_list.max_by{ |t| t[1][0]}
    return y
  end

	#通常役判定
  tehai_list.each do |tehai|
    fu =20 + 2  #面前自摸和了り限定
    yaku=[]
    yaku << ["門前清自摸和",1]
    #役牌判定
    yaku << ["自風 #{self_wind[sw]}",1] if (tehai.include?([sw,sw,sw]))
    yaku << ["場風 #{round_wind[sw]}",1] if (tehai.include?([rw,rw,rw]))
    yaku << ["役牌 白",1] if (tehai.include?([41,41,41]))
    yaku << ["役牌 發",1] if (tehai.include?([43,43,43]))
    yaku << ["役牌 中",1] if (tehai.include?([45,45,45]))
    #七対子判定
    yaku << ["七対子",2] if(tehai.count==7)
    #三暗刻判定
    yaku << ["三暗刻",2] if(tehai.count{|m| mentsu_type_check(m)=="刻子"} == 3)
    #一気通貫判定
    if ((([[1,2,3],[4,5,6],[7,8,9]]-tehai).empty?) || (([[11,12,13],[14,15,16],[17,18,19]]-tehai).empty?) || (([[21,22,23],[24,25,26],[27,28,29]]-tehai).empty?)) then
      yaku << ["一気通貫",2]
    end
    #三色同順判定
    (1..7).each do |h|
      if(([[h,h+1,h+2,],[h+10,h+11,h+12],[h+20,h+21,h+22]]-tehai).empty?) then
        yaku <<["三色同順",2]
        break
      end
    end
    #三色同刻判定
    (1..9).each do |h|
      if(([[h,h,h,],[h+10,h+10,h+10],[h+20,h+20,h+20]]-tehai).empty?) then
        yaku <<["三色同刻",2]
        break
      end
    end
    #小三元判定
    yaku << ["小三元",2] if(tehai.flatten.count{|x|x > 40 && x < 50} == 8)
    #一色判定
    ##清一色判定
    if((tehai.flatten.all?{|x| x > 0 && x < 10}) || (tehai.flatten.all?{|x| x > 10 && x < 20}) || (tehai.flatten.all?{|x| x > 20 && x < 30})) then
      yaku << ["清一色",6]
    ##混一色判定
    elsif((tehai.flatten.all?{|x| x > 0 && x < 10 || x > 30}) || (tehai.flatten.all?{|x| x > 10 && x < 20 || x > 30}) || (tehai.flatten.all?{|x| x > 20})) then
      yaku << ["混一色",3]
    end
    #盃口系判定
    ##二盃口判定
    if ((mentsu_type_check(tehai[0])=="雀頭")&&(tehai[1..4].all?{|x|mentsu_type_check(x)=="順子"}) && (tehai[1]==tehai[2]) && (tehai[3]==tehai[4])) then
      yaku << ["二盃口",3]
    ##一盃口判定
    elsif ((mentsu_type_check(tehai[1])=="順子" && (tehai.count(tehai[1]) == 2)) || (mentsu_type_check(tehai[2])=="順子" && (tehai.count(tehai[2]) == 2)) || (mentsu_type_check(tehai[3])=="順子" && (tehai.count(tehai[3]) == 2))) then
      yaku << ["一盃口",1]
    end
    #帯么老頭系判定
    ##混老頭判定
    if ((tehai.flatten - [1,9,11,19,21,29,31,33,35,37,41,43,45]).empty?) then
      yaku << ["混老頭",2]
    ##純全帯么判定
    elsif(((tehai-[[1,1,1],[9,9,9],[11,11,11],[19,19,19],[21,21,21],[29,29,29],[1,2,3],[7,8,9],[11,12,13],[17,18,19],[21,22,23],[27,28,29]]).flatten - [1,9,11,19,21,29]).empty?) then
      yaku << ["純全帯么",3]
    ##全帯么判定
  elsif(((tehai-[[1,1,1],[9,9,9],[11,11,11],[19,19,19],[21,21,21],[29,29,29],[1,2,3],[7,8,9],[11,12,13],[17,18,19],[21,22,23],[27,28,29],[31,31,31],[33,33,33],[35,35,35],[37,37,37],[41,41,41],[43,43,43],[45,45,45]]).flatten - [1,9,11,19,21,29,31,33,35,37,41,43,45]).empty?) then
    yaku << ["全帯么",2]
  end
  #断么九判定
  if ((tehai.flatten - [2,3,4,5,6,7,8,12,13,14,15,16,17,18,22,23,24,25,26,27,28]).empty?) then
    yaku << ["断么九",1]
  end
  #平和判定
  #1.全て順子
  if (mentsu_type_check(tehai[0])=="雀頭")&&(tehai[1..4].all?{|x|mentsu_type_check(x)=="順子"}) then
    #2.雀頭が役牌ではない
    if(tehai[0]!=[sw,sw] && tehai[0]!=[rw,rw] && tehai[0][0] < 40) then
      #3.両面待ち
      if( ((tehai[1][0] == ah) && ah % 10 != 7) || ((tehai[1][2] == ah) && ah % 10 != 3) || ((tehai[2][0] == ah)  && ah % 10 != 7) || ((tehai[2][2] == ah) && ah % 10 != 3) || ((tehai[3][0] == ah) && ah % 10 != 7) || ((tehai[3][2] == ah) && ah % 10 != 3) || ((tehai[4][0] == ah) && ah % 10 != 7) || ((tehai[4][2] == ah) && ah % 10 != 3) ) then
        yaku << ["平和",1]
      end
    end
  end
  
  #符計算
  if (yaku.include?( ["七対子",2])) then
    fu = 25
  elsif (yaku.include?( ["平和",1])) then
    fu = 20
  else
    #雀頭
    if (tehai[0]==[41,41])||(tehai[0]==[43,43])||(tehai[0]==[45,45]) then
      fu += 2
    elsif (tehai[0]==[rw,rw]) then
      fu += 2
    elsif (tehai[0]==[sw,sw]) then
      fu += 2
    end
    #刻子
    tehai.each do |t|
      if (mentsu_type_check(t)=="刻子") then
        if (t.include?(1 || 9 || 11 || 19 || 21 || 29 || 31 || 33 || 35 || 37 || 41 || 43 ||45)) then
          fu += 8
        else
          fu += 4
        end
      end
    end
    #和了り形
    ##単騎
    if tehai[0]==[ah,ah] then
      fu +=2
    else
      tehai.each do |t|
        if (mentsu_type_check(t)=="順子") then
          #嵌張
          if (t[1]== ah) then
            fu += 2
          else
            #辺張
            [0,10,20].each do |x|
              if ((t == [x+1,x+2,x+3] && ah == (x+3)) || (t == [x+7,x+8,x+9] && ah == (x+7))) then
                fu +=2
              end
            end
          end
        end
      end
    end
    #符の繰り上げ
    fu = fu / 10.0
    fu = fu.ceil
    fu =fu * 10
    fu = fu.to_i
  end

  han =0
  yaku.map{|x|han += x[1]}
  han = 13 if han > 14
  yaku_list << [yaku,[point_list[fu][han],[han,fu]]] if yaku.count!=0
  end #tehai_list.each 通常役判定

  if yaku_list.count!=0 then
    #点数が高い方を返す
    y = yaku_list.max_by{ |t| t[1][0]}
    return y
  end

end

if文の羅列による条件分岐がメインの、力技のプログラムになっています。(;^ω^)

“point_check”関数には5つの引数を使用していて、内容は以下のようになっています。

  1. t : 手牌(和了判定プログラム”agari_check”の返り値)
  2. sw : 自風
  3. rw : 場風
  4. ah : 和了り牌
  5. th : 地和判定

点数計算において、字牌は自風と場風は役牌になる場合とならない場合があるため判定が必要で、

平和においては和了り方が両面待ちであるかどうかと、雀頭が役牌でないことを確認することが必要なため、このような引数になっています。

また、配牌直後で、和了り形ができていた場合は「地和」とするため、地和判定用の変数を用意します。

次に、“point_check”関数の返り値は、次のようになっていて、役満と通常役で若干違いがあります。

#役満
[役リスト, [点数, 役表示用文字列("役満" or "〇倍役満")]] 

#通常役
[役リスト, [点数,[飜数,符]]] 

このプログラムを使用するため、ゲームプログラムのはじめを、以下のように変更します。

require 'dxruby'
require_relative './agari_check.rb'
require_relative './point_check.rb'  #←追加

これで、和了りの時に表示する情報を用意することができました。

次回は、点数計算時のプログラムを追加します。

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

コメント

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