Class: HandRepository
- Inherits:
-
Object
- Object
- HandRepository
- Includes:
- Singleton
- Defined in:
- lib/rora/repository/hand_repository.rb
Constant Summary collapse
- HEART_FLUSH =
32
- DIAMOND_FLUSH =
243
- SPADE_FLUSH =
3125
- CLUB_FLUSH =
16807
Instance Method Summary collapse
- #evaluate_5_card_hand(cards) ⇒ Object
- #evaluate_7_card_hand(cards) ⇒ Object
- #has_flush?(key) ⇒ Boolean
-
#initialize ⇒ HandRepository
constructor
A new instance of HandRepository.
-
#list(arguments = nil) ⇒ Object
Returns all possible poker hands.
-
#list_and_group_by_hand_score(arguments = nil) ⇒ Object
Returns unique poker hands.
Constructor Details
#initialize ⇒ HandRepository
Returns a new instance of HandRepository.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/rora/repository/hand_repository.rb', line 12 def initialize @hands = Array.new @five_card_table = Hash.new CSV.foreach("lib/rora/5-card-hands.csv") do |row| @five_card_table[row[1].to_i] = [row[0].to_i, row[3], row[4]] end @seven_card_table = Hash.new CSV.foreach("lib/rora/7-card-hands.csv") do |row| @seven_card_table[row[1].to_i] = [row[0].to_i, row[4], row[5]] end @flushes_table = Hash.new CSV.foreach("lib/rora/flushes.csv") do |row| @flushes_table[row[0].to_i] = [row[1].to_i, row[2]] end end |
Instance Method Details
#evaluate_5_card_hand(cards) ⇒ Object
31 32 33 34 |
# File 'lib/rora/repository/hand_repository.rb', line 31 def evaluate_5_card_hand(cards) flush = Hand.new(cards).flush? @five_card_table.fetch(cards.inject(1) {|product, card| product * card.rank.id} * (flush ? 67 : 1)) end |
#evaluate_7_card_hand(cards) ⇒ Object
36 37 38 39 40 |
# File 'lib/rora/repository/hand_repository.rb', line 36 def evaluate_7_card_hand(cards) key = generate_suit_key(cards) flush = has_flush?(key) flush ? get_best_hand(cards, key) : @seven_card_table.fetch(cards[0].rank.id * cards[1].rank.id * cards[2].rank.id * cards[3].rank.id * cards[4].rank.id * cards[5].rank.id * cards[6].rank.id) end |
#has_flush?(key) ⇒ Boolean
42 43 44 |
# File 'lib/rora/repository/hand_repository.rb', line 42 def has_flush?(key) key % HEART_FLUSH == 0 || key % DIAMOND_FLUSH == 0 || key % SPADE_FLUSH == 0 || key % CLUB_FLUSH == 0 end |
#list(arguments = nil) ⇒ Object
Returns all possible poker hands.
No Arguments If no arguments are provided, this method will return all 2,598,960 (52c5) poker hands.
Starting Hand If a starting hand is provided as an argument, this method returns all poker hands that can be made with the given starting hand. A standard deck of 52 cards is assumed. Exactly 19,600 (50c3) 5-card poker hands will be returned for any given starting hand.
Starting Hand and Deck If a deck is provided along with a starting hand, this method will return all poker hands that can be made with the given starting hand and cards that remain in the deck.
Starting Hand and Board If a board is provided along with a starting hand, this method will return all poker hands that can be made with the given starting hand and board. In this scenario, a standard deck of 52 cards is assumed. A deck will contain exactly 50 cards after the starting hand has been dealt. The deck will contain 47 cards after the flop, 46 cards after the turn and 45 cards after the river.
Once the community cards have been dealt, there are 21 (7c5) ways to choose a 5-card poker hand from the 5 community cards and 2 hole cards. The total number of hands that will be returned from this method are as follows:
If the board has 5 community cards, flop turn & river have been dealt: 21 hands -> 21 (7c5) # 1 (45c0)
If the board has 4 community cards, flop and turn have been dealt: 966 hands -> 21 (7c5) # 46 (46c1)
If the board has 3 community cards, flop has been dealt: 22701 hands -> 21 (7c5) # 1081 (47c2)
Starting Hand, Board and Deck This method will return all poker hands that can be made with the given starting hand and cards that remain in the deck.
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/rora/repository/hand_repository.rb', line 88 def list(arguments=nil) return all_hands if arguments.nil? || arguments[:starting_hand].nil? starting_hand = arguments[:starting_hand] deck = arguments[:deck].nil? ? Deck.new : arguments[:deck] board = arguments[:board] spec_hands = Array.new if !board.nil? raise RuntimeError if board.contains_any? starting_hand.cards if board.cards.size == 5 (board.cards + starting_hand.cards).combination(5).to_a.each { |cards| spec_hands << Hand.new(cards) } else deck.remove(starting_hand).remove(board).combination(5 - board.cards.size).to_a.each do |cards| (starting_hand.cards + board.cards + cards).combination(5).to_a.each { |cds| spec_hands << Hand.new(cds) } end end return spec_hands end deck.remove(starting_hand).combination(3).each { |cards| spec_hands << Hand.new(cards + starting_hand.cards) } spec_hands end |
#list_and_group_by_hand_score(arguments = nil) ⇒ Object
Returns unique poker hands.
While there are over 2.5 million distinct poker hands, many of these hands have the same value in poker. To elaborate on this a bit, consider the number of hands a player could have containing a pair of fours with a 10-7-6 kicker:
4♣ 4♦ 6♠ 7♥ 10♥ 4♠ 4♦ 6♠ 7♥ 10♥ 4♥ 4♦ 6♠ 7♥ 10♥ 4♣ 4♠ 6♠ 7♥ 10♥ 4♣ 4♦ 6♠ 7♥ 10♦ 4♣ 4♦ 6♠ 7♦ 10♥ 4♣ 4♦ 6♣ 7♥ 10♥ 4♣ 4♦ 6♠ 7♠ 10♥ 4♣ 4♦ 6♠ 7♦ 10♠ 4♣ 4♦ 6♣ 7♥ 10♣
This list goes on much further - in fact, there are exactly 768 distinct hand combinations that contain of exactly one pair of fours with a 10-7-6 kicker. Each of these 768 hands has the same hand value, or score.
This exercise demonstrates that the number of unique hands (that is, hands that share an identical hand score) is significantly lower than the number of distinct hands. This is because card suits don’t tend to affect the score of a hand (the only exception being a flush).
This method carries the same semantics as the list method, but returns unique hands instead of every possible hand.
139 140 141 142 143 144 145 146 147 148 |
# File 'lib/rora/repository/hand_repository.rb', line 139 def list_and_group_by_hand_score(arguments=nil) spec_hands = list(arguments) return spec_hands if spec_hands.nil? || spec_hands.size == 0 hash = Hash.new spec_hands.each do |hand| hash[(hand.cards.inject(1) {|product, card| product * card.rank.id } * (hand.flush? ? 67 : 1))] = hand end hash.values end |