94 lines
1.7 KiB
Ruby
94 lines
1.7 KiB
Ruby
#!/usr/bin/env ruby
|
|
|
|
require 'card'
|
|
|
|
class Hand
|
|
def initialize(hand_string)
|
|
@cards = hand_string.scan(/../).collect { |s| Card.new(s) }.sort
|
|
end
|
|
|
|
def legal?
|
|
@cards.size == @cards.sort.uniq.size && [5,10].include?(@cards.size)
|
|
end
|
|
|
|
def illegal?
|
|
!(legal?)
|
|
end
|
|
|
|
def rank
|
|
return nil if illegal?
|
|
|
|
# array of suits, ranks
|
|
suits = @cards.collect { |c| c.suit_s }
|
|
ranks = @cards.collect { |c| c.rank }
|
|
|
|
# count of suits
|
|
suit_counts = Hash.new(0)
|
|
suits.each { |s| suit_counts[s] += 1 }
|
|
|
|
# count of ranks
|
|
rank_counts = Hash.new(0)
|
|
ranks.each { |s| rank_counts[s] += 1 }
|
|
|
|
# test for straight & flush
|
|
straight = (ranks.sort == (ranks.min .. ranks.max).to_a)
|
|
flush = (suits.sort.uniq.size == 1)
|
|
|
|
# rank hand
|
|
return :royal_flush if straight && flush && ranks.min == 10
|
|
return :straight_flush if straight && flush
|
|
return :four_of_a_kind if [1,4] == rank_counts.values.sort
|
|
return :full_house if [2,3] == rank_counts.values.sort
|
|
return :flush if flush
|
|
return :straight if straight
|
|
|
|
# nothing
|
|
nil
|
|
end
|
|
|
|
|
|
def score
|
|
r = rank
|
|
|
|
return 0 if r.nil?
|
|
|
|
# ten card hands
|
|
return 80 if @cards.size == 10 && r == :straight_flush
|
|
return 40 if @cards.size == 10 && r == :flush
|
|
return 20 if @cards.size == 10 && r == :straight
|
|
|
|
# five card hands
|
|
return 21 if r == :royal_flush
|
|
return 20 if r == :straight_flush
|
|
return 15 if r == :four_of_a_kind
|
|
return 10 if r == :full_house
|
|
return 7 if r == :flush
|
|
return 5 if r == :straight
|
|
|
|
# nothing
|
|
return 0
|
|
end
|
|
|
|
def score_name
|
|
rank.to_s.gsub(/_/,' ') if rank
|
|
end
|
|
|
|
def to_s
|
|
@cards.collect { |c| c.to_s }.join(', ')
|
|
end
|
|
|
|
def hash
|
|
to_s.hash
|
|
end
|
|
|
|
def <=>(other)
|
|
to_s <=> other.to_s
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|