Daniel Harple wrote:
> 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'.
>>
>> - Einar
> 
> 
> 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
> 

Thanks a lot! This sort of resembles the code I've written, apart from 
all the interesting bits! :-) In particular the sorting bit, but also 
the shuffling - so much more elegant than my "manual" approach.

In general I'm interested "idiomatic programming", so I'm very much 
looking for "the Ruby way" of doing these things. In fact, I'm also 
writing the game in C#, which is the language I know best. In a way, the 
more different the implementations become, the happier I'll be.

- Einar