Rubyでポーカーの役判定プログラムを書いてみました。[プログラミング]

 文字列内の文字や単語の数をカウントする処理を使ってポーカーの役判定ができるかも?と思ったことから、Rubyでポーカーの役判定プログラムを書いてみました。

 今回のRubyで書いたプログラムは、与えられた手札5枚についての文字列からポーカーの役を判定するものになってます。さすがに今の段階(PaizaランクDが終わった)では、ポーカーゲームができるようなプログラムは手に負えないです。

#カードをスートと数字に分けて配列に入れる
str = “S1 H8 D7 S11 C8” #5枚のカードの内容を、スートと数字をつけて文字列として入力。
suit = str.delete(“^A-Z| “).split(‘ ‘)
snum = str.delete(“^0-9| “).split(‘ ‘)
num = []
flush = 0
straight = 0

for i in 0..4
 num[i] = snum[i].to_i
end

#手札のスートが全て一致しているか判定
if suit.count(suit[0]) == suit.length
    flush = 1
end

#手札が全て続き番号(もしくは、[1,10,11,12,13])になっているか判定
if num.sort[1] == num.sort[0] +1 && num.sort[2] == num.sort[0] + 2 && num.sort[3] == num.sort[0] +3 && num.sort[4] == num.sort[0] + 4 || num.sort == [1,10,11,12,13]
 straight = 1
end

#手札内の同じ数字のカードを数える
count_box = []
for i in 0..num.uniq.length-1
 count_box[i] = num.count(num.uniq[i])
end

#役を判定
if count_box.sort.reverse == [4,1]
    puts “4カード”
elsif count_box.sort.reverse == [3,2]
 puts “フルハウス”
elsif count_box.sort.reverse == [3,1,1]
 puts “3カード”
elsif count_box.sort.reverse == [2,2,1]
 puts “2ペア”
elsif count_box.sort.reverse == [2,1,1,1]
     puts “1ペア”
elsif count_box.sort.reverse == [1,1,1,1,1]
 if num.sort == [1,10,11,12,13] && flush == 1
  puts “ロイヤルストレートフラッシュ”
 elsif straight == 1 && flush == 1 && num.sort != [1,10,11,12,13]
  puts “ストレートフラッシュ”
    elsif flush == 1
  puts “フラッシュ”
 elsif straight == 1
  puts “ストレート”
 else
  puts “ノーペア”
 end
end

 ブログシステムの影響で、Rubyコード文内の’ ‘や” “が全角に自動的に変換されてしまうようです。また半角スペースによるインデントが無効化されるため、全角スペースでインデントしています。このため、そのまま開発環境にコピペしてもエラーになります。
 このコードが動くかどうか試す場合は、お手数ですが、こちらのテキストファイルの方をご使用ください。

手札の情報をそれぞれの配列に格納する

 5枚の手札は、「S1 H8 D7 S11 C8」の形の文字列で表記されます。数字の前の半角アルファベットはスートを表しており、Sがスペード、Hがハート、Dがダイヤ、Cがクラブになってます。なお、ジョーカーは使用しません。

 まずは、手札の文字列について、スートと数字に分けて、それぞれの配列(suit[]、snum[])に入れます。

 スートについては、.delete(“^A-Z| “)メソッドで文字列から数字を消してから、.split(‘ ‘)メソッドによって空白で区切ったものをスート用配列(suit[])に入れます。一方の数字については、.delete(“^0-9| “)メソッドで文字列からアルファベットを消してから、 .split(‘ ‘)メソッドによって空白で区切ったものを数字用配列(snum[])に入れ、さらにデータ型を整数型に変換してから、新しく用意した配列(num[])に入れます。

手札5枚のスートが全て同じかどうかどうかの判定。

 スートが入った配列の最初の要素(suit[0])について配列内の個数をカウントし、配列の要素数(suit.length)と一致していれば、手札のスートが全て一致していることになります。スートが一致した場合は、Flush変数を1にします。

手札5枚が続き番号もしくは、[1,10,11,12,13]になっているかどうかの判定。

 手札5枚の数字が入っている配列num[]の要素が、続き番号もしくは、[1,10,11,12,13]になっているかどうかを判定します。

 num[]の要素は、.sortメソッドで昇順に並べ替えてから、num[1]、num[2]、num[3]、num[4]の要素について、それぞれnum[0]+1、num[0]+2、num[0]+3、num[0]+4と等しいか判定。全て満たしていれば、手札5枚が続き番号になってます。

 ここで手札5枚が続き番号もしくは、[1,10,11,12,13]になっていた場合は、straight変数を1にします。

数字用配列内の要素の個数から役を判定

 手札の数字が入っている配列num[]の中に、同じ数字がいくつあるかカウントします。

 重複を除いた配列(num[].uniq)の各要素について、元の配列num[]に含まれる個数をカウントし、カウント結果格納用の配列(count_box[])に格納します。

 配列count_box[]に同じ数字の個数を格納したら、.sort.reverseメソッドを使用して要素を降順に並べ替てから、その内容によって役を判定していきます。

[4,1]の場合、「4カード」を表示。
[3,2]の場合、「フルハウス」を表示。
[3,1,1]の場合、「3カード」を表示。
[2,2,1]の場合、「2ペア」を表示。
[2,1,1,1]の場合、「1ペア」を表示。

 ここで5枚の手札内に同じ数字がなかった(num[]の内容が[1,1,1,1,1])場合は、次の処理に進みます。

同じ数字のカードがなかった場合の役判定

 Flush変数が1で、num[]の内容が[1,10,11,12,13]であれば、「ロイヤルストレートフラッシュ」を表示。

 Flush 変数、straight 変数がともに1になっていて、かつ、num[]の内容が[1,10,11,12,13]でない場合は、「ストレートフラッシュ」を表示。

 Flush 変数が1で、straight 変数が0の場合は、「フラッシュ」を表示。

 Flush 変数が0で、straight 変数が1の場合は、「ストレート」を表示。

 Flush 変数、straight 変数が両者とも0の場合は、「ノーペア」(いわゆる役無し)を表示。

 以上がRubyで書いたポーカーの役判定プログラムになります。何しろプログラミング初心者なので、気の利いた書き方になっていない。

 プログラムが書き終わったので、オンラインの開発環境サイトpaiza.ioを使って、実際にプログラムを動かしてみます。いくつかのテストデータを入れて試したところ、何とか上手く動いてくれました。

 いずれはポーカーゲームができるプログラムも書けるようになりたいですが、かなり先になりそうです。

にほんブログ村 ゲームブログへ

スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする