Ruby 保龄球计算器
我正在用Ruby编写一个保龄球分数计算器,它是使用RSpec定义和测试的。它目前正在运行,但只通过了8个输入测试中的5个。以下是我的实现代码:Ruby 保龄球计算器,ruby,rspec,Ruby,Rspec,我正在用Ruby编写一个保龄球分数计算器,它是使用RSpec定义和测试的。它目前正在运行,但只通过了8个输入测试中的5个。以下是我的实现代码: class ScoreKeeper def calculate(input) unless input.is_a? String raise argumentException, "Score Keeper will only except string types for score calculation."
class ScoreKeeper
def calculate(input)
unless input.is_a? String
raise argumentException, "Score Keeper will only except string types for score calculation."
end
# Thanksgiving Turkey Edge Case
return 300 if input == "xxxxxxxxxxxx"
# Calculate Score
throws = input.gsub(/-/, "0").split(//)
score = 0
throws.each_with_index do |ball, i|
current_throw = i
last_throw = throws[i - 1] || "0"
lastlast_throw = throws[i - 2] || "0"
next_throw = throws[i + 1] || "0"
if current_throw == 0
last_throw = 0
lastlast_throw = 0
end
if current_throw == 1
lastlast_throw = 0
end
working_value = 0
# Add numbers directly (unless part of a spare frame)
if ((1..9) === ball.to_i)
working_value = ball.to_i
end
# Add strike as 10 points
if ball == "x"
working_value = 10
end
# Add spare as number of remaining pins from last throw
if ball == "/"
if last_throw == "/" || last_throw == "x"
raise argumentException, "Invalid score string. A spare cannot immediately follow a strike or spare."
end
working_value = 10 - last_throw.to_i
end
# Strike / Spare Bonus
if last_throw == "x" || last_throw == "/" || lastlast_throw == "x"
score += working_value
end
# Add current throw value
score += working_value
end
if score > 300 || score < 0
raise argumentExcpetion, "Invalid score string. Impossible score detected."
end
score
end
end
失败的输入是:
- “5/5/5/5/5/5/5/5/5/5/5”(预期:150,获得:155)
- “x3/61xxx2/9-7/xxx”(预期为82,实际为88)
- “14456/5/--17/6/--2/6”(预期:193,获得:223)
- 我看到的第一件事是您使用:
您没有将返回的字符串分配给任何对象,而是将其丢弃
input = '#0#'
input.gsub('0', '-') # => "#-#"
input # => "#0#"
我怀疑您正在考虑变异,但我建议您只需将值传递给:
你的代码不是惯用的Ruby;有许多事情你需要改变:
- 而不是
使用:if!input.u是a吗?字符串
除非,否则使用unless input.is_a? String raise argumentException, "Score Keeper will only except string types for score calculation." end
比使用否定测试更好
- 而不是
使用“尾随if”:if input == "xxxxxxxxxxxx" return 300 end
- 不要用前导的
命名变量<代码>帧应该是\uuu
帧
- 不要用混合大小写命名变量,如
、lastFrame
和lastFrame
,也称为“camelCase”。我们对Ruby变量和方法使用“snake_case”,对类和模块使用camelCase。这是一个可读性问题workingValue
- 不要以尾随
)结束行代码>:
我们唯一使用尾随分号的时候是在一行上使用多个语句,这应该是非常罕见的。除非你知道为什么和什么时候应该这样做,否则不要这样做workingValue = 0;
- 考虑一下您在这里遇到的潜在问题:
虽然您的代码可能会回避这个问题,但不要编写这样的代码并考虑其副作用。也许您真的想测试该值是否为介于1和9之间的整数"12".include?('1') # => true "12".include?('2') # => true "12".include?('12') # => true
((1 .. 9) === '1'.to_i) # => true ((1 .. 9) === '2'.to_i) # => true ((1 .. 9) === '12'.to_i) # => false
- 而不是使用
你可以简单地使用return score
Ruby将返回最后看到的值;您不必显式地返回它score
- 正确缩进代码。当你不得不重新投入到代码中去调试某些东西时,你未来的自我会很感激的。一致使用两个空格缩进
- 自由地使用空格将代码分隔为可读块。它不会影响代码的运行时速度,并且使代码更易于阅读。再一次,你未来的自己会欣赏它
虽然这似乎是吹毛求疵,但在一个开发团队中编写代码时,这些小事情会起到很大的作用,如果不做这些事情,可能会让您在代码审查过程中陷入困境。您的问题似乎是,对于前两个帧,您正在添加最后两个帧。请考虑以下内容:
arr = [1,2,3,4,5,6,7,8,9]
arr.each_with_index do |num, i|
puts "current number #{num}"
puts arr[i-1]
puts arr[i-2]
end
我认为需要一个if语句来处理前两个帧,因为如果索引为0,则-index将循环回数组的末尾
所以你需要像
arr = [1,2,3,4,5,6,7,8,9]
arr.each_with_index do |num, i|
puts "current number #{num}"
if i <= 1
puts "no previous frame"
elsif i == 1
puts arr[i-1] + "can be added to frame 2"
else
puts arr[i-1] + "can be added to frame 1"
puts arr[i-2] + "can be added to frame 2"
end
end
arr=[1,2,3,4,5,6,7,8,9]
arr.each_与_索引do | num,i|
放入“当前数字#{num}”
如果我问你什么问题?欢迎来到堆栈溢出。在请求调试代码的帮助时,有必要提供示例输入和预期输出。如果没有这些,我们必须拼凑出一些容易出错的东西。
return score
score
arr = [1,2,3,4,5,6,7,8,9]
arr.each_with_index do |num, i|
puts "current number #{num}"
puts arr[i-1]
puts arr[i-2]
end
arr = [1,2,3,4,5,6,7,8,9]
arr.each_with_index do |num, i|
puts "current number #{num}"
if i <= 1
puts "no previous frame"
elsif i == 1
puts arr[i-1] + "can be added to frame 2"
else
puts arr[i-1] + "can be added to frame 1"
puts arr[i-2] + "can be added to frame 2"
end
end