6

I'm creating a card game with multiple classes. Currently, I'm using global variables to hold the $shuffled_deck, $players_hand, and $dealers_hand variables, but I worry when using global variables (perhaps, needlessly) and would prefer to use instance variables.

I've been reading around, but nothing is really clicking. Can anyone help point me in the right direction with this?

Using instance variables I haven't been able to save the @players_hand and @dealers_hand to be able to use them in other classes. For instance, I have @players_hand from the Player class. I have the Dealer class draw a card, but I can't pull that @players_hand into the Dealer class to add the two together.

My current code is:

class Blackjack

  def initialize
    @player = Player.new
    @dealer = Dealer.new
  end
end

class Dealer

  def initialize
    @deck = Deck.new
    $dealers_hand = 0
  end

  def hit_dealer
    @deck.hit_dealer
  end

  def hit_player
    @deck.hit_player
  end

  def draw_card
    @hit = $shuffled_deck
  end

  def shuffle
    @deck.suits
  end
end

class Player

  def initialize
    $players_hand = 0
  end   
end

class Deck

 def suits
   #code that shuffled the deck..
   $shuffled_deck = @shuffled_deck
 end

 def hit_player
   @hit = $shuffled_deck.pop
 end

 def hit_dealer
   @hit = $shuffled_deck.pop
 end

end
1
  • Good question, but there will be quite a lot of concepts to go through to get a complete answer. Hopefully someone will know a good reference document, but you'll definitely need to get a handle on encapsulation which is the idea of working out which object a piece of data belongs to, and normally ends up with you adding more (smaller) classes with more specific responsibilities Commented Feb 22, 2012 at 16:47

2 Answers 2

6

using your example you can do it like this

class Blackjack
  attr_reader :player, :dealer

  def initialize
    @player = Player.new
    @dealer = Dealer.new
  end
end

class Dealer
  def dealers_hand #the long java way of a getter
    @dealers_hand
  end

  #and now the short ruby way
  attr_reader :dealers_hand #if you only need to read the attribute
  attr_writer :dealers_hand #if you only need to write the attribute
  attr_accessor: dealers_hand #if you need both

  def initialize
    @deck = Deck.new
    @dealers_hand = 5
  end

  def hit_dealer
    @deck.hit_dealer
  end

  def hit_player
    @deck.hit_player
  end

  def draw_card
    @hit = $shuffled_deck
  end

  def shuffle
    @deck.suits
  end
end

class Player
  attr_reader :players_hand
  def initialize
    @players_hand = 0
  end   
end

class Deck

 def suits
   attr_reader :shuffled_deck
   @shuffled_deck = @shuffled_deck
 end

 def hit_player
   @hit = $shuffled_deck.pop
 end

 def hit_dealer
   @hit = $shuffled_deck.pop
 end

end

game = Blackjack.new
p game.dealer.dealers_hand
game.dealer.dealers_hand = 4
p game.dealer.dealers_hand
Sign up to request clarification or add additional context in comments.

2 Comments

would it be better to use attr_accessor :players_hand in the Dealer class instead of both attr_writer and attr_reader?
of course, you are right, should haven mentioned that, edited the class Dealer with some explanation
5

You want to use attr_reader, attr_writer, or attr_accessor. Here's how they work:

  • attr_reader :players_hand: Allows you to write some_player.players_hand to get the value of that player's players_hand instance variable
  • attr_writer :players_hand: Allows you to write some_player.players_hand = 0 to set the variable to 0
  • attr_accessor :players_hand: Allows you to both read and write, as though you'd used both attr_reader and attr_writer.

Incidentally, all these do is write methods for you. If you wanted, you could do it manually like this:

class Player
  def initialize
    @players_hand = 0
  end  

  def players_hand
    @players_hand
  end

  def players_hand=(new_value)
    @players_hand = new_value
  end
end

1 Comment

Thanks @Chuck, so I would want to do something like. class Player attr_accessor :players_hand #rest of players methods end def Blackjack def initialize @player = Player.new end end and then write to that players hand ... @player.players_hand

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.