From: Dave Burt Date: 2005-03-23T22:19:49+09:00 Subject: Re: [SOLUTION][QUIZ] Texas Hold'Em (#24) I apologise for posting the URL incorrectly. It's really: http://www.dave.burt.id.au/ruby/poker.rb This is a pretty long project. Here are some highlights: # each hand type has a name and a function taking a hand and returning it, # sorted, or nil if the hand doesn't match this type. HandTypes = [ ['Royal Flush', proc {|hand| if hand.find_all{|c|c.value >= 10}.map(:suit).frequencies(5).size >= 1 Poker.find_straight(hand) end }], ['Straight Flush', proc {|hand| suit, count = *hand.map(:suit).frequencies(5)[0] if count && count >= 1 if straight = Poker.find_straight(hand.find_all {|card| card.suit == suit }) result = hand.dup result.delete_if {|card| straight.include?(card) } straight + result.sort_by_most_frequent(:value) end end }], ['Four of a Kind', proc {|hand| if hand.map(:value).frequencies(2).size >= 4 hand.sort_by_most_frequent :value end }], ['Flush', proc {|hand| if hand.map(:suit).frequencies(5).size >= 1 hand.sort_by_most_frequent :suit end }], ['Straight', proc {|hand| Poker.find_straight(hand) }], ['Three of a Kind', proc {|hand| if hand.map(:value).frequencies(3).size >= 1 hand.sort_by_most_frequent :value end }], ['Two Pair', proc {|hand| if hand.map(:value).frequencies(2).size >= 2 hand.sort_by_most_frequent :value end }], ['Pair', proc {|hand| if hand.map(:value).frequencies(2).size >= 1 hand.sort_by_most_frequent :value end }], ['High Card', proc {|hand| hand.sort.reverse }] ] # # Returns [n, "Hand type", ordered_cards] # The n at the front is bigger for better hands, so that # you can sort by hand_value. # def self.hand_value(cards, min_cards = 7) # self #=> Poker:Module if cards.size >= min_cards HandTypes.each_with_index do |hand_type, index| hand_match = hand_type[1].call(cards) if hand_match # return EvaluatedHand.new(hand_match, hand_type[0], [HandTypes.size - index, hand_match]) return [ HandTypes.size - index, hand_type[0], hand_match ] end end end [0, '', cards.sort_by_most_frequent(:value)] end # then it all comes together like this: hands = [] # get hands from input and evaluate them input.each do |line| hands << line.to_cards.poker_value end # determine the winner winner = hands.inject([]) do |memo, hand| [memo, hand].max end # output each hand and its value hands.each do |hand| puts "#{hand[2]} #{hand[1]} #{'(winner)' if hand == winner}" end That plus a Poker::find_straight and Array#frequencies and that's pretty much all there is to my answer. Cheers, Dave "Dave Burt" faked: > http://www.dave.burt.id.au/poker.rb > > (requires card.rb in the same directory) > > An explanation (and comments) will come later tonight. > > Cheers, > Dave