Game python rock, paper, scissors

I use Python and I am trying to write a simple program that simulates a rock, paper, scissors game. Everything works, except when I enter the wrong answer (something other than rock, paper or scissors) when I get this error.

Traceback (most recent call last): File "C:/Users/home/Desktop/BAGARDNER/Python/rock_pape_scissors.py", line 88, in <module> main() File "C:/Users/home/Desktop/BAGARDNER/Python/rock_pape_scissors.py", line 14, in main number = user_guess() File "C:/Users/home/Desktop/BAGARDNER/Python/rock_pape_scissors.py", line 48, in user_guess return number UnboundLocalError: local variable 'number' referenced before assignment 

I understand that this tells me that the number is not referenced, but from what I understand in the code, it does not need the number when the qualifier is false.

 #import random module import random #main function def main(): #intro message print("Let play 'Rock, Paper, Scissors'!") #call the user guess function number = user_guess() #call the computer number function num = computer_number() #call the results function results(num, number) #computer_number function def computer_number(): #get a random number in the range of 1 through 3 num = random.randrange(1,4) #if/elif statement if num == 1: print("Computer chooses rock") elif num == 2: print("Computer chooses paper") elif num == 3: print("Computer chooses scissors") #return the number return num #user_guess function def user_guess(): #get the user guess guess = input("Choose 'rock', 'paper', or 'scissors' by typing that word. ") #while guess == 'paper' or guess == 'rock' or guess == 'scissors': if is_valid_guess(guess): #if/elif statement #assign 1 to rock if guess == 'rock': number = 1 #assign 2 to paper elif guess == 'paper': number = 2 #assign 3 to scissors elif guess == 'scissors': number = 3 return number else: print('That response is invalid.') user_guess() def is_valid_guess(guess): if guess == 'rock' or 'paper' or 'scissors': status = True else: status = False return status def restart(): answer = input("Would you like to play again? Enter 'y' for yes or \ 'n' for no: ") #if/elif statement if answer == 'y': main() elif answer == 'n': print("Goodbye!") else: print("Please enter only 'y' or 'n'!") #call restart restart() #results function def results(num, number): #find the difference in the two numbers difference = num - number #if/elif statement if difference == 0: print("TIE!") #call restart restart() elif difference % 3 == 1: print("I'm sorry! You lost :(") #call restart restart() elif difference % 3 == 2: print("Congratulations! You won :)") #call restart restart() main() 

Thank you for your help!

+2
source share
4 answers

Here is your problem:

 if guess == 'rock' or 'paper' or 'scissors': 

This line in is_valid_guess does not do what you think. Instead, it always returns True . What you are looking for looks something like this:

 if guess == 'rock' or guess == 'paper' or guess == 'scissors': 

or more briefly:

 if guess in ('rock', 'paper', 'scissors'): 

The problem is that you always return True because of how Python evaluates strings in a boolean context. The string if guess == 'rock' or 'paper' or 'scissors': evaluates to:

 if (guess == 'rock') or ('paper') or ('scissors'): 

This means that Python checks to see if guess == 'rock' . If this is true, the conditional value evaluates to True . If it is erroneous, the interpreter tries to evaluate bool('paper') . This is always evaluated as True , because all non-empty lines are "true" . Therefore, all of your conditional conditions are always True , and each line is "valid."

As a result, your code considers all lines to be "valid," and then explodes when it fails to assign a number to an assumption that is not actually supported.


As a final note, your is_valid_guess method can be trimmed a bit, as you simply return the result of your boolean expression. Instead of using the status variable as an intermediate element, you can simply evaluate the expression and return it immediately. I also use the lower() method for string objects to allow case insensitivity in case you want to allow.

 def is_valid_guess(guess): return guess.lower() in ('rock', 'paper', 'scissors') 

You have one more problem that you mentioned in the comments: you user_guess recursive way so that it user_guess itself if the user enters an invalid guess. However, in this case, it does not return the result of the recursive call. You need to either return a recursive result by changing the last line of user_guess to:

 return user_guess() 

Or else you must force this function to use a loop instead of recursion, which I would do, because the function is not essentially recursive. You can do something like this:

 def user_guess(): # get first guess guess = input("Choose 'rock', 'paper', or 'scissors' by typing that word. ") # If that guess is invalid, loop until we get a valid guess. while not is_valid_guess(guess): print('That response is invalid.') guess = input("Choose 'rock', 'paper', or 'scissors' by typing that word. ") # Now assign the (valid!) guess a number # This dictionary is just shorthand for your if/elif chain. guess_table = { 'rock' : 1, 'paper' : 2, 'scissors' : 3 } # Return the number associated with the guess. return guess_table[guess.lower()] 
+3
source

Edit

 if guess == 'rock' or 'paper' or 'scissors': 

to

 if guess == 'rock' or guess == 'paper' or guess == 'scissors': 

In fact, to make the function as simple as possible, just do the following:

 def is_valid_guess(guess): return guess == 'rock' or guess == 'paper' or guess == 'scissors' 
+1
source

As other users have pointed out, you need to change your check in is_valid_guess to:

 if guess == 'rock' or guess == 'paper' or guess == 'scissors': 

While this will not solve your immediate problem, this is good (useful) advice and will allow you to avoid the errors that you encounter.

In addition, no matter what the user enters, you always return what they type. To prevent this, you must return user_guess() to the else block:

 if is_valid_guess(guess): #if/elif statement #assign 1 to rock if guess == 'rock': number = 1 #assign 2 to paper elif guess == 'paper': number = 2 #assign 3 to scissors elif guess == 'scissors': number = 3 return number else: print('That response is invalid.') return user_guess() # <-- right here 
+1
source

Just change input to raw_input

+1
source

Source: https://habr.com/ru/post/985537/


All Articles