I am very new to Python and coding in general. I tried to create my own Rock, Paper, Scissors game. The game itself is working fine. the problem ensues when I tried to create a loop system to repeat the game. The issue I'm getting can be tested by doing the following: typing "rock", then typing "yes" to play again and repeating those two steps. Eventually, it gives me an "Invalid Input." It is only supposed to print this if the user types something besides rock, paper, or scissors. I think it's an issue with Python memorizing the values assigned to the two variables, but I am not sure. I added the "Choice = None" and "Opponent_Choice = None" in an attempt to reset the variable at the beginning of every loop, but it did not solve my issue. Is there any way I can fix this? I'd really appreciate any input and advice. Thank you for your time.
import random
# to loop the program
def Repeat():
Answer = input ("Do you want to play again? (Y/N): ")
if Answer == ("Yes") or Answer == ("yes") or Answer == ("Y") or Answer == ("y"):
Game()
if Answer == ("No") or Answer == ("no") or Answer == ("N") or Answer == ("n"):
exit()
else:
print ("Invalid Input")
Repeat()
def Game():
# Variable Reset
Choice = None
Opponent_Choice = None
# Choices
Opponent_Choices = ["Rock", "Paper", "Scissors"]
Choice = input ("Type Rock, Paper, or Scissors: ")
Opponent_Choice = random.choice(Opponent_Choices)
# Outcomes
# if you choose rock
if Choice == "Rock" or Choice == "rock":
if Opponent_Choice == "Paper":
print ("your opponent chose Paper. You lose!")
Repeat()
elif Opponent_Choice == "Scissors":
print ("your opponent chose Sciccors. You win!")
Repeat()
elif Opponent_Choice == "Paper":
print ("your opponnet chose Rock. It was a tie!")
Repeat()
# if you choose paper
elif Choice == "Paper" or Choice == "paper":
if Opponent_Choice == "Paper":
print ("your opponent chose Paper. It was a tie!")
Repeat()
elif Opponent_Choice == "Scissors":
print ("your opponent chose Sciccors. You lose!")
Repeat()
elif Opponent_Choice == "Paper":
print ("your opponet chose Rock. You win!")
Repeat()
# if you choose scissors
elif Choice == "Scissors" or Choice == "scissors":
if Opponent_Choice == "Paper":
print ("your opponent chose Paper. You win!")
Repeat()
elif Opponent_Choice == "Scissors":
print ("your opponent chose Sciccors. It was a tie!")
Repeat()
elif Opponent_Choice == "Paper":
print ("your opponet chose Rock. You lose!")
Repeat()
else:
print ("Invalid input")
Game()
Game()
p.s. Sorry for the messy code :P Still very new to this.
The actual issue: The actual issue
CodePudding user response:
One problem with the code is that you have functions calling themselves. The function Game() and Repeat() in your code do this. This is called recursion and can be very useful. But it can also cause problems if used incorrectly. For one thing, let's consider the code above DOES work, if you played it for very long, you would get a stack overflow exception. I would suggest some research on recursion and "the stack" to understand this better.
If you take out the recursion like so for example: it should work.
I also noticed you are checking user input on the confirmation question. Very nice. But why not for the Rock Paper Scissors selection?
Example refactor without recursion:
import random
# to loop the program
def Repeat():
while True:
result = Confirm()
if (result is True):
break
def Confirm():
Answer = input ("Do you want to play again? (Y/N): ")
if Answer == ("Yes") or Answer == ("yes") or Answer == ("Y") or Answer == ("y"):
return True
if Answer == ("No") or Answer == ("no") or Answer == ("N") or Answer == ("n"):
exit()
else:
return False
def Game():
# Choices
Opponent_Choices = ["Rock", "Paper", "Scissors"]
Choice = input("Type Rock, Paper, or Scissors: ")
Opponent_Choice = random.choice(Opponent_Choices)
# Outcomes
# if you choose rock
if Choice == "Rock" or Choice == "rock":
if Opponent_Choice == "Paper":
print ("your opponent chose Paper. You lose!")
Repeat()
elif Opponent_Choice == "Scissors":
print ("your opponent chose Sciccors. You win!")
Repeat()
elif Opponent_Choice == "Paper":
print ("your opponnet chose Rock. It was a tie!")
Repeat()
# if you choose paper
elif Choice == "Paper" or Choice == "paper":
if Opponent_Choice == "Paper":
print ("your opponent chose Paper. It was a tie!")
Repeat()
elif Opponent_Choice == "Scissors":
print ("your opponent chose Sciccors. You lose!")
Repeat()
elif Opponent_Choice == "Paper":
print ("your opponet chose Rock. You win!")
Repeat()
# if you choose scissors
elif Choice == "Scissors" or Choice == "scissors":
if Opponent_Choice == "Paper":
print ("your opponent chose Paper. You win!")
Repeat()
elif Opponent_Choice == "Scissors":
print ("your opponent chose Sciccors. It was a tie!")
Repeat()
elif Opponent_Choice == "Paper":
print ("your opponet chose Rock. You lose!")
Repeat()
else:
print ("Invalid input")
while True:
Game()
CodePudding user response:
I can't give you an answer about why there's and error, but here is a curl: the 'invalid input ' massage you get was from the line 11, in 'Repeat()'. The line will only be runned of the if statment above it was false, and the if statment will on be runned if the another if statment above it exit, which means you'll only get the massage if the Game() function somehow exited,which shouldn't happen. You can add a print() after line 7 to comfirm that. The REAL reason was because you used recursion, like @dominic has said. And you should try his code.
PS: don't feel back about the messy code. Mine is worse than yous. But you really don't have to captialize the variables and function. Good luck with Python!
CodePudding user response:
The reason you seem to be getting the invalid input is due to your check for the Opponent_choice not checking for Rock but instead checking for paper twice. Therefore it jumps all the way to the else statement at the end of the function which contains the invalid input print statement if the opponent chooses Rock.
if Opponent_Choice == "Paper":
print ("your opponent chose Paper. You lose!")
Repeat()
elif Opponent_Choice == "Scissors":
print ("your opponent chose Sciccors. You win!")
Repeat()
elif Opponent_Choice == "Paper": #error here
print ("your opponnet chose Rock. It was a tie!")
Repeat()
The fix would be
if Opponent_Choice == "Paper":
print ("your opponent chose Paper. You lose!")
Repeat()
elif Opponent_Choice == "Scissors":
print ("your opponent chose Sciccors. You win!")
Repeat()
elif Opponent_Choice == "Rock": #change made here
print ("your opponnet chose Rock. It was a tie!")
Repeat()