On 11/18/05, Ruby Quiz <james / grayproductions.net> wrote:
> The card game of Euchre has an unusual ordering of cards in the hand.  This
> week's Ruby Quiz 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