質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

4回答

3011閲覧

ポーカー:最も強い手札がどれか判断する

yuz55

総合スコア11

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2017/04/15 07:43

###前提・実現したいこと
先日、「入力した文字列が、ポーカーのどの役になっているか」を判断するコードに関する質問をしたものです。皆様のお助言のおかげで無事完成させることができました、ありがとうございます。
今度は、複数の手札の情報を入力したときに、それぞれの役名を表示したうえで、どの手札が一番強いかを判断するコードを書いています。

出力例:
card: "H1 H13 H12 H11 H10”,
hand: "Straight_Flush",
best: true

card: "H9 C9 S9 H2 C2”,
hand: "Fullhouse"

この時、「どの手札が一番強いか」を判断するのに、どうしたらよいのか分からず行き詰っています…。この点についてアドバイス頂けたら嬉しいです!
現在、自力で下にあげたコードまで書きました。上の例でいえば、それぞれの手札に対して、cardとhandを出力するところまでです。
###該当のソースコード

ruby

1 2 3#ポーカーの役を判定するアプリケーションをつくる。 4#複数の五枚のカードの組の情報(例:S8 S7 H6 H5 S4, H1 H13 H12 H11 H10)を入力すると、それが何の役になっているのか判定したうえで、一番強い役がどれかを表示。 5 6 7#役の配列をつくる。インデックスの大小で役の強弱を表す。 8YAKU = ["High_Cards", "One_Pair", "Two_Pair", "Three_of_a_Kind", "Straight", "Flush", "Fullhouse", "Four_of_a_Kind", "Straight_Flush", "Royal_Straight_Flush"] 9 10 11#役の判断。 12 13def eval_hand 14 puts "文字列を入力してください(例:S8 S7 H6 H5 S4, H1 H13 H12 H11 H10)" 15 #カンマ(,)で文字列を分割し、いくつかの手札からなる配列を返す。 16 hands = gets.split(",") 17 18 hands.each do |h| 19 #それそれのカードから、スートの部分だけ、数字の部分だけを取り出した配列を別に作る。 20 hand = h.split 21 suits = [] 22 numbers = [] 23 24 hand.each do |c| 25 suits.push c[0] 26 numbers.push c[1].to_i 27 end 28 29 case same_number_counts(numbers) 30 when [2,1,1,1] 31 yaku = YAKU[1] 32 when [2,2,1] 33 yaku = YAKU[2] 34 when [3,1,1] 35 yaku = YAKU[3] 36 when [3,2] 37 yaku = YAKU[6] 38 when [4,1] 39 yaku = YAKU[7] 40 else 41 case [straight(numbers), flush(suits)] 42 when [true, false] 43 yaku = YAKU[4] 44 when [false, true] 45 yaku = YAKU[5] 46 when [true, true] 47 if numbers == [1,10,11,12,13] 48 yaku = YAKU[9] 49 else 50 yaku = YAKU[8] 51 end 52 else 53 yaku = YAKU[0] 54 end 55 puts "card:#{h}\n\nhand:#{yaku}\n\n" 56 end 57 end 58end 59 60 61def same_number_counts(numbers) 62 same_numbers = numbers.group_by{|r|r}.map(&:size).sort.reverse 63end 64 65def straight(numbers) 66 steps = numbers.sort.map{|r|r - numbers[0]} 67 steps == [0,1,2,3,4] || steps == [0,9,10,11,12] 68end 69 70def flush(suits) 71 suits.uniq.size == 1 72end 73 74def end_program 75 exit 76end 77 78def exception 79 puts "入力された値は無効です" 80end 81 82 83#メニューの表示 84while true do 85 puts "[0]役を判定する" 86 puts "[1]アプリを終了する" 87 input = gets.to_i 88 89 if input == 0 then 90 eval_hand 91 elsif input == 1 then 92 end_program 93 else 94 exception 95 end 96end

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

それを信じるかどうか、私はまた、すべての私の心を持つゲームやポーカーが大好きです。 私は数週間前にカジノを始めましたが、今ではこれが私の趣味であり、私の勝ち方です。 したがって、この場合、私はあなたが間違いなくカジノの機能の明確な説明を得ることができるさまざまなプラットフォームについて 読む をお勧めしたいと思います。 あなたも時間を過ごすのこの方法を試してみたいのであれば、私たちも知ってみましょう。

投稿2023/11/17 15:05

carlfiedler

総合スコア2

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

気の付いたバグだけ直しました。2つ目のバグはインデントがおかしいせいでしょうね。

diff

1--- old 2017-04-15 22:42:05.194114848 +0900 2+++ new 2017-04-15 22:44:32.277113159 +0900 3@@ -21,7 +21,7 @@ 4 5 hand.each do |c| 6 suits.push c[0] 7- numbers.push c[1].to_i 8+ numbers.push c[1..-1].to_i 9 end 10 11 case same_number_counts(numbers) 12@@ -49,9 +49,9 @@ 13 end 14 else 15 yaku = YAKU[0] 16+ end 17 end 18 puts "card:#{h}\n\nhand:#{yaku}\n\n" 19- end 20 end 21 end 22 23@@ -60,8 +60,9 @@ 24 same_numbers = numbers.group_by{|r|r}.map(&:size).sort.reverse 25 end 26 27-def straight(numbers) 28- steps = numbers.sort.map{|r|r - numbers[0]} 29+def straight(n) 30+ numbers = n.sort 31+ steps = numbers.map{|r|r - numbers[0]} 32 steps == [0,1,2,3,4] || steps == [0,9,10,11,12] 33 end

「どの手札が一番強いか」を判断するのに、どうしたらよいのか分からず行き詰っています…。

カンマで区切られた札の中での比較でいいんですよね。

Ruby

1def eval_hand 2 puts "文字列を入力してください(例:S8 S7 H6 H5 S4, H1 H13 H12 H11 H10)" 3 #カンマ(,)で文字列を分割し、いくつかの手札からなる配列を返す。 4 hands = gets.chomp.split(",") 5 scores = hands.map{|hand| score(hand)} 6 high_score = scores.max 7 puts "一番強いのは" 8 scores.each.with_index do |sc,i| 9 puts hands[i] if sc==high_score 10 end 11end 12def score(hand) 13 hand に対しての点数を数値で返す 14end

同点があり得るので、複数の手が表示される事があります。
同じ役の中での強弱の判断はご存じでしょうか?
例:ワンペア⇒ペアのカードが強い方。ペアのカードが同じなら、残りのカードの中の最強のカードが強い方。それも同じならその次に強いカードが強い方。それも同じなら最後のカードが強い方。それも同じなら同点。

投稿2017/04/15 14:21

otn

総合スコア84421

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

フラッシュはスートによって強さが変わるし、ワンペアは数字によって強さが変わります。
役によって違う以上、場合分けするしかないでしょう。

まずは役自体の強さで比較し、同じだった場合にそれぞれの役の比較に移るという二段階で処理してください。

投稿2017/04/15 13:56

Zuishin

総合スコア28656

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2017/04/15 14:30

> フラッシュはスートによって強さが変わるし、 それはローカルルールでしょうね。
Zuishin

2017/04/15 20:49

なるほど。ローカルルールでないものというのはどこを見ればいいんでしょうか?
Zuishin

2017/04/16 02:59

ありがとうございます。確かに私の知っているルールはメジャーなものではないようですね。 ただ、それを見るとストレートやストレートフラッシュの時だけ A の扱いが変わりますし、ローカルルールも、カジノや競技会で変わるのであれば、やはり最初から役によって場合分けするよう作るのがいいのではないかと思いました。
guest

0

やくに点数をつけてその大小を比較するというのはどうでしょうか?

Ruby

1#encoding: utf-8 2 3=begin 4ポーカーのやくはんていプログラム 5=end 6 7def PokerHand_Judge(array) 8 return "NoPair" if array.length < 2 9 10 mark = [] 11 num = [] 12 13 array.each do |element| 14 mark << element.slice!(0) 15 num << element.to_i 16 end 17 18 mark.uniq! 19 20 tmp = num.group_by{|e| e}.map{|key, val| val}.map{|e| e.length}.sort 21 22 case tmp 23 when [1, 1, 1, 2]; return "OnePair" 24 when [1, 2, 2]; return "TwoPair" 25 when [1, 1, 3]; return "ThreeOfAKind" 26 when [2, 3]; return "FullHouse" 27 when [1, 4]; return "FourOfAKind" 28 end 29 30 return "NoPair" if array.length != 5 31 32 straight = false 33 royal = false 34 35 min = num.min 36 max = num.max 37 38 if max - min <= 4 39 straight = true 40 end 41 42 if straight == false 43 min = 14 if num.min == 1 44 if max - min <= 4 45 straight = true 46 royal = true 47 end 48 end 49 50 flush = false 51 52 if mark.length == 1 53 flush = true 54 end 55 56 if royal && flush; return "RoyalStraightFlush" 57 elsif straight && flush; return "StraightFlush" 58 elsif flush; return "Flush" 59 elsif straight; return "Straight" 60 end 61 62 return "NoPair" 63end 64 65def Score(str) 66 case str 67 when "RoyalStraightFlush"; return 0 68 when "StraightFlush"; return 1 69 when "FourOfAKind"; return 2 70 when "FullHouse"; return 3 71 when "Flush"; return 4 72 when "Straight"; return 5 73 when "ThreeOfAKind"; return 6 74 when "TwoPair"; return 7 75 when "OnePair"; return 8 76 when "NoPair"; return 9 77 end 78end 79 80str = "S8 S7 H6 H5 S4 H1 H13 H12 H11 H10\n" 81 82cards = str.chomp.to_s.split("\s").each_slice(5).to_a 83 84dis = [] 85 86cards.each do |element| 87 dis << "cards:\s#{element.join(",")}" 88 answer = PokerHand_Judge(element) 89 dis << "hand:\s#{answer}" 90 dis << Score(answer) 91end 92 93dis.each_slice(3).to_a.sort_by{|e| e[2]}.each_with_index do |element, i| 94 puts element[0] 95 puts element[1] 96 if i.zero? 97 puts "best: true" 98 end 99 puts "" 100end

参考
ポーカーの役判定プログラム(C#)
私のコードは参考にしたページに書いてあるC#のコードをRubyで書き直しただけのものです。

投稿2017/04/15 09:33

編集2017/04/16 13:02
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問