-1

I am having trouble getting this to work. The error I get is:

114 in 'numberstash' : undefined method 'cards' for nil:Nilclass (No Method Error).

It is for a Blackjack game. I spent several hours trying to fix this code, including making a bunch of test scripts to figure it out. However, I have had no luck. This works on my test script, however it doesn't work on the current script:

class Card
  attr_accessor :suit, :value

  def initialize(suit, value)
    @suit = suit
    @value = value
  end

  def to_s
    "#{value} of #{suit}"
  end
end

class Deck
  attr_accessor :cards

  def initialize(number_of_decks)
    @cards = []
    num = number_of_decks
    counter = 0
    while counter < num
      ['H','C', 'S', 'D'].product(['2','3','4','5','6','7','8','9','10','J','K','Q','A']).each do |arr|
        @cards << Card.new(arr[0], arr[1])
      end
      counter += 1
    end
  end
end

class Player
  attr_accessor :cards, :testvalue

  def initialize
    @cards = []
  end
end

class Dealer
  attr_accessor :cards

  @cards = []
end

class Blackjack
  attr_accessor :deck, :player, :dealer

  def calculate arr
    new = arr.map { |e| e[1] }
    sum = 0
    ace = 0
    new.each { |value|
      if value == 'A'
        sum += 1
        ace = 1
      elsif value.to_i == 0
        sum += 10
      else
        sum += value.to_i
      end
    }
    if ace = 1 && sum + 10 <= 21
      ace = 0
      sum = sum + 10
    end
  end

  def initialize
    deck = Deck.new(4)
    #@deck = @deck.shuffle
    player = Player.new()
    dealer = Dealer.new()
  end

  def dealcards
    #puts 'dealcards'
    #player.cards << deck.cards.pop
    #dealer.cards << deck.cards.pop
  end

  def start
    #dealcards
    #player_turn
    #dealer_turn
    #compare?
    #play again?
    numberstash
  end

  def numberstash
    #player.cards << deck.cards.pop
    puts player.cards
    #dealer.cards << deck.cards.pop
  end
end

game = Blackjack.new()
game.start

My question is, why am I getting the above mentioned error?

sites
  • 21,417
  • 17
  • 87
  • 146

1 Answers1

5

Everywhere in Blackjack that you use player, you mean @player, for example in Blackjack#initialize:

@player = Player.new()

and Blackjack#numberstash:

puts @player.cards

@ identifies instance variables, the kinds of thing accessed by attr_accessor.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Sean Redmond
  • 3,974
  • 22
  • 28
  • and as it goes in ruby, to test this, write a test assert game.instance_variables not_nil, assert game.instance_variables == #however many you defined) ect. – darethas Jul 14 '13 at 23:24
  • Thank you for responding Sean. So what are you suggesting I do to fix the code? Sorry I am very new when it comes to Ruby. Thanks – Quest of Virtue Jul 15 '13 at 01:12
  • The just need to understand that the properties you've used with `attr_accessor` are instance variables, and need to be prefixed with `@` when you refer to them. Take a look at [this answer](http://stackoverflow.com/a/4371458/131226) for a brief overview of accessors and instance variables. – Sean Redmond Jul 15 '13 at 01:24
  • Also, when you write `player = something` you are defining local variable instead of using setter method, to use to setter method you can use `self.player = ` – sites Jul 15 '13 at 05:57
  • In this case `self.player` and `@player` are equivalent -- as they are pretty much any time you use `attr_accessor`. You only _need_ to use the `self` version if your accessor does something more complicated than just assign a value to the variable (and in that case you can't use the `attr_accessor` shortcut anyway) – Sean Redmond Jul 15 '13 at 14:04