# Euchre Hands (#55)

**URL:** <https://www.ruby-forum.com/t/euchre-hands-55/102075>\
**Category:** Ruby\
**Created:** [November 24, 2005, 4:26pm UTC](https://www.ruby-forum.com/t/euchre-hands-55/102075 "2005-11-24T16:26:23Z")\
**Posts on this page:** 3\
**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 24, 2005, 4:26pm UTC](https://www.ruby-forum.com/t/euchre-hands-55/102075/1 "2005-11-24T16:26:23Z")

</div>

My wife can’t stand how Euchre reorders the suits. “Everyone know Jacks  
come  
after Tens,” she would say. Funny how most of us except the odd Ace  
concept  
where the low card is frequently the high card, or even both. Once you  
start  
moving Jacks though, a lot of people have trouble following the game.

Of course, my wife would also say, “How can you call that Jack a Club  
(assuming  
Clubs are Trump), when it has Spades printed on it?” She’s got me  
there.

My wife’s analysis of Euchre’s card order is really right on: It’s  
unusual.  
Because of that, the traditional sort() tool won’t get you all the way  
to a  
solution. That makes us think about other options.

Don’t get me wrong, many solutions bent sort() to their will. However,  
as I  
said in the quiz, I was looking as much at how to know the answer is  
correct as  
I was at just having an answer. To me, the weighted sorts are hard to  
prove and  
no one did it to my satisfaction. Given that, I want to look at the  
other major  
approach people hit on.

The following is the beginning of Bob S.'s solution:

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

# Euchre hand sorter

CARDS = %w(A K Q J T 9)
suits = %w(Spades Hearts Clubs Diamonds)

# read and check input data
trump = gets.chomp
raise "Invalid Trump Suit" unless suits.include? trump
hand = []
5.times do
  card = gets.chomp
  raise "Invalid card #{card}" unless
    card.length == 2 &&
    CARDS.include?(card[0,1]) &&
    suits.find { |suit| suit[0,1].downcase == card[1,1] }
  raise "Duplicate card #{card}" if hand.include? card
  hand << card
end

# ...

```

Bob begins by defining the traditional card order, and the four suits.

The next chunk of code reads the trump suit and hand into variables.  
This code  
is careful to ensure proper input. Suits must be one of the known four  
and  
cards must be two characters, have a known face and suit, and not be  
duplicated.

```
# ...

# rotate trump suit to front
suits.push(suits.shift) while suits.first != trump

# if hand is void in second suit, swap second and fourth
# (this keeps output in alternating colors)
unless hand.find { |card| card[1,1] == suits[1][0,1].downcase }
  suits[1], suits[3] = suits[3], suits[1]
end

# ...

```

This chunk of code does two things. First, the suits are “rotated”  
until trump  
is the first suit. Note that this is why “CARDS” was declared as a  
constant but  
“suits” is just a variable. Good hints for the reader in this code.

The second thing the code does is the trick many hit on to defeat my  
extra  
red/black requirement. If we have four suits ordered red, black, red,  
black (or  
black, red, black, red), the only edge case we can do anything about is  
when the  
player doesn’t have the second suit. Here’s the mapping of possible  
orderings  
(assuming Spades is trump) to show what I mean:

```
all four suits (black, red, black, red ordering works 

```

fine)

```
Spades, Hearts, and Clubs (already correct)
Hearts, Clubs, and Diamonds (already correct)
Spades, Hearts, and Diamonds (can't move trump to fix)
Spades, Clubs, and Diamonds (the fixable case)

just two suits (moves won't change anything)
a single suit (already correct)

```

In the fixable case, swapping the (missing) second and (present) fourth  
suits  
resolves the issue. That’s what you’re seeing in the code above.

```
# ...

# generate a sort order
deck = []
suits.each do |suit|
  CARDS.each do |card|
    deck << card + suit[0,1].downcase
  end
end

# ...

```

Given that the correct suit order has been established, the entire  
Euchre deck  
is built, in traditional card order.

```
# ...

# move bowers to front
deck.insert(0, deck.delete_at(3))
deck.insert(1, deck.delete_at(15))

# ...

```

With the full deck in proper suit order, the only thing that remains is  
to shift  
the bowers to the head of the pack. Their location is assured, thus the  
use of  
magic numbers above, though index() is an alternative.

```
# ...

# output sorted hand (n.b. Array#& (intersection) seemed to work, but
# is the order guaranteed?)
puts trump
puts deck.select { |card| hand.include? card }

```

With the work out of the way, showing the results is trivial. Print  
trump and  
then just walk the deck printing any card in the hand.

I think that solution is very straight-forward and easy to accept as  
correct,  
even without a large group of tests. Let’s look at one more variation  
of the  
same theme, by Dominik B.:

```
order = {
    "Spades" => "JsJcAsKsQsTs9sAdKdQdJdTd9dAcKcQcTc9cAhKhQhJhTh9h",
    "Hearts" => "JhJdAhKhQhTh9hAsKsQsJsTs9sAdKdQdTd9dAcKcQcJcTc9c",
    "Clubs" => "JcJsAcKcQcTc9cAhKhQhJhTh9hAsKsQsTs9sAdKdQdJdTd9d",
    "Diamonds" => "JdJhAdKdQdTd9dAcKcQcJcTc9cAhKhQhTh9hAsKsQsJsTs9s"
}

trump = gets.strip
cards = readlines.map { |l| l.strip }
o = order[trump].dup
# do we have a card of the 2nd suit
unless cards.any? { |card| card[1] == o[15] }
    # if not replace second suit by the last
    o[14, 12] = o[36, 12]
end
puts trump, cards.sort_by { |card| o.index(card) }

```

This is basically the same thing, with prebuilt decks. The code here  
just  
selects which of the four possible decks to use base on the trump  
indication in  
the input.

Again we see the second and fourth suits swapped, if needed. This time  
it is  
done with a simple String copy.

Finally, cards are sorted, by their position in the complete deck.

My thanks to all the card sharks who solved the quiz and even taught me  
alternate hand ordering schemes.

Tomorrow we’re off to the Pinewood Derby, so everyone pick up a car kit  
sometime  
this evening…

---

<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 24, 2005, 4:50pm UTC](https://www.ruby-forum.com/t/euchre-hands-55/102075/2 "2005-11-24T16:50:35Z")

</div>

Ruby Q. wrote:

> # rotate trump suit to front
> 
> suits.push(suits.shift) while suits.first != trump
> 
> …First, the suits are “rotated” until trump  
> is the first suit. Note that this is why “CARDS” was declared as a constant but  
> “suits” is just a variable. Good hints for the reader in this code.

Having much to learn, I have since discovered that it works fine even if  
SUITS is declared as a constant. You only get a warning if you reassign  
something else to SUITS; you can maniuplate the array that SUITS  
references without getting a warning.

---

<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 24, 2005, 5:01pm UTC](https://www.ruby-forum.com/t/euchre-hands-55/102075/3 "2005-11-24T17:01:26Z")

</div>

bob\_showalter wrote:

> Having much to learn, I have since discovered that it works fine even if  
> SUITS is declared as a constant. You only get a warning if you reassign  
> something else to SUITS; you can maniuplate the array that SUITS  
> references without getting a warning.

Yes, but I think it was more correct as is, since it showed that it was  
a variable and could change.

James Edward G. II
