Hi
This one seemed pretty easy, so I gave it a try.
My first idea was to solve the whole sorting in the <=> method of the
Card class. But it was too confusing this way, because I had to include
all possible comparisons. Also the Card itself had to know what the
trump suit was.
Then I tried a different approach. I wrote a Card#weighting method which
returned a number, for trump jack a 41, for trump color jack a 40, and
so on. Then i sorted the card array with sort_by and the weighting. But
I wasn’t satisfied yet, because again, the card had to know what suit
was trump. And the numbering was ugly, too.
So my final idea was to just implement the <=> method for sorting
without regard to trump. Then in my Hand class, which knows about the
trump, I wrote a sort! method for the sorting with regard to trump suit.
Now I’m interested to see other solutions
Robin S.
module Euchre
class Hand
attr_accessor :cards
def initialize( trump )
@cards = []
@trump = Card.new( trump )
end
def <<( card )
@cards << card
end
def sort!
@cards =
# First the trump jack..
@cards.select{ |c| trump_suit?(c) and c.jack? } |
# then the jack of the trump color..
@cards.select{ |c| trump_color?(c) and c.jack? } |
# then all the trump cards..
@cards.select{ |c| trump_suit?(c) }.sort.reverse |
# then a different color, so the colors alternate..
@cards.select{ |c| !trump_color?(c) and
c.suit =~ /d|c/ }.sort.reverse |
# then the cards with the same color as the trump..
@cards.select{ |c| trump_color?(c) }.sort.reverse |
# and finally the rest.
@cards.sort.reverse
end
def trump_suit?( card ) card.suit == @trump.suit end
def trump_color?( card ) card.color == @trump.color end
def to_s
@cards.join("\n")
end
end
class Card
attr_accessor :suit, :face
Suits = ['d', 'h', 'c', 's']
Faces = ['9', 'T', 'J', 'K', 'A']
Colors = {'d' => :red, 'h' => :red, 'c' => :black, 's' => :black}
def initialize( suit, face=nil )
@suit = suit.downcase
@face = face.upcase if face
end
def jack?() @face == 'J' end
def color() Colors[@suit] end
# Sort first by suit and then by face.
def <=>( other )
rel = Suits.index(@suit) - Suits.index(other.suit)
rel = Faces.index(@face) - Faces.index(other.face) if rel == 0
rel
end
def to_s
@face + @suit
end
end
end
if FILE == $0
lines = readlines
trump = lines.shift.slice(/\w+/)
hand = Euchre::Hand.new(trump[0,1])
lines.join.scan(/(\w)(\w)/) do |face, suit|
hand << Euchre::Card.new(suit, face)
end
hand.sort!
puts trump
puts hand
end