On Mar 8, 2006, at 3:48 PM, Einar Høst wrote:
That solution requires some_field to be ‘naturally’ ordered,
though, doesn’t it? (I’m very new to Ruby…) What if some_field
contains a string, and I want ‘Oranges’ to be sorted before
‘Apples’? Actually, I’m writing a card game, so I want ‘Spades’ <
‘Hearts’ < ‘Clubs’ < ‘Diamonds’.
As mentioned, you should use the Comparable mix-in.
class Card
include Comparable
SUITES = %w{Spade Heart Club Diamond}
VALUES = %w{Ace King Queen Jack} + (“1”…“10”).to_a.reverse
def initialize(suite, value)
@suite, @value = suite, value
end
attr_reader :suite, :value
def <=>(card)
if @suite == card.suite
VALUES.index(@value) <=> VALUES.index(card.value)
else
SUITES.index(@suite) <=> SUITES.index(card.suite)
end
end
end
and full example of a Card game skeleton:
require ‘pp’
module CardGame
class Deck
def initialize
@cards = []
Card::SUITES.each do |suite|
Card::VALUES.each { |v| @cards << Card.new(suite, v) }
end
# shuffle the deck
@cards = @cards.sort_by { rand }
end
def draw_card
@cards.pop
end
end
class Card
include Comparable
SUITES = %w{Spade Heart Club Diamond}
VALUES = %w{Ace King Queen Jack} + ("1".."10").to_a.reverse
def initialize(suite, value)
@suite, @value = suite, value
end
attr_reader :suite, :value
def <=>(card)
if @suite == card.suite
VALUES.index(@value) <=> VALUES.index(card.value)
else
SUITES.index(@suite) <=> SUITES.index(card.suite)
end
end
end
class Hand
def initialize
@cards = []
end
def <<(card)
@cards << card
@cards.sort!
@cards
end
end
end
deck = CardGame::Deck.new
hand1 = CardGame::Hand.new
hand2 = CardGame::Hand.new
Draw some cards
3.times do
hand1 << deck.draw_card
hand2 << deck.draw_card
end
pp hand1, hand2
END
– Daniel