Class: PokerHand
- Inherits:
-
Object
- Object
- PokerHand
- Includes:
- Comparable
- Defined in:
- lib/ruby-poker/poker_hand.rb
Constant Summary collapse
- OPS =
[ ['Royal Flush', :royal_flush? ], ['Straight Flush', :straight_flush? ], ['Four of a kind', :four_of_a_kind? ], ['Full house', :full_house? ], ['Flush', :flush? ], ['Straight', :straight? ], ['Three of a kind', :three_of_a_kind?], ['Two pair', :two_pair? ], ['Pair', :pair? ], ['Highest Card', :highest_card? ], ]
- RESOLVING_METHODS =
Resolving methods are just passed directly down to the @hand array
[:size, :+, :-]
- @@allow_duplicates =
true by default
true
Instance Attribute Summary collapse
-
#hand ⇒ Object
readonly
Returns the value of attribute hand.
Class Method Summary collapse
Instance Method Summary collapse
-
#<<(new_cards) ⇒ Object
Add a card to the hand.
- #<=>(other_hand) ⇒ Object
-
#=~(re) ⇒ Object
The =~ method does a regular expression match on the cards in this hand.
-
#by_face ⇒ Object
Returns a new PokerHand object with the cards sorted by value with the highest value first.
-
#by_suit ⇒ Object
Returns a new PokerHand object with the cards sorted by suit The suit order is spades, hearts, diamonds, clubs.
-
#delete(card) ⇒ Object
Remove a card from the hand.
-
#face_values ⇒ Object
Returns an array of the card values in the hand.
- #flush? ⇒ Boolean
- #four_of_a_kind? ⇒ Boolean
- #full_house? ⇒ Boolean
-
#hand_rating ⇒ Object
(also: #rank)
Returns the verbose hand rating.
- #highest_card? ⇒ Boolean
-
#initialize(cards = []) ⇒ PokerHand
constructor
Returns a new PokerHand object.
-
#just_cards ⇒ Object
(also: #cards)
Returns string representation of the hand without the rank.
- #pair? ⇒ Boolean
- #royal_flush? ⇒ Boolean
- #score ⇒ Object
-
#sort_using_rank ⇒ Object
Returns a string of the hand arranged based on its rank.
- #straight? ⇒ Boolean
- #straight_flush? ⇒ Boolean
- #three_of_a_kind? ⇒ Boolean
-
#to_a ⇒ Object
(also: #to_ary)
Returns an array of ‘Card` objects that make up the `PokerHand`.
-
#to_s ⇒ Object
Returns string with a listing of the cards in the hand followed by the hand’s rank.
- #two_pair? ⇒ Boolean
-
#uniq ⇒ Object
Same concept as Array#uniq.
Constructor Details
#initialize(cards = []) ⇒ PokerHand
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/ruby-poker/poker_hand.rb', line 14 def initialize(cards = []) if cards.is_a? Array @hand = cards.map do |card| if card.is_a? Card card else Card.new(card.to_s) end end elsif cards.respond_to?(:to_str) @hand = cards.scan(/\S{2,3}/).map { |str| Card.new(str) } else @hand = cards end check_for_duplicates if !@@allow_duplicates end |
Instance Attribute Details
#hand ⇒ Object (readonly)
Returns the value of attribute hand.
3 4 5 |
# File 'lib/ruby-poker/poker_hand.rb', line 3 def hand @hand end |
Class Method Details
.allow_duplicates ⇒ Object
6 |
# File 'lib/ruby-poker/poker_hand.rb', line 6 def self.allow_duplicates; @@allow_duplicates; end |
.allow_duplicates=(v) ⇒ Object
7 |
# File 'lib/ruby-poker/poker_hand.rb', line 7 def self.allow_duplicates=(v); @@allow_duplicates = v; end |
Instance Method Details
#<<(new_cards) ⇒ Object
303 304 305 306 307 308 309 310 311 312 313 314 315 |
# File 'lib/ruby-poker/poker_hand.rb', line 303 def << new_cards if new_cards.is_a?(Card) || new_cards.is_a?(String) new_cards = [new_cards] end new_cards.each do |nc| unless @@allow_duplicates raise "A card with the value #{nc} already exists in this hand. Set PokerHand.allow_duplicates to true if you want to be able to add a card more than once." if self =~ /#{nc}/ end @hand << Card.new(nc) end end |
#<=>(other_hand) ⇒ Object
294 295 296 |
# File 'lib/ruby-poker/poker_hand.rb', line 294 def <=> other_hand self.score[0].compact <=> other_hand.score[0].compact end |
#=~(re) ⇒ Object
71 72 73 |
# File 'lib/ruby-poker/poker_hand.rb', line 71 def =~ (re) re.match(just_cards) end |
#by_face ⇒ Object
44 45 46 |
# File 'lib/ruby-poker/poker_hand.rb', line 44 def by_face PokerHand.new(@hand.sort_by { |c| [c.face, c.suit] }.reverse) end |
#by_suit ⇒ Object
36 37 38 |
# File 'lib/ruby-poker/poker_hand.rb', line 36 def by_suit PokerHand.new(@hand.sort_by { |c| [c.suit, c.face] }.reverse) end |
#delete(card) ⇒ Object
322 323 324 |
# File 'lib/ruby-poker/poker_hand.rb', line 322 def delete card @hand.delete(Card.new(card)) end |
#face_values ⇒ Object
61 62 63 |
# File 'lib/ruby-poker/poker_hand.rb', line 61 def face_values @hand.map { |c| c.face } end |
#flush? ⇒ Boolean
127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/ruby-poker/poker_hand.rb', line 127 def flush? if (md = (by_suit =~ /(.)(.) (.)\2 (.)\2 (.)\2 (.)\2/)) [ [ 6, Card::face_value(md[1]), *(md[3..6].map { |f| Card::face_value(f) }) ], arrange_hand(md) ] else false end end |
#four_of_a_kind? ⇒ Boolean
94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/ruby-poker/poker_hand.rb', line 94 def four_of_a_kind? if (md = (by_face =~ /(.). \1. \1. \1./)) # get kicker (md.pre_match + md.post_match).match(/(\S)/) [ [8, Card::face_value(md[1]), Card::face_value($1)], arrange_hand(md) ] else false end end |
#full_house? ⇒ Boolean
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/ruby-poker/poker_hand.rb', line 107 def full_house? if (md = (by_face =~ /(.). \1. \1. (.*)(.). \3./)) arranged_hand = arrange_hand(md[0] + ' ' + md.pre_match + ' ' + md[2] + ' ' + md.post_match) [ [7, Card::face_value(md[1]), Card::face_value(md[3])], arranged_hand ] elsif (md = (by_face =~ /((.). \2.) (.*)((.). \5. \5.)/)) arranged_hand = arrange_hand(md[4] + ' ' + md[1] + ' ' + md.pre_match + ' ' + md[3] + ' ' + md.post_match) [ [7, Card::face_value(md[5]), Card::face_value(md[2])], arranged_hand ] else false end end |
#hand_rating ⇒ Object Also known as: rank
250 251 252 253 254 |
# File 'lib/ruby-poker/poker_hand.rb', line 250 def OPS.map { |op| (method(op[1]).call()) ? op[0] : false }.find { |v| v } end |
#highest_card? ⇒ Boolean
229 230 231 232 |
# File 'lib/ruby-poker/poker_hand.rb', line 229 def highest_card? result = by_face [[1, *result.face_values[0..4]], result.hand.join(' ')] end |
#just_cards ⇒ Object Also known as: cards
51 52 53 |
# File 'lib/ruby-poker/poker_hand.rb', line 51 def just_cards @hand.join(" ") end |
#pair? ⇒ Boolean
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/ruby-poker/poker_hand.rb', line 209 def pair? if (md = (by_face =~ /(.). \1./)) # get kicker arranged_hand = arrange_hand(md) arranged_hand.match(/(?:\S\S ){2}(\S)\S\s+(\S)\S\s+(\S)/) [ [ 2, Card::face_value(md[1]), Card::face_value($1), Card::face_value($2), Card::face_value($3) ], arranged_hand ] else false end end |
#royal_flush? ⇒ Boolean
75 76 77 78 79 80 81 |
# File 'lib/ruby-poker/poker_hand.rb', line 75 def royal_flush? if (md = (by_suit =~ /A(.) K\1 Q\1 J\1 T\1/)) [[10], arrange_hand(md)] else false end end |
#score ⇒ Object
258 259 260 261 262 263 264 265 266 267 |
# File 'lib/ruby-poker/poker_hand.rb', line 258 def score # OPS.map returns an array containing the result of calling each OPS method again # the poker hand. The non-nil cell closest to the front of the array represents # the highest ranking. # find([0]) returns [0] instead of nil if the hand does not match any of the rankings # which is not likely to occur since every hand should at least have a highest card OPS.map { |op| method(op[1]).call() }.find([0]) { |score| score } end |
#sort_using_rank ⇒ Object
275 276 277 |
# File 'lib/ruby-poker/poker_hand.rb', line 275 def sort_using_rank score[1] end |
#straight? ⇒ Boolean
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/ruby-poker/poker_hand.rb', line 142 def straight? result = false if hand.size >= 5 transform = delta_transform # note we can have more than one delta 0 that we # need to shuffle to the back of the hand i = 0 until transform.match(/^\S{3}( [1-9x]\S\S)+( 0\S\S)*$/) or i >= hand.size do # only do this once per card in the hand to avoid entering an # infinite loop if all of the cards in the hand are the same transform.gsub!(/(\s0\S\S)(.*)/, "\\2\\1") # moves the front card to the back of the string i += 1 end if (md = (/.(.). 1.. 1.. 1.. 1../.match(transform))) high_card = Card::face_value(md[1]) arranged_hand = fix_low_ace_display(md[0] + ' ' + md.pre_match + ' ' + md.post_match) result = [[5, high_card], arranged_hand] end end end |
#straight_flush? ⇒ Boolean
83 84 85 86 87 88 89 90 91 92 |
# File 'lib/ruby-poker/poker_hand.rb', line 83 def straight_flush? if (md = (/.(.)(.)(?: 1.\2){4}/.match(delta_transform(true)))) high_card = Card::face_value(md[1]) arranged_hand = fix_low_ace_display(md[0] + ' ' + md.pre_match + ' ' + md.post_match) [[9, high_card], arranged_hand] else false end end |
#three_of_a_kind? ⇒ Boolean
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/ruby-poker/poker_hand.rb', line 163 def three_of_a_kind? if (md = (by_face =~ /(.). \1. \1./)) # get kicker arranged_hand = arrange_hand(md) arranged_hand.match(/(?:\S\S ){3}(\S)\S (\S)/) [ [ 4, Card::face_value(md[1]), Card::face_value($1), Card::face_value($2) ], arranged_hand ] else false end end |
#to_a ⇒ Object Also known as: to_ary
Returns an array of ‘Card` objects that make up the `PokerHand`.
288 289 290 |
# File 'lib/ruby-poker/poker_hand.rb', line 288 def to_a @hand end |
#to_s ⇒ Object
283 284 285 |
# File 'lib/ruby-poker/poker_hand.rb', line 283 def to_s just_cards + " (" + + ")" end |
#two_pair? ⇒ Boolean
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/ruby-poker/poker_hand.rb', line 182 def two_pair? # \1 is the face value of the first pair # \2 is the card in between the first pair and the second pair # \3 is the face value of the second pair if (md = (by_face =~ /(.). \1.(.*?) (.). \3./)) # to get the kicker this does the following # md[0] is the regex matched above which includes the first pair and # the second pair but also some cards in the middle so we sub them out # then we add on the cards that came before the first pair, the cards # that were in-between, and the cards that came after. arranged_hand = arrange_hand(md[0].sub(md[2], '') + ' ' + md.pre_match + ' ' + md[2] + ' ' + md.post_match) arranged_hand.match(/(?:\S\S ){4}(\S)/) [ [ 3, Card::face_value(md[1]), # face value of the first pair Card::face_value(md[3]), # face value of the second pair Card::face_value($1) # face value of the kicker ], arranged_hand ] else false end end |