Ruby脚本崩溃

时间:2017-01-30 05:45:45

标签: ruby

我有以下代码,我试图从这本Ruby书中学习并且它一直在崩溃,我花了几个小时试图修复。如果有人知道为什么会这样,请告诉我。我不喜欢Ruby

#define custom classes ------------------------------------------- --------

#Define a class representing the console window
class Screen

  def cls  #Define a method that clears the display area
    puts ("\n" * 25)  #Scroll the screen 25 times
    puts "\a"  #Make a little noise to get the player's attention
  end

  def pause    #Define a method that pauses the display area
    STDIN.gets  #Execute the STDIN class's gets method to pause script
                #execution until the player presses the enter key
  end

end

#Define a class representing the Ruby Number Guessing Game
class Game

  #This method displays the game's opening screen
  def display_greeting

    Console_Screen.cls  #Clear the display area

    #Display welcome message
    print "\t\t  Welcome to the Ruby Number Guessing Game!" +
    "\n\n\n\n\n\n\n\n\n\n\n\n\n\nPress Enter to " +
               "continue."

  Console_Screen.pause       #Pause the game

  end

  #Define a method to be used to present game instructions
  def display_instructions

    Console_Screen.cls       #Clear the display area
    puts "INSTRUCTIONS:\n\n"  #Display a heading

    #Display the game's instructions
    puts "This game randomly generates a number from 1 to 100 and" 
    puts "challenges you to identify it in as few guesses as possible."
    puts "After each guess, the game will analyze your input and provide"
    puts "you with feedback. You may take as many turns as you need in" 
    puts "order to guess the game's secret number.\n\n"
    puts "Game will stop if you have guessed 10 times.\n\n\n"
    puts "Good luck!\n\n\n\n\n\n\n\n\n"
    print "Press Enter to continue."

    Console_Screen.pause       #Pause the game

  end

  #Define a method that generates the game's secret number
  def generate_number

    #Generate and return a random number between 1 and 100
    return randomNo = 1 + rand(1000)

  end

  #Define a method to be used control game play
  def play_game



    #Call on the generate_number method in order to get a random number
    number = generate_number  

    #Loop until the player inputs a valid answer
    loop do

      Console_Screen.cls       #Clear the display area

        if answer == "c"

            print "Game count : #{$gameCount}"

        end
      #Prompt the player to make a guess
      print "\nEnter your guess and press the Enter key: "

      reply = STDIN.gets  #Collect the player's answer
      reply.chop!         #Remove the end of line character
      reply = reply.to_i  #Convert the player's guess to an integer


          #Validate the player's input only allowing guesses between 1 and 100
          if reply < 1 or reply > 1000 then
            redo  #Redo the current iteration of the loop
          end

          #Analyze the player's guess to determine if it is correct
          if reply == number then    #The player's guess was correct
            Console_Screen.cls        #Clear the display area
            print "You have guessed the number! Press enter to continue."
            Console_Screen.pause      #Pause the game
            break  #Exit loop
          elsif reply < number then  #The player's guess was too low
            Console_Screen.cls        #Clear the display area
            print "Your guess is too low! ( valid range: 1 - 1000) Press Enter to continue."
            Console_Screen.pause      #Pause the game
          elsif reply > number then  #The player's guess was too high
            Console_Screen.cls        #Clear the display area
            print "Your guess is too high! ( valid range: 1 - 1000) Press Enter to continue."
            Console_Screen.pause      #Pause the game
          end
          $noOfGuesses +=1

      break if $noOfGuesses > 10

    end

  end

  #This method displays the information about the Ruby Number Guessing Game
  def display_credits

    Console_Screen.cls  #Clear the display area

    #Thank the player and display game information
    puts "\t\tThank you playing the Ruby Number Guessing Game.\n\n\n\n"
    puts "\n\t\t\t Developed by Jerry Lee Ford, Jr.\n\n"
    puts "\t\t\t\t  Copyright 2010\n\n"
    puts "\t\t\tURL: http://www.tech-publishing.com\n\n\n\n\n\n\n\n\n\n"

  end

end


# Main Script Logic -------------------------------------------------------

Console_Screen = Screen.new  #Instantiate a new Screen object
SQ = Game.new                #Instantiate a new Game object

#Execute the Game class's display_greeting method
SQ.display_greeting

answer = ""

$gameCount = 0
$noOfGuesses = 0
$totalNoOfGuesses = 0
$avgNoOfGuesses = 0


#Loop until the player enters y or n and do not accept any other input
loop do

  Console_Screen.cls  #Clear the display area

  #Prompt the player for permission to start the game
  print "Are you ready to play the Ruby Number Guessing Game? (y/n): "

  answer = STDIN.gets  #Collect the player's response
  answer.chop!  #Remove any extra characters appended to the string

  #Terminate the loop if valid input was provided
  break if answer == "y" || answer == "n" || answer == "c"  #Exit loop

end 

#Analyze the player's input
if answer == "n"  #See if the player elected not to take the game

  Console_Screen.cls  #Clear the display area

  #Invite the player to return and play the game some other time
  puts "Okay, perhaps another time.\n\n"

else  #The player wants to play the game

    #Execute the Game class's display_instructions method
    SQ.display_instructions

  loop do

    $gameCount+=1

    #Execute the Game class's play_game method 
    SQ.play_game

    $totalNoOfGuesses = $noOfGuesses * $gameCount

    $avgNoOfGuesses = $totalNoOfGuesses / $noOfGuesses
    print "The total number of guesses was  #{$totalNoOfGuesses}"
    print "The average number of guesses was  #{$avgNoOfGuesses}"
    Console_Screen.pause      #Pause the game
    print "Press Enter to continue"

    Console_Screen.cls  #Clear the display area

    #Prompt the player for permission start a new round of play
    print "Would you like to play again? (y/n): "

    playAgain = STDIN.gets  #Collect the player's response
    playAgain.chop!  #Remove any extra characters appended to the string

    break if playAgain == "n"  #Exit loop

  end

  #Call upon the Game class's determine_credits method in order to thank
  #the player for playing the game and to display game information
  SQ.display_credits

end

2 个答案:

答案 0 :(得分:2)

运行代码时说:

script-not-working.rb:74:in `block in play_game': undefined local variable or method `answer' for #<Game:0x0000000180f9c0> (NameError)
    from script-not-working.rb:70:in `loop'
    from script-not-working.rb:70:in `play_game'
    from script-not-working.rb:181:in `block in <main>'
    from script-not-working.rb:176:in `loop'
    from script-not-working.rb:176:in `<main>'

因此,一个解决方案可以使变量回答全局,在所有answer变量之前添加$应该是:$answer。代码使用其他全局变量,因此可能没问题。有比这更好的做法,但对于这个代码它工作正常。之后游戏正常运行。但似乎在评估数量方面存在一些其他问题。这应该是另一个修复。也许是另一个问题。所以调查一下你的代码。

以下是使用$ answer:

进行全局代码回答的结果
#Define a class representing the console window
class Screen

  def cls  #Define a method that clears the display area
    puts ("\n" * 25)  #Scroll the screen 25 times
    puts "\a"  #Make a little noise to get the player's attention
  end

  def pause    #Define a method that pauses the display area
    STDIN.gets  #Execute the STDIN class's gets method to pause script
                #execution until the player presses the enter key
  end

end

#Define a class representing the Ruby Number Guessing Game
class Game

  #This method displays the game's opening screen
  def display_greeting

    Console_Screen.cls  #Clear the display area

    #Display welcome message
    print "\t\t  Welcome to the Ruby Number Guessing Game!" +
    "\n\n\n\n\n\n\n\n\n\n\n\n\n\nPress Enter to " +
               "continue."

  Console_Screen.pause       #Pause the game

  end

  #Define a method to be used to present game instructions
  def display_instructions

    Console_Screen.cls       #Clear the display area
    puts "INSTRUCTIONS:\n\n"  #Display a heading

    #Display the game's instructions
    puts "This game randomly generates a number from 1 to 100 and" 
    puts "challenges you to identify it in as few guesses as possible."
    puts "After each guess, the game will analyze your input and provide"
    puts "you with feedback. You may take as many turns as you need in" 
    puts "order to guess the game's secret number.\n\n"
    puts "Game will stop if you have guessed 10 times.\n\n\n"
    puts "Good luck!\n\n\n\n\n\n\n\n\n"
    print "Press Enter to continue."

    Console_Screen.pause       #Pause the game

  end

  #Define a method that generates the game's secret number
  def generate_number

    #Generate and return a random number between 1 and 100
    return randomNo = 1 + rand(1000)

  end

  #Define a method to be used control game play
  def play_game



    #Call on the generate_number method in order to get a random number
    number = generate_number  

    #Loop until the player inputs a valid answer
    loop do

      Console_Screen.cls       #Clear the display area

        if $answer == "c"

            print "Game count : #{$gameCount}"

        end
      #Prompt the player to make a guess
      print "\nEnter your guess and press the Enter key: "

      reply = STDIN.gets  #Collect the player's answer
      reply.chop!         #Remove the end of line character
      reply = reply.to_i  #Convert the player's guess to an integer


          #Validate the player's input only allowing guesses between 1 and 100
          if reply < 1 or reply > 1000 then
            redo  #Redo the current iteration of the loop
          end

          #Analyze the player's guess to determine if it is correct
          if reply == number then    #The player's guess was correct
            Console_Screen.cls        #Clear the display area
            print "You have guessed the number! Press enter to continue."
            Console_Screen.pause      #Pause the game
            break  #Exit loop
          elsif reply < number then  #The player's guess was too low
            Console_Screen.cls        #Clear the display area
            print "Your guess is too low! ( valid range: 1 - 1000) Press Enter to continue."
            Console_Screen.pause      #Pause the game
          elsif reply > number then  #The player's guess was too high
            Console_Screen.cls        #Clear the display area
            print "Your guess is too high! ( valid range: 1 - 1000) Press Enter to continue."
            Console_Screen.pause      #Pause the game
          end
          $noOfGuesses +=1

      break if $noOfGuesses > 10

    end

  end

  #This method displays the information about the Ruby Number Guessing Game
  def display_credits

    Console_Screen.cls  #Clear the display area

    #Thank the player and display game information
    puts "\t\tThank you playing the Ruby Number Guessing Game.\n\n\n\n"
    puts "\n\t\t\t Developed by Jerry Lee Ford, Jr.\n\n"
    puts "\t\t\t\t  Copyright 2010\n\n"
    puts "\t\t\tURL: http://www.tech-publishing.com\n\n\n\n\n\n\n\n\n\n"

  end

end


# Main Script Logic -------------------------------------------------------

Console_Screen = Screen.new  #Instantiate a new Screen object
SQ = Game.new                #Instantiate a new Game object

#Execute the Game class's display_greeting method
SQ.display_greeting

$answer = ""

$gameCount = 0
$noOfGuesses = 0
$totalNoOfGuesses = 0
$avgNoOfGuesses = 0


#Loop until the player enters y or n and do not accept any other input
loop do

  Console_Screen.cls  #Clear the display area

  #Prompt the player for permission to start the game
  print "Are you ready to play the Ruby Number Guessing Game? (y/n): "

  $answer = STDIN.gets  #Collect the player's response
  $answer.chop!  #Remove any extra characters appended to the string

  #Terminate the loop if valid input was provided
  break if $answer == "y" || $answer == "n" || $answer == "c"  #Exit loop

end 

#Analyze the player's input
if $answer == "n"  #See if the player elected not to take the game

  Console_Screen.cls  #Clear the display area

  #Invite the player to return and play the game some other time
  puts "Okay, perhaps another time.\n\n"

else  #The player wants to play the game

    #Execute the Game class's display_instructions method
    SQ.display_instructions

  loop do

    $gameCount+=1

    #Execute the Game class's play_game method 
    SQ.play_game

    $totalNoOfGuesses = $noOfGuesses * $gameCount

    $avgNoOfGuesses = $totalNoOfGuesses / $noOfGuesses
    print "The total number of guesses was  #{$totalNoOfGuesses}"
    print "The average number of guesses was  #{$avgNoOfGuesses}"
    Console_Screen.pause      #Pause the game
    print "Press Enter to continue"

    Console_Screen.cls  #Clear the display area

    #Prompt the player for permission start a new round of play
    print "Would you like to play again? (y/n): "

    playAgain = STDIN.gets  #Collect the player's response
    playAgain.chop!  #Remove any extra characters appended to the string

    break if playAgain == "n"  #Exit loop

  end

  #Call upon the Game class's determine_credits method in order to thank
  #the player for playing the game and to display game information
  SQ.display_credits

end

答案 1 :(得分:1)

问题在于Game类中的play_game方法,没有定义变量答案的地方,即分配给一个值,即使是一个空值。所以我编辑了你的脚本,使得该方法将答案作为一个争论,当稍后在这里调用该方法时,你将从控制台预期的答案作为其参数传递。

  SQ.play_game answer

以下是

下面编辑过的脚本
  #Define a class representing the console window
   class Screen

   def cls  #Define a method that clears the display area
      puts ("\n" * 25)  #Scroll the screen 25 times
      puts "\a"  #Make a little noise to get the player's attention
   end

   def pause    #Define a method that pauses the display area
     STDIN.gets  #Execute the STDIN class's gets method to pause script
            #execution until the player presses the enter key
   end

end

#Define a class representing the Ruby Number Guessing Game
class Game

     #This method displays the game's opening screen
     def display_greeting

     Console_Screen.cls  #Clear the display area

     #Display welcome message
     print "\t\t  Welcome to the Ruby Number Guessing Game!" +
         "\n\n\n\n\n\n\n\n\n\n\n\n\n\nPress Enter to " +
           "continue."

     Console_Screen.pause       #Pause the game

  end

   #Define a method to be used to present game instructions
   def display_instructions

   Console_Screen.cls       #Clear the display area
    puts "INSTRUCTIONS:\n\n"  #Display a heading

   #Display the game's instructions
    puts "This game randomly generates a number from 1 to 100 and" 
    puts "challenges you to identify it in as few guesses as possible."
    puts "After each guess, the game will analyze your input and     provide"
    puts "you with feedback. You may take as many turns as you need in" 
    puts "order to guess the game's secret number.\n\n"
    puts "Game will stop if you have guessed 10 times.\n\n\n"
    puts "Good luck!\n\n\n\n\n\n\n\n\n"
    print "Press Enter to continue."

   Console_Screen.pause       #Pause the game

   end

  #Define a method that generates the game's secret number
  def generate_number

    #Generate and return a random number between 1 and 100
    return randomNo = 1 + rand(1000)

  end

   #Define a method to be used control game play
   def play_game answer



     #Call on the generate_number method in order to get a random number
     number = generate_number  

#Loop until the player inputs a valid answer
loop do

  Console_Screen.cls       #Clear the display area

    if answer == "c"

        print "Game count : #{$gameCount}"

    end
  #Prompt the player to make a guess
  print "\nEnter your guess and press the Enter key: "

  reply = STDIN.gets  #Collect the player's answer
  reply.chop!         #Remove the end of line character
  reply = reply.to_i  #Convert the player's guess to an integer


      #Validate the player's input only allowing guesses between 1 and 100
      if reply < 1 or reply > 1000 then
        redo  #Redo the current iteration of the loop
      end

      #Analyze the player's guess to determine if it is correct
      if reply == number then    #The player's guess was correct
        Console_Screen.cls        #Clear the display area
        print "You have guessed the number! Press enter to continue."
        Console_Screen.pause      #Pause the game
        break  #Exit loop
      elsif reply < number then  #The player's guess was too low
        Console_Screen.cls        #Clear the display area
        print "Your guess is too low! ( valid range: 1 - 1000) Press Enter to continue."
        Console_Screen.pause      #Pause the game
      elsif reply > number then  #The player's guess was too high
        Console_Screen.cls        #Clear the display area
        print "Your guess is too high! ( valid range: 1 - 1000) Press Enter to continue."
        Console_Screen.pause      #Pause the game
      end
      $noOfGuesses +=1

  break if $noOfGuesses > 10

    end

end

     #This method displays the information about the Ruby Number Guessing Game
    def display_credits

       Console_Screen.cls  #Clear the display area

     #Thank the player and display game information
      puts "\t\tThank you playing the Ruby Number Guessing Game.\n\n\n\n"
      puts "\n\t\t\t Developed by Jerry Lee Ford, Jr.\n\n"
      puts "\t\t\t\t  Copyright 2010\n\n"
      puts "\t\t\tURL: http://www.tech-publishing.com\n\n\n\n\n\n\n\n\n\n"

    end

  end


     # Main Script Logic -------------------------------------------------------

     Console_Screen = Screen.new  #Instantiate a new Screen object
      SQ = Game.new                #Instantiate a new Game object

       #Execute the Game class's display_greeting method
      SQ.display_greeting

      answer = ""

       $gameCount = 0
      $noOfGuesses = 0
       $totalNoOfGuesses = 0
       $avgNoOfGuesses = 0


    #Loop until the player enters y or n and do not accept any other input
  loop do

     Console_Screen.cls  #Clear the display area

      #Prompt the player for permission to start the game
    print "Are you ready to play the Ruby Number Guessing Game? (y/n): "

     answer = STDIN.gets  #Collect the player's response
     answer.chop!  #Remove any extra characters appended to the string

    #Terminate the loop if valid input was provided
    break if answer == "y" || answer == "n" || answer == "c"  #Exit loop

   end 

     #Analyze the player's input
     if answer == "n"  #See if the player elected not to take the game

    Console_Screen.cls  #Clear the display area

    #Invite the player to return and play the game some other time
   puts "Okay, perhaps another time.\n\n"

  else  #The player wants to play the game

  #Execute the Game class's display_instructions method
  SQ.display_instructions

    loop do

    $gameCount+=1

    #Execute the Game class's play_game method 
     SQ.play_game answer

      $totalNoOfGuesses = $noOfGuesses * $gameCount

       $avgNoOfGuesses = $totalNoOfGuesses / $noOfGuesses
      print "The total number of guesses was  #{$totalNoOfGuesses}"
      print "The average number of guesses was  #{$avgNoOfGuesses}"
       Console_Screen.pause      #Pause the game
      print "Press Enter to continue"

      Console_Screen.cls  #Clear the display area

     #Prompt the player for permission start a new round of play
      print "Would you like to play again? (y/n): "

      playAgain = STDIN.gets  #Collect the player's response
      playAgain.chop!  #Remove any extra characters appended to the string

       break if playAgain == "n"  #Exit loop
     end


    #Call upon the Game class's determine_credits method in order to thank
     #the player for playing the game and to display game information
     SQ.display_credits
  end