From: Dale Martenson Date: 2005-11-21T06:07:24+09:00 Subject: Re: Euchre Hands (#55) I used to play euchre a lot in college so this was fun. It might be fun writing an entire euchre game. What I did was first think about the best test to prove my solution. If you have a completely shuffled euchre deck for a specfic trump, the entire deck would take on a known order. So I wrote four tests: require 'test/unit' require 'euchre' HEARTS_AS_TRUMP_DECK = [ 'Jh','Jd','Ah','Kh','Qh','Th','9h', 'As','Ks','Qs','Js','Ts','9s', 'Ad','Kd','Qd','Td','9d', 'Ac','Kc','Qc','Jc','Tc','9c' ] SPADES_AS_TRUMP_DECK = [ 'Js','Jc','As','Ks','Qs','Ts','9s', 'Ad','Kd','Qd','Jd','Td','9d', 'Ac','Kc','Qc','Tc','9c', 'Ah','Kh','Qh','Jh','Th','9h' ] DIAMONDS_AS_TRUMP_DECK = [ 'Jd','Jh','Ad','Kd','Qd','Td','9d', 'Ac','Kc','Qc','Jc','Tc','9c', 'Ah','Kh','Qh','Th','9h', 'As','Ks','Qs','Js','Ts','9s', ] CLUBS_AS_TRUMP_DECK = [ 'Jc','Js','Ac','Kc','Qc','Tc','9c', 'Ah','Kh','Qh','Jh','Th','9h', 'As','Ks','Qs','Ts','9s', 'Ad','Kd','Qd','Jd','Td','9d' ] class TestEuchre < Test::Unit::TestCase def setup @ed = EuchreDeck.new @eh = EuchreHand.new @ed.shuffle while( card = @ed.deal ) @eh.add_card( card ) end end def test_hearts_as_trump @eh.trump = "Hearts" assert_equal( HEARTS_AS_TRUMP_DECK, @eh.hand ) end def test_spades_as_trump @eh.trump = "Spades" assert_equal( SPADES_AS_TRUMP_DECK, @eh.hand ) end def test_diamonds_as_trump @eh.trump = "Diamonds" assert_equal( DIAMONDS_AS_TRUMP_DECK, @eh.hand ) end def test_clubs_as_trump @eh.trump = "Clubs" assert_equal( CLUBS_AS_TRUMP_DECK, @eh.hand ) end end I took the original input program and created a EuchreDeck class: class EuchreDeck def initialize # build a Euchre deck @cards = Array.new %w{9 T J Q K A}.each do |face| %w{d c s h}.each do |suit| @cards << face + suit end end end def shuffle @cards = @cards.sort_by { rand } end def deal @cards.shift end end I wrote a EuchreHand class that would take cards dealt to it and originize them by a computed card value using sort. class EuchreHand Suit = Struct.new( :suit, :alternate_suit_1, :off_suit, :alternate_suit_2 ) @@suits = { "Diamonds"=>Suit.new("d","c","h","s"), "Clubs"=>Suit.new("c","h","s","d"), "Spades"=>Suit.new("s","d","c","h"), "Hearts"=>Suit.new("h","s","d","c") } @@face_values_trump = { "J" => 6, "A" => 4, "K" => 3, "Q" => 2, "T" => 1, "9" => 0 } @@face_values_regular = { "A" => 5, "K" => 4, "Q" => 3, "J" => 2, "T" => 1, "9" => 0 } MAX_CARDS_PER_SUIT = 7 def initialize @trump = nil @hand = [] end def left_brower?( card ) card == "J#{@trump.off_suit}" end def trump?( card ) card[1].chr == @trump.suit end def trump=( suit_string ) @trump = @@suits[ suit_string ] end def trump @@suits.index(@trump) end def add_card( card ) @hand.push( card ) end def card_value( card ) face = card[0].chr suit = card[1].chr if left_brower?(card) then suit_value = @trump.to_a.reverse.index( @trump.suit ) * MAX_CARDS_PER_SUIT face_value = @@face_values_trump[ face ] - 1 elsif trump?(card) then suit_value = @trump.to_a.reverse.index( @trump.suit ) * MAX_CARDS_PER_SUIT face_value = @@face_values_trump[ face ] else suit_value = @trump.to_a.reverse.index( suit ) * MAX_CARDS_PER_SUIT face_value = @@face_values_regular[ face ] end suit_value + face_value end def hand @hand.sort {|x,y| card_value(y)<=>card_value(x) } end end Once my tests passed, I rewrote the original input program as: require 'euchre' # choose trump puts %w{Diamonds Clubs Spades Hearts}[rand(4)] ed = EuchreDeck.new ed.shuffle 5.times{ puts ed.deal } And the sort program as: require 'euchre' eh = EuchreHand.new eh.trump = gets.strip while card = gets eh.add_card( card.strip ) end puts eh.trump puts eh.hand It would be a fun to attempt to create a EuchreBot to actually play. --Dale