Score получает массив в качестве параметра в спецификации, но ваш код не передает его. Чтобы исправить это, вам нужно использовать что-то вроде этого (см. Параметр card
)
def score(card) # Line 78
@total = 0
@hand.each do # Line 80
puts @values
@total += @values[card]
end
@total
end
undefined method '[]' for nil:NilClass
означает, что массив или хэш имеет значение nil, к которому вы пытаетесь получить доступ, используя []. К сожалению, вы не публикуете в своем сообщении никаких подробностей / стековых трасс. Я думаю, что ни @hand, ни @values не определены где-то для теста, см. Edit внизу.
Обратите внимание, ваш код использует много переменных экземпляра, таких как @hand
, которые, возможно, не нужны, яd предлагает использовать вместо них локальные переменные и возвращать значения из методов, которые затем можно использовать в качестве параметров в других методах
Редактировать:
Спецификации вызывают только метод оценки и ничего больше. Поэтому ни @hand
, ни @values
переменные экземпляра, определенные вне метода, недоступны. Вы должны определить это в спецификациях, например, используя instance_variable_set(:@hand, ["three"])
или instance_variable_set(:@values, { "three" => 3 })
в тестах, как показано выше.
Но так как вы не можете изменить предопределенные спецификации для испытания, я думаю, это невозможно. И это, конечно, впоследствии привело бы к другим ошибкам, которые также нуждаются в исправлении. Возможно, это неправильный подход, делайте небольшие шаги, чтобы все стало зеленым, рефакторинг позже.
Я добавил строки для установки переменных экземпляра в качестве ссылки в моем примере ниже:
it 'scores `"three"` as 3' do
instance_variable_set(:@hand, ["three"])
instance_variable_set(:@values, { "three" => 3 })
expect(score(["three"])).to eq(3)
end
- Отслеживание стека - это ошибка, содержащая номера строк для вызываемых методов, которые вы опубликовалидля другого ArgumentError. Теперь я посмотрел на ошибки локально, не беспокоясь.
Вот мое решение, которое просто работает, я не проводил никаких рефакторингов, я надеюсь, что вы можете работать или учиться уэто также:
def random_card
cards = ["two", "three", "four", "five", "six", "seven",
"eight", "nine", "ten", "jack", "queen", "king", "ace"]
cards[rand(13)]
end
def move
case gets.chomp
when "hit"
"hit"
when "stick"
"stick"
else
"hit"
end
end
def score(cards)
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
}
total = 0
current_result = 0
cards.each do |card|
total += values[card]
current_result = current_result + values[card]
puts "Score so far: #{current_result}"
end
total
end
def run_game
cards = []
total_score = 0
while move == 'hit' && total_score <= 21
cards.unshift random_card
total_score = score(cards)
end
if total_score <= 21
puts "You scored: #{total_score}"
else
puts "You busted with: #{total_score}"
end
end