抓住并扔掉红宝石不起作用

时间:2013-11-12 04:15:25

标签: ruby

我正在尝试在Ruby中制作一个数字猜谜游戏,但是当我输入是,当我想再玩时,程序会退出。我尝试使用catch和throw但它不起作用。我能帮忙吗?

这是我的代码。

class Game
    def Play
        catch (:start) do
            $a=rand(11)
            puts ($a)
            until $g==$a
                puts "Guess the number between 0-10."
                $g=gets.to_i
                if $g>$a
                    puts "The number you guessed is too high."
                elsif $g==$a
                    puts "Correct you won!!!"
                    puts "Would you like to play again?"
                    $s=gets()
                    if $s=="yes"
                        $c=true
                    end
                    if $c==true
                        throw (:start) 
                    end
                elsif $g<$a
                    puts "The number you guessed is too low."
                end
            end
        end
    end
end
Game.new.Play

编辑:在尝试使用建议后,这是我的新代码:

class Game
  def Play
    catch (:start) do
      $a=rand(11)
      puts ($a)
      while $s=="yes"
        until $g==$a
          puts "Guess the number between 0-10."
          $g=gets.chomp.to_i
          if $g>$a
            puts "The number you guessed is too high."
          elsif $g==$a
            puts "Correct you won!!!"
            puts "Would you like to play again?"
            $s=gets.chomp
            if $s=="yes"
              throw (:start)
            end
          elsif $g<$a
            puts "The number you guessed is too low."
          end
        end
      end
    end
  end
end
Game.new.Play

4 个答案:

答案 0 :(得分:3)

你的第一个问题是:

$s=gets()
if $s=="yes"
    $c=true
end

gets方法将读取下一行,包括换行符'\ n',并将其与“是”进行比较:

> gets
=> "yes\n" 

在Ruby中修复此问题的惯用方法是chomp方法:

> gets.chomp
=> "yes"

那就是说,你的代码还有其他两个不足之处。

  1. 您可能来自PHP,Perl等语言,甚至只是Bash脚本,但Ruby在变量之前不需要美元符号。使用$给出一个可变的全局范围,这可能不是你想要的。实际上,您几乎从不希望变量具有全局范围。

    Ruby使用三种类型的符号前缀来表示范围 - 例如,@ @表示类,$表示全局。然而,最常见的变量类型只是本地的,不需要任何前缀,我建议你的代码。

  2. 我一直被告知,对控制结构使用异常是非常糟糕的做法。使用while / break结构可以更好地提供代码。

答案 1 :(得分:1)

执行gets()时,它会在最后检索带有'\ n'的整行。您需要使用以下方法修剪新行字符:

$g=gets.chomp.to_i

其他gets

相同

答案 2 :(得分:0)

根据您更新的代码(修复其他人显示的换行问题),您的新问题是您已将所有游戏包裹在while $s=="true"内。第一次运行代码时,$snil(它从未设置过),因此您永远无法进行游戏。如果您使用局部变量而不是全局变量(s而不是$s),这将变得更加明显,因为代码甚至都没有运行。

这是我重新编写游戏的一种工作方式。

class Game
  def play
    keep_playing = true
    while keep_playing
      answer = rand(11)     # Make a new answer each time
      puts answer if $DEBUG # we don't normally let the user cheat
      loop do               # keep going until I break from the loop
        puts "Guess the number between 0-10."
        guess = gets.to_i   # no need for chomp here
        if guess>answer
          puts "The number you guessed is too high."
        elsif guess<answer
          puts "The number you guessed is too low."
        else
          puts "Correct you won!!!",
               "Would you like to play again?"
          keep_playing = gets.chomp.downcase=="yes"
          break
        end
      end
    end
  end
end
Game.new.play

答案 3 :(得分:0)

我知道这并没有真正回答你的问题,为什么你的代码不起作用,但在看到你发布的代码后我只需要重构它。你走了:

class Game
  def initialize
    @answer = rand(11)
  end

  def play
    loop do
      guess = get_guess
      display_feedback guess
      break if guess == @answer
    end
  end

  def self.play_loop
    loop do
      Game.new.play
      break unless play_again?
    end
  end

  private

  def get_guess
    puts "Guess the number between 0-10."
    return gets.chomp.to_i
  end

  def display_feedback(guess)
    if guess > @answer
      puts "The number you guessed is too high."
    elsif guess < @answer
      puts "The number you guessed is too low."
    elsif guess == @answer
      puts "Correct you won!!!"
    end
  end

  def self.play_again?
    puts "Would you like to play again?"
    return gets.chomp == "yes"
  end
end

Game.play_loop