#!/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