Chris Braddock on 21 Nov 2005 23:55:08 -0000


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: [PhillyOnRails] a little hold 'em code ... help please


Minor ruby idiom as you asked for feedback =)

Absolutely - just the kind of stuff I'm interested in - thanks.


A Ruby/OO noob could use a little help here.

I saw the Hold 'Em trainer project on the community wiki. Thought I might kick it around a bit.

I think I have some basic code to get a deck shuffled but there is one place where I'm a little confused (see comments) and I'd love to get some code critiques as I'm just fumbling my way through this right now.

#holdem.rb
class Card
 attr_reader :suit, :rank
 def initialize(suit, rank)
   @suit = suit
   @rank = rank
 end
end

class Deck
 attr_reader :deck
 SUITS = ["C","D","H","S"]
 RANKS = ["2","3","4","5","6","7","8","9","10","J","Q","K","A"]

A very common idiom for constructing lists of strings is to use %w, a la

irb(main):001:0> ary = %w(2 3 4 5 6 7 8 9 10 J Q K A)
=> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]
irb(main):002:0>

Ah ok - very nice.


The %W variant allows interpolation:

irb(main):002:0> ace = 'A'
=> "A"
irb(main):003:0> ary2 = %W(2 3 4 5 6 7 8 9 10 J Q K #{ace})
=> ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]
irb(main):004:0>

It just saves some typing for a common case =)

Does that accomplish something for this specific case or were you just bringing %W to my attention?



 def initialize
   @deck = Array.new
   SUITS.each do |suit|
     RANKS.each do |rank|
       @deck[@deck.length] = Card.new(suit, rank)
     end
   end

It might be clearer to say

@deck << Card.new(suit, rank)

Yes that is more succinct.


however

   self
 end
 def shuffle
   deck_shuffled = Array.new
   deck_length_orig = @deck.length
   while deck_shuffled.length < deck_length_orig
     rand_card = rand(@deck.length)
     deck_shuffled << @deck[rand_card]
     @deck.delete_at(rand_card)
   end
   @deck.replace(deck_shuffled)
 end
end

deck = Deck.new
deck.shuffle
# why do I need to use deck.deck if I'm returning self on initialize? have pointer to self object and that's <> the array?

why not define each for the deck?

class Deck
  def each &block
    @deck.each &block
  end
end

or

class Deck
  def each
    @deck.each { |card| yield card }
  end
end

I like the first, personally, but either works, and each, traditionally, uses yield not an explicit param

Phew. Pretty cool. I guess this is the sort of thing where I'm going to have to rearrange my thinking patterns to embrace OO.


So was I right in my guess that the reason I have to use deck.deck to begin with is that the 'deck' before the period points to the object deck and the second 'deck' points to the instance variable @deck?

I still don't quite grasp why I can't return @deck in Deck#initialize and have a pointer directly to the @deck instance var.

Also I kind of expected that someone might come back and say it doesn't make sense to have the object that just points to the array and suggest I structure it differently altogether.


_______________________________________________ talk mailing list talk@phillyonrails.org http://lists.phillyonrails.org/mailman/listinfo/talk