Ruby 保龄球计算器

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."

我正在用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."
    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 input == "xxxxxxxxxxxx"
            return 300
        end
        
        使用“尾随if”:

      • 不要用前导的
        \uuu
        命名变量<代码>帧
        应该是

      • 不要用混合大小写命名变量,如
        lastFrame
        lastFrame
        workingValue
        ,也称为“camelCase”。我们对Ruby变量和方法使用“snake_case”,对类和模块使用camelCase。这是一个可读性问题
      • 不要以尾随
        )结束行

        workingValue = 0;
        
        我们唯一使用尾随分号的时候是在一行上使用多个语句,这应该是非常罕见的。除非你知道为什么和什么时候应该这样做,否则不要这样做

      • 考虑一下您在这里遇到的潜在问题:

        "12".include?('1') # => true
        "12".include?('2') # => true
        "12".include?('12') # => true
        
        虽然您的代码可能会回避这个问题,但不要编写这样的代码并考虑其副作用。也许您真的想测试该值是否为介于1和9之间的整数

        ((1 .. 9) === '1'.to_i) # => true
        ((1 .. 9) === '2'.to_i) # => true
        ((1 .. 9) === '12'.to_i) # => false
        
      • 而不是使用

        return score
        
        你可以简单地使用

        score
        
        Ruby将返回最后看到的值;您不必显式地返回它

      • 正确缩进代码。当你不得不重新投入到代码中去调试某些东西时,你未来的自我会很感激的。一致使用两个空格缩进
      • 自由地使用空格将代码分隔为可读块。它不会影响代码的运行时速度,并且使代码更易于阅读。再一次,你未来的自己会欣赏它

      虽然这似乎是吹毛求疵,但在一个开发团队中编写代码时,这些小事情会起到很大的作用,如果不做这些事情,可能会让您在代码审查过程中陷入困境。

      您的问题似乎是,对于前两个帧,您正在添加最后两个帧。请考虑以下内容:

      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