2017-01-30 94 views
0

我試圖從這本Ruby書中學到以下代碼,它不斷崩潰,我花了數小時試圖修復。如果任何人有任何線索爲什麼發生這種情況,請讓我知道。我不喜歡紅寶石Ruby腳本崩潰

#定義自定義類------------------------------------- --------------

#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 
+3

編輯的腳本能否請您發佈錯誤消息和堆棧跟蹤你得到? – Bustikiller

+2

這令人不安地充滿了'$'-type全局變量。這是你在消耗你之前需要立即踢球的習慣。 – tadman

回答

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。該代碼使用其他全局變量,因此它可以很好。有比這更好的做法,但對於此代碼,它工作正常。之後,遊戲運行正常。但它似乎有一些其他問題來評估數字。這應該是另一個修復。也許是另一個問題。所以調查一下你的代碼。

下面是代碼的製作答案全球使用$回答結果:

#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

的問題是在遊戲類中的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