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