When the user enters "hit", they are given a random card assigned to a value. I have set the card as key and points as a value in hashes, and every time I try to call it, it does not put anything!

def random_card
  cards = ["two", "three", "four", "five", "six", "seven",
           "eight", "nine", "ten",
           "jack", "queen", "king", "ace"]

  cards[rand(13)]
end

def score
  card_value = {
  two: 2,
  three: 3,
  four: 4,
  five: 5,
  six: 6,
  seven: 7,
  eight: 8,
  nine: 9,
  ten: 10,
  jack: 10,
  queen: 10,
  king: 10,
  ace: 11,
}
puts "point #{card_value[:card]}"
end

def move
  while true
    puts '"hit" or "stick"'
    input = gets.chomp
    if input == "hit"
      puts card = random_card
      score
    end
    break if input == "stick"
  end
end

When the user enters "hit" output should be a random card and the point that is assigned to that card, eg Three points 3

3 Answers

2
Sebastian Palma On Best Solutions

The easiest is just to update

puts "point #{card_value[:card]}"

To

puts "point #{card_value[random_card.to_sym]}"

The reason is card_value[:card] is trying to get from the card_value hash they card key, which doesn't exist.

Your random_card function returns a "random" string value from the cards array defined in its body, being a string, you'll get the same error, as the keys in the card_value are symbols, so you need to convert that result to a symbol.



Answering to the dx7 nice addition.

You can just declare a CARD_VALUES hash, containing card names and points, which you can then pick up with Array#sample, so you avoid adding a useless instance variable for the card, and having to pass it as a method argument when calling random_card:

CARD_VALUES = { two: 2, three: 3, four: 4, five: 5, six: 6, seven: 7, eight: 8, nine: 9, ten: 10,
               jack: 10, queen: 10, king: 10, ace: 11 }

def random_card
  CARD_VALUES.to_a.sample
end

def move
  loop do
    puts '"hit" or "stick"'
    input = gets.chomp
    if input == 'hit'
      card, point = random_card
      puts "card: #{card}"
      puts "point: #{point}"
    end
    break if input == 'stick'
  end
end

move
0
iGian On

You could also define a constant with all the cards, build a deck with the keys and shuffle the deck, popping a card: this avoids getting a card twice.

CARDS = {two: 2,three: 3,four: 4,five: 5,six: 6,seven: 7,eight: 8,nine: 9,ten: 10,jack: 10,queen: 10,king: 10,ace: 11}

deck = CARDS.keys # it's an array with all the keys
# score = 0 # just in case
loop do
  puts '"hit" or "stick"'
  input = gets.chomp
  if input == "hit"
    puts card = deck.shuffle!.pop # so you are removing the card from the deck
    puts value = CARDS[card]
    # puts score += value # just in case
  end
  break if input == "stick"
end
# puts score # just in case
-1
dx7 On

I will try to answer you without change your algorithm.

The problem is puts "point #{card_value[:card]}". You don't have that :card key on hash card_value. Considering you want to get the score from previously got random card, you need to pass that card to the score method and then get the score.

def random_card
  cards = ["two", "three", "four", "five", "six", "seven",
           "eight", "nine", "ten",
           "jack", "queen", "king", "ace"]

  cards[rand(13)]
end

def score(card)
  card_value = {
  two: 2,
  three: 3,
  four: 4,
  five: 5,
  six: 6,
  seven: 7,
  eight: 8,
  nine: 9,
  ten: 10,
  jack: 10,
  queen: 10,
  king: 10,
  ace: 11,
}
puts "point #{card_value[card.to_sym]}"
end

def move
  while true
    puts '"hit" or "stick"'
    input = gets.chomp
    if input == "hit"
      puts card = random_card
      score(card)
    end
    break if input == "stick"
  end
end

move

Your cards are strings and your hash card_value uses symbols as keys. So you need to use to_sym to convert string into symbol.