class Hand

Constants

RANKS

Attributes

cards[R]

Public Class Methods

new(cards) click to toggle source
# File lib/rpoker/hand.rb, line 16
def initialize(cards)
  @cards = parse_cards(cards)

  validate_cards!
end

Public Instance Methods

<=>(other_hand) click to toggle source
# File lib/rpoker/hand.rb, line 22
def <=>(other_hand)
  Matchup.new(self, other_hand).winner
end
card_ranks() click to toggle source
# File lib/rpoker/hand.rb, line 42
def card_ranks
  cards.map(&:rank)
end
card_suits() click to toggle source
# File lib/rpoker/hand.rb, line 38
def card_suits
  cards.map(&:suit)
end
card_values() click to toggle source
# File lib/rpoker/hand.rb, line 46
def card_values
  wheel? ? [5,4,3,2,1] : cards.map(&:to_i)
end
display() click to toggle source
# File lib/rpoker/hand.rb, line 34
def display
  puts cards.join(" ")
end
flush?() click to toggle source
# File lib/rpoker/hand.rb, line 54
def flush?
  card_suits.uniq.size == 1
end
form() click to toggle source
# File lib/rpoker/hand.rb, line 88
def form
  @form ||= compute_form
end
four_of_a_kind?() click to toggle source
# File lib/rpoker/hand.rb, line 68
def four_of_a_kind?
  form == :AAAAx
end
full_house?() click to toggle source
# File lib/rpoker/hand.rb, line 72
def full_house?
  form == :AAABB
end
pair?() click to toggle source
# File lib/rpoker/hand.rb, line 84
def pair?
  form == :AAxxx
end
rank() click to toggle source
# File lib/rpoker/hand.rb, line 26
def rank
  @rank ||= RANKS.find { |rank| send("#{rank}?") } || :high_card
end
rank_idx() click to toggle source
# File lib/rpoker/hand.rb, line 30
def rank_idx
  RANKS.index(rank) || RANKS.size
end
sort!() click to toggle source

sort cards by their rank multiplicity in descending order e.g. sort 2s Jh 4s Js 2c as Jh Js 2s 2c 4s

# File lib/rpoker/hand.rb, line 94
def sort!
  @cards.sort_by! { |card| [-card_rank_to_count[card.rank], -card.to_i] }
end
straight?() click to toggle source
# File lib/rpoker/hand.rb, line 58
def straight?
  return true if wheel?
  sorted_values = card_values.sort
  sorted_values.last - sorted_values.first == 4 && form == :xxxxx
end
straight_flush?() click to toggle source
# File lib/rpoker/hand.rb, line 50
def straight_flush?
  flush? && straight?
end
three_of_a_kind?() click to toggle source
# File lib/rpoker/hand.rb, line 76
def three_of_a_kind?
  form == :AAAxx
end
two_pair?() click to toggle source
# File lib/rpoker/hand.rb, line 80
def two_pair?
  form == :AABBx
end
wheel?() click to toggle source
# File lib/rpoker/hand.rb, line 64
def wheel?
  card_ranks.sort == %w(A 2 3 4 5).sort
end

Private Instance Methods

card_rank_to_count() click to toggle source
# File lib/rpoker/hand.rb, line 100
def card_rank_to_count
  @card_rank_to_count ||=
    card_ranks.each_with_object(Hash.new(0)) { |v, hsh| hsh[v] += 1 }
end
check_for_duplicates!() click to toggle source
# File lib/rpoker/hand.rb, line 132
def check_for_duplicates!
  if duplicates?
    raise ArgumentError, 'A hand cannot contain duplicate cards'
  end
end
compute_form() click to toggle source
# File lib/rpoker/hand.rb, line 105
def compute_form
  card_rank_counts      = card_rank_to_count.values.sort.reverse
  counts_for_duplicates = card_rank_counts.select { |c| c > 1 }

  counts_for_duplicates.zip(['A', 'B'])
    .map { |count, letter| letter * count }.join.ljust(5, 'x').to_sym
end
duplicates?() click to toggle source
# File lib/rpoker/hand.rb, line 138
def duplicates?
  cards.map(&:to_s).uniq.size < 5
end
parse_cards(cards) click to toggle source
# File lib/rpoker/hand.rb, line 113
def parse_cards(cards)
  case cards
  when Array  then cards.map { |card| card.is_a?(Card) ? card : Card.new(card) }
  when String then cards.split(' ').map { |s| Card.new(s) }
  else raise ArgumentError, 'Input must be a string or array'
  end
end
validate_cards!() click to toggle source
# File lib/rpoker/hand.rb, line 121
def validate_cards!
  validate_length!
  check_for_duplicates!
end
validate_length!() click to toggle source
# File lib/rpoker/hand.rb, line 126
def validate_length!
  unless cards.size == 5
    raise ArgumentError, 'A hand must contain 5 cards'
  end
end