# Euchre Hands (#55)

**URL:** <https://www.ruby-forum.com/t/euchre-hands-55/79954>\
**Category:** Ruby\
**Created:** [November 18, 2005, 2:33pm UTC](https://www.ruby-forum.com/t/euchre-hands-55/79954 "2005-11-18T14:33:00Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![james](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/bc8723/32.png) [@james](https://www.ruby-forum.com/u/james)\
**Post date:** [November 18, 2005, 2:33pm UTC](https://www.ruby-forum.com/t/euchre-hands-55/79954/1 "2005-11-18T14:33:00Z")

</div>

The three rules of Ruby Q.:

1. Please do not post any solutions or spoiler discussion for this quiz  
until  
48 hours have passed from the time on this message.

2. Support Ruby Q. by submitting ideas as often as you can:

[http://www.rubyquiz.com/](http://www.rubyquiz.com/)

1. Enjoy!

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

The card game of Euchre has an unusual ordering of cards in the hand.  
This  
week’s Ruby Q. is to take a random Euchre hand and sort it.

The first thing you need to know is that Euchre is played with a small  
deck of  
cards. Four suits are used Diamonds (d), Clubs (c), Spades (s), and  
Hearts (h),  
but each suit has only the cards Nine (9), Ten (T), Jack (J), Queen (Q),  
King  
(K), and Ace (A). The cards are generally ordered as I just listed  
them, Nine  
being the low card and Ace the high card. The exception is the  
“Bowers”.

When a Euchre hand is started, the first task is to select a Trump suit.  
How  
that’s done is not important, just know that one suit is always  
different from  
the rest. Trump is the best suit, valued higher than the other three  
suits  
(which are basically equal). In the Trump suit, the card order changes.

The first oddity of Trump is that the Jack of the selected suit becomes  
the  
Right Bower, the highest ranked Trump card. The second oddity is that  
the other  
Jack of the same color (Diamonds and Hearts are red while Clubs and  
Spades are  
black) becomes the Left Bower, the second highest Trump card. This card  
is  
considered to be of the Trump suit for the rest of the hand. For  
example, if  
Spades is selected as Trump, the order of Spades becomes (lowest to  
highest):  
9s, Ts, Qs, Ks, As, Jc, and Js. All other suits run Nine to Ace, save  
that  
Clubs will be short a Jack.

The three non-Trump suits are equal, but it is good interface to sort  
the by  
suit alternating red, black, red, and black, I think. Especially with a  
GUI,  
this makes it easier to understand the hand.

Input (on STDIN) will be a line containing the Trump suit, followed by  
five  
lines containing a Euchre hand. For example:

Diamonds  
Kc  
Jh  
Kd  
Td  
Ah

Your script should output (to STDOUT) the Trump suit, followed by the  
cards in  
sorted order (highest card first):

Diamonds  
Jh  
Kd  
Td  
Kc  
Ah

Here’s a script that will feed your program random hands:

#!/usr/local/bin/ruby -w

# 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

# choose trump

puts %w{Diamonds Clubs Spades Hearts}[rand(4)]

# deal a hand

cards = cards.sort\_by { rand }  
puts cards[0…4]

One last thought: If accuracy is our ultimate goal here, how will you  
know your  
output is correct?

---

<div class="post-metadata">

**Author:** ![james](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/bc8723/32.png) [@james](https://www.ruby-forum.com/u/james)\
**Post date:** [November 19, 2005, 8:32pm UTC](https://www.ruby-forum.com/t/euchre-hands-55/79954/2 "2005-11-19T20:32:40Z")

</div>

On 18/11/05, Ruby Q. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Spades is selected as Trump, the order of Spades becomes (lowest to highest):  
> Diamonds  
> Jh  
> cards = Array.new  
> cards = cards.sort\_by { rand }  
> puts cards[0…4]
> 
> One last thought: If accuracy is our ultimate goal here, how will you know your  
> output is correct?

Hello James,

I have to admit that I do not totally understand. Why is in the  
example the King of Clubs higher than the Ace of hearts. I thought an  
Ace would be higher than a King and Clubs and Hearts are equal except  
for the Jack if the trump is Diamond.

And secondly I do not understand the paragraph about the red-black sort  
order.

cheers,

## Brian

[http://ruby.brian-schroeder.de/](http://ruby.brian-schroeder.de/)

Stringed instrument chords: [http://chordlist.brian-schroeder.de/](http://chordlist.brian-schroeder.de/)

---

<div class="post-metadata">

**Author:** ![james](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/bc8723/32.png) [@james](https://www.ruby-forum.com/u/james)\
**Post date:** [November 19, 2005, 8:50pm UTC](https://www.ruby-forum.com/t/euchre-hands-55/79954/3 "2005-11-19T20:50:17Z")

</div>

On Nov 19, 2005, at 1:31 PM, Brian Schröder wrote:

> > Your script should output (to STDOUT) the Trump suit, followed by  
> > the cards in  
> > sorted order (highest card first):
> > 
> > ```
> > Diamonds
> > Jh
> > Kd
> > Td
> > Kc
> > Ah
> > 
> > ```

> Hello James,

Hello Brian.

> I have to admit that I do not totally understand.

That’s probably just my terrible explination. Let’s see if I can  
clear it up…

> Why is in the example the King of Clubs higher than the Ace of hearts.

Cards are sorted first buy suit, then by value. Trump is a better  
suit then the rest, but the others are equal and can come in any  
order. The suit order above is Diamonds (Trump), Clubs, then  
Hearts. Inside those suits, cards are sorted by face value.

> And secondly I do not understand the paragraph about the red-black  
> sort order.

Technically, this is another (correct) answer to the above:

```
Diamonds
Jh
Kd
Td
Ah
Kc

```

The cards are still sorted in order of value. However, now we have  
put the red suits together. I think it’s better to break them up,  
when we can. That’s why my example shows Clubs between the two suits.

Does that help?

James Edward G. II

---

<div class="post-metadata">

**Author:** ![james](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/bc8723/32.png) [@james](https://www.ruby-forum.com/u/james)\
**Post date:** [November 19, 2005, 8:58pm UTC](https://www.ruby-forum.com/t/euchre-hands-55/79954/4 "2005-11-19T20:58:55Z")

</div>

On 19/11/05, James Edward G. II [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > ```
> > > Kc
> > > 
> > > ```
> 
> > Why is in the example the King of Clubs higher than the Ace of hearts.
> 
> Cards are sorted first buy suit, then by value. Trump is a better  
> suit then the rest, but the others are equal and can come in any  
> order. The suit order above is Diamonds (Trump), Clubs, then  
> Hearts. Inside those suits, cards are sorted by face value.

Now I understand. I always sort my cards first by value then by suite.  
That was the problem.

cheers,

Brian

> > [snip]
> 
> Does that help?

Yes

> James Edward G. II

–  
[http://ruby.brian-schroeder.de/](http://ruby.brian-schroeder.de/)

Stringed instrument chords: [http://chordlist.brian-schroeder.de/](http://chordlist.brian-schroeder.de/)

---

<div class="post-metadata">

**Author:** ![james](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/bc8723/32.png) [@james](https://www.ruby-forum.com/u/james)\
**Post date:** [November 20, 2005, 4:20pm UTC](https://www.ruby-forum.com/t/euchre-hands-55/79954/5 "2005-11-20T16:20:18Z")

</div>

On 11/18/05, Ruby Q. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> The card game of Euchre has an unusual ordering of cards in the hand. This  
> week’s Ruby Q. is to take a random Euchre hand and sort it.

Hmm. My original solution was to assign integer values to each card  
and suit, and sort\_by that mapping.

#!/usr/bin/ruby -w

NUMS = %w(9 T J Q K A)  
SUITS = %w(h c d s)  
COLOURS = Hash[\*%w(s B d R c B h R)]

def card\_value(card, trump)  
num, suit = card.split(‘’)

```
value = NUMS.index(num)
value += 10 * SUITS.index(suit)
if num == 'J'
	value += 150 if COLOURS[suit] == COLOURS[trump]
	value += 10 if suit == trump
elsif suit == trump
	value += 100
end

return value

```

end

trump = gets.chomp  
tsuit = trump[0,1].downcase

puts trump  
puts $stdin.readlines.sort\_by { |card| -card\_value(card,tsuit) }

When I started to think about it though, that seemed a little silly to  
me. If you ever use more than ten numbers, or more than 5 cards,  
things start to get messy and sneaky bugs pop up. I realised that what  
I was really doing was creating an array of base-10 numbers to  
represent the cards. Why not just create an actual array and be done  
with it?

So, here’s my version 2:

#!/usr/bin/ruby -w

NUMS = %w(9 T J Q K A)  
SUITS = %w(h c d s)  
COLOURS = Hash[\*%w(s B d R c B h R)]

def card\_value(card, trump)  
num, suit = card.split(‘’)

```
value = Array.new

value << (num == 'J' && value[3] == 1 ? 1 : 0)
value << (num == 'J' && COLOURS[suit] == COLOURS[trump] ? 1 : 0)
value << (suit == trump ? 1 : 0)
value << SUITS.index(suit)
value << NUMS.index(num)

```

end

trump = gets.chomp  
tsuit = trump[0,1].downcase

puts trump  
puts $stdin.readlines.sort\_by { |card| card\_value(card,tsuit) }.reverse

Though, incidentally, I’m not sure how the performance of the two  
would compare. I also wish I could think of a neater way to include  
those boolean values than the ? 1 : 0 thing. I considered defining \<=\>  
for TrueClass and FalseClass, but thought that might be a little icky.

Sam

---

<div class="post-metadata">

**Author:** ![james](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/bc8723/32.png) [@james](https://www.ruby-forum.com/u/james)\
**Post date:** [November 21, 2005, 3:29am UTC](https://www.ruby-forum.com/t/euchre-hands-55/79954/6 "2005-11-21T03:29:43Z")

</div>

I seriously debated with myself whether it was worth submitting my  
solution. It takes a whole 100 lines of code! I decided in the end that  
I would post it anyway.

I made the opposite decision to Robin S. and decided to stick with  
the \<=\> approach. The cards do have to know about the trump suit, but  
the deck class automatically handles that.

Here it is:

class Card  
@@values = {‘A’ =\> :ace, ‘K’ =\> :king, ‘Q’ =\> :queen, ‘J’ =\> :jack,  
‘T’ =\> :ten, ‘9’ =\> :nine}  
@@value\_values = {:ace =\> 6, :king =\> 5, :queen =\> 4, :jack =\> 3, :ten  
=\> 2, :nine =\> 1}  
@@suits = {‘h’ =\> :hearts, ‘d’ =\> :diamonds, ‘c’ =\> :clubs, ‘s’ =\>  
:spades}  
@@suit\_values = {:hearts =\> 2, :diamonds =\> -2, :clubs =\> 1, :spades  
=\> -1}

```
# The suit_values is used to compactly calculate the order suits

```

should be sorted in

```
def initialize(string = "Jh", trump = :hearts)
	@suit = :hearts
	@value = :ace
	@trump = trump
	if string
		self.parse(string)
	end
end

def parse(string)
	cardarray = string.upcase.scan(/[AKQJT9][HDCS]/)
	if cardarray.length > 0
		@value = @@values[cardarray[0][0,1]]
		@suit = @@suits[(cardarray[0][1,1]).downcase]
	end
end

def rank_value
	case @suit
		when @trump
			return @value == :jack ? 40 : (@@value_values[@value] + 30)
		when @@suit_values.index(@@suit_values[@trump] * -1)
		# True when card is of the trump's suit's colour companion
			return @value == :jack ? 39 : (@@value_values[@value] + 10)
		when @@suit_values.index((@@suit_values[@trump] % 2) + 1)
		# Triggers for clubs if trump is red or hearts if trump is black
			return @@value_values[@value] + 20
		else
		# The last remaining suit comes last
			return @@value_values[@value]
	end
end

def <=>(other)
	self.rank_value <=> other.rank_value
end

def printable
	@@values.index(@value) + @@suits.index(@suit)
end

include Comparable

attr_accessor :trump, :value, :suit

```

end

class Hand  
def initialize(trump = :hearts, \*cards)  
@cards = Array.new  
@trump = trump  
cards.each do |cs|  
@cards \<\< Card.new(cs, trump)  
end  
@cards.sort!  
end

```
def add_card(card)
	@cards << Card.new(card, @trump)
end

def display
	@cards.sort!
	@cards.reverse.each do |card|
		puts card.printable
	end
end

def inspect
	handstring = String.new
	@cards.each do |card|
		handstring << card.printable << ', '
	end
	handstring.chop!
	handstring.chop!
end

def trump=(newtrump)
	@trump = newtrump
	@cards.each {|c| c.trump = newtrump}
end

attr_accessor :cards
attr_reader :trump

```

end

if **FILE** == $0

```
until (trumpline = readline()) != ""
end

case trumpline.downcase[0,1]
	when 'h'
		trump = :hearts
	when 'd'
		trump = :diamonds
	when 'c'
		trump = :clubs
	when 's'
		trump = :spades
	else
		raise StandardError, "Bad Input"
end

h = Hand.new(trump)

5.times do |t|
	cardline = readline()
	h.add_card(cardline)
end

puts trump.to_s.capitalize
h.display

```

end
