how to use an if else statement in another while loop - python

I am new to coding. I want to try writing a simple rock paper scissors game. But I can't figure out how to end the game.
In the end of this program if the user input is wrong I want to go to the end variable again. I tried with the commented lines but its not working.
player1 = input("What is player 1's name ? ")
player2 = input("What is player 2's name ? ")
player1 = player1.title()
player2 = player2.title()
while True:
print(player1 + " What do you choose ? rock / paper / scissors : ")
a = input()
print(player2 + " What do you choose ? rock / paper / scissors : ")
b = input()
if a == "rock" and b == "scissors" :
print(player1, "won !!!")
elif a == "scissors" and b == "rock":
print(player2, "won !!!")
elif a == "paper" and b == "rock":
print(player1, "won !!!")
elif a == "rock" and b == "paper":
print(player2, "won !!!")
elif a == "scissors" and b == "paper":
print(player1, "won !!!")
elif a == "paper" and b == "scissors":
print(player2, "won !!!")
elif a == b:
print("Its a tie :-(")
elif a or b != "rock" or "paper" or "scissors":
print("Wrong input, Try again")
end = input("Do you want to play again ? yes/no ") == "yes"
if input == "yes":
continue
else:
print('''
GAME OVER''')
break
# elif input != "yes" or "no":
# print("Wrong input, Try again. yes or no ?")
I expect it to end game if the input is "no" and restart the game if input is "yes" if the input is not correct I want the prompt to appear again.

Your code has a few issues which need some addressing, and a few places where it can be streamlined. I have made a few changes to your program as well as added a few comments explaining the changes.
player1 = input("What is player 1's name ? ").title() #This uses chaining to streamline code
player2 = input("What is player 2's name ? ").title() #Same as above
while True:
a = input(player1 + " What do you choose ? rock / paper / scissors : ") #no need to use a separate print statement
b = input(player2 + " What do you choose ? rock / paper / scissors : ")
valid_entries = ["rock", "paper", "scissors"] #To check for valid inputs
if (a not in valid_entries) or (b not in valid_entries):
print("Wrong input, try again")
continue
a_number = valid_entries.index(a) #Converting it to numbers for easier comparison
b_number = valid_entries.index(b)
if(a_number == b_number):
print("Its a tie :-(")
else:
a_wins = ((a_number > b_number or (b_number == 2 and a_number == 0)) and not (a_number == 2 and b_number == 0)) #uses some number comparisons to see who wins instead of multiple if/elif checks
if(a_wins):
print(player1, "won !!!")
else:
print(player2, "won !!!")
end = input("Do you want to play again ? yes/no ")
while (end !="yes") and (end != "no"):
print("invalid input, try again")
end = input("Do you want to play again ? yes/no ")
if end == "yes":
continue
else:
print("GAME OVER")
break
These changes also make the check by using another while loop to see if the input to restart the game was valid or not
*Note that I have not tested these changes and some edits may need to be be made

Just check the value of end
if end is True:
continue
else:
break
Since, you have set the value of end as a boolean by comparing the input() to "yes", it will say whether the user wants to end the game?
Also, you are not initializing the input variable, and the last elif condition will always be true as mentioned in the comment.

Well you can simplify your code using a list and then simplify your if tests. You can check the order of the options and based on it make a decision. You can also make the tests standard to minimize the number of if statements. This my suggestion to improve your code. I hope it helps:
# get playe names
player1 = input("What is player 1's name ? ")
player2 = input("What is player 2's name ? ")
player1 = player1.title()
player2 = player2.title()
# init vars
options = ["rock", "paper", "scissors"]
players = [player1, player2]
# start game
while True:
a = input(player1 + " What do you choose ? rock / paper / scissors : ")
b = input(player2 + " What do you choose ? rock / paper / scissors : ")
# check if inputs are correct
while (a not in options or b not in options):
print("Wrong input, Try again")
a = input(player1 + " What do you choose ? rock / paper / scissors : ")
b = input(player2 + " What do you choose ? rock / paper / scissors : ")
# check who won
if abs(options.index(a) - options.index(b)) == 1:
print(players[1*int(options.index(a) > options.index(b))], "won !!!")
elif abs(options.index(b) - options.index(a)) > 1:
print(players[1*int(options.index(a) > options.index(b))], "won !!!")
elif a == b:
print("Its a tie :-(")
# continue or drop game
end = input("Do you want to play again ? yes/no ")
if end == "yes":
continue
else:
print('''
GAME OVER''')
break

Related

Do not want to let Computer play his turn once Player enters invalid choice. How to achieve?

I'm a beginner and writing a code for "Rock Paper Scissors" game. I don't want to run this game(code) over and over again, hence, used while loop. Now, at the "else:" step when any invalid choice is typed by the Player, Computer plays it's turn too after which "Invalid choice. Play your turn again!" is displayed.
I want when a Player types any invalid choice, the computer should not play it's turn and we get "Invalid choice. Play your turn again!" displayed, keeping the game running.
Please check my code and point me to the issue. Please explain with the correction. Thanks in advance!
print("Welcome to the famous Rock Paper Scissors Game. \n")
Choices = ["Rock", "Paper", "Scissors"]
while(True):
Player = input("Your turn: ")
Computer = random.choice(Choices)
print(f"Computer's turn: {Computer} \n")
if Player == Computer:
print("That's a tie, try again! \n")
elif Player == "Rock" and Computer == "Scissors":
print("You Won!!! \n")
elif Player == "Rock" and Computer == "Paper":
print("Computer won! \n")
elif Player == "Paper" and Computer == "Scissors":
print("Computer won! \n")
elif Player == "Paper" and Computer == "Rock":
print("You Won!!! \n")
elif Player == "Scissors" and Computer == "Paper":
print("You Won!!! \n")
elif Player == "Scissors" and Computer == "Rock":
print("Computer won! \n")
else:
print("Invalid choice. Play your turn again! \n")
You can check if the input is valid before the computer plays, and ask again if it is invalid using continue -
Choices = ["Rock", "Paper", "Scissors"]
while(True):
Player = input("Your turn: ")
if Player not in Choices: # If it is not in Choices list above
print("Invalid choice. Play your turn again! \n")
continue # This will re run the while loop again.
# If Player gives valid input, then continues this
Computer = random.choice(Choices)
print(f"Computer's turn: {Computer} \n")
# The next lines ....
Also check out - Break, Continue and Pass

Break command doesn't stop loop [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
The Break Command Doesnt work and when i try to run it, it gets stuck like it cant compile because its stuck in a loop
My code isn't running at all, I have reviewed my code but it doesn't seem to work. Everything is fine for me.
import random
# print("Winning Rules of the Rock paper scissor game as follows: \n"
# + "Rock vs paper->paper wins \n"
# + "Rock vs scissor->Rock wins \n"
# + "paper vs scissor->scissor wins \n")
while True:
def main():
print("Enter choice \n 1. Rock \n 2. paper \n 3. scissor \n")
try :
choice_name = (input("User turn: "))
if choice_name == 1:
choice_name = 'Rock'
if choice_name == 2:
choice_name = 'paper'
if choice_name == 3:
choice_name = 'scissor'
else:
choice_name = None
input("Atleast Enter a Valid Number like BRUHHHHHHHHH: ")
except ValueError:
print ("Try again")
main()
print("user choice is: " + choice_name)
print("\nNow its computer turn.......")
Computer_Choice = random.randint(1, 3)
while Computer_Choice == choice_name:
Computer_Choice = random.randint(1, 3)
if Computer_Choice == 1:
Computer_Choice_name = 'Rock'
elif Computer_Choice == 2:
Computer_Choice_name = 'paper'
else:
Computer_Choice_name = 'scissor'
print("Computer choice is: " + Computer_Choice_name)
print(choice_name + " V/s " + Computer_Choice_name)
if((choice_name == 1 and Computer_Choice == 2) or
(choice_name == 2 and Computer_Choice == 1)):
print("paper wins => ", end="")
result = "paper"
elif((choice_name == 1 and Computer_Choice == 3) or
(choice_name == 3 and Computer_Choice == 1)):
print("Rock wins =>", end="")
result = "Rock"
else:
print("scissor wins =>", end="")
result = "scissor"
if result == choice_name:
print("<== User wins ==>")
else:
print("<== Computer wins ==>")
print("Do you want to play again? (Y/N)")
ans = input()
if ans == 'n' or ans == 'N':
break
print("\nThanks for playing")
You are defining a function inside of a while loop. Currently the loop always evaluates to False.
What you want is:
def main():
while True:
# ...
Then you need to actually call main. At the end of the file:
if __name__ == '__main__':
main()

Simplify Python code (Rock, Paper, Scissors)

I am a complete python newbie and this is my first question on stackoverflow, so please be patient with me :)
So to get some excersise, I tried programming my own rock, paper, scissors game in Python. However, my code is relatively long compared to other rock, paper, scissor programs. This is because I programmed every single possible option in the game. Is there a possibility to simplify this code? As in not having to programm every single possibiliy in the game? Because doing so might be possible in Rock, Paper, Scissors, but probably not in more advanced problems.
Let me know what you think, thank you!!!
All the best,
Luca Weissbeck
The code:
#Rock, Paper, Scissors
while True:
Game_list = ["Rock", "Paper", "Scissors"]
User_1 = str(input("Rock, Paper, Scissors?"))
#Let the computer make its choice
import random
Computer_1 = random.choice(Game_list)
#Possibility of a draw
if str(Computer_1) == User_1:
Draw_choice = str(input("It's a draw. Do you want to replay?(Y/N)"))
if Draw_choice == "Y":
continue
else:
break
#Possibility of player winning
if str(Computer_1) == "Rock" and User_1 == "Paper" or str(Computer_1) ==
"Paper" and User_1 == "Scissors" or str(Computer_1) == "Scissors" and User_1
== "Rock":
UW1 = str(input("You won. The computer chose:" + Computer_1 + " Do
you want to play again? (Y/N)"))
if UW1 == "Y":
continue
else:
break
#Possibility of computer winning
if str(Computer_1) == "Rock" and User_1 == "Scissors" or str(Computer_1)
== "Paper" and User_1 == "Rock" or str(Computer_1) == "Scissors" and User_1
== "Paper":
UL1 = str(input("You lost. The Compuer chose:" + Computer_1 + " Do
you want to play again? (Y/N)"))
if UL1 == "Y":
continue
else:
break
#End sentence
print("Bye, thank you for playing!")
There are a lot of repeated strings in this program. They can be collapsed.
import random
States = ['Rock','Paper','Scissors']
playAgain = True
while playAgain:
User = str(input("Choose your play: "))
try:
User = States.index(User)
except:
print('Your choice is not one of the choices in Rock, Paper, Scissors')
break
Comp = random.randint(0,2)
winner = (Comp-User)%3
if winner==0:
print("There is a tie. Both User and Computer chose " + States[User])
elif winner==1:
print("Computer wins. Computer chose "+States[Comp]+" and User chose "+States[User])
else:
print("User wins. Computer chose "+States[Comp]+" and User chose "+States[User])
if str(input("Do you want to play again? (Y/N)")) == "N":
playAgain = False
print("Thanks for playing!")
You can try to store the win possibilities.
win_case = [['rock','scissor'], ['scissor','paper'], ['paper','rock']]
Then the main program will be like
if (user == comp):
// draw
elif ([user,comp] in win_case):
// user win
else:
// comp win
Length of code is one thing. Organization and readability is another (more important) one. What often helps is a separation of code and config. Set constants, settings, messages first, then use them in the code:
import random
# game config
R, P, S = "Rock", "Paper", "Scissors"
BEATS = {R: S, P: R, S: P}
MESSAGES = {
"draw": "It's a draw. Play again? (Y/N)\n",
"win": "You won. Comp chose: {}. Play again? (Y/N)\n",
"loss": "You lost. Comp chose: {}. Play again? (Y/N)\n",
"invalid": "Invalid input: {}. Play again? (Y/N)\n",
}
# game code
play = "Y"
while play.upper() == "Y":
u1 = str(input("{}, {}, {}?\n".format(R, P, S)))
c1 = random.choice([R, P, S])
if u1 not in BEATS:
play = input(MESSAGES["invalid"].format(u1))
elif c1 == u1:
play = input(MESSAGES["draw"])
elif BEATS[u1] == c1:
play = input(MESSAGES["win"].format(c1))
else:
play = input(MESSAGES["loss"].format(c1))

New to Python: Getting TypeError: unhashable type: 'list'

So I have a class assignment I have to make a rock paper scissors game and stop cheating. I keep getting TypeError: unhashable type: 'list'
I have no idea what is causing this; could someone help me to fix this?
import random
import re
def MatchAssess():
if userThrow == compThrow:
print("Draw")
elif userThrow == "r" and compThrow == "p":
print("Computer chose paper; you chose rock - you lose")
elif userThrow == "p" and compThrow == "s":
print("Computer chose scissors; you chose paper - you lose!")
elif userThrow == "r" and compThrow == "p":
print("Computer chose paper; you chose rock - you lose!")
elif userThrow == "s" and compThrow == "r":
print("Computer chose rock; you chose scissors - you lose!")
else:
print("you win")
CompThrowSelection = ["r","p","s"]
ThrowRule = "[a-z]"
while True:
compThrow = random.choice(CompThrowSelection)
userThrow = input("Enter Rock [r] Paper [p] or Scissors [s]")
if not re.match(CompThrowSelection,userThrow) and len(userThrow) > 1:
MatchAssess()
else:
print("incorrect letter")
userThrow = input("Enter Rock [r] Paper [p] or Scissors [s]")
I noticed some fault with your logic on the code.
One is that re.match() is to be applied on a pattern rather than on a list. For list we can use something like,
if element in list:
# Do something
Next is that len(userThrow) > 1 will never be satisfied if user makes a valid input. So make len(userThrow) >= 1 or even == 1.
Last I added a continue statement on the conditional branch for catching wrong input, rather than reading input again from there.
So finally, this is the working code!
while True:
compThrow = random.choice(CompThrowSelection)
userThrow = raw_input("Enter Rock [r] Paper [p] or Scissors [s]")
if userThrow in CompThrowSelection and len(userThrow) >= 1:
MatchAssess()
else:
print("incorrect letter")
continue
Hope this helps! :)
It should be corrected as
if userThrow in CompThrowSelection and len(userThrow) == 1: # this checks user's input value is present in your list CompThrowSelection and check the length of input is 1
MatchAssess()
and
userThrow = raw_input("Enter Rock [r] Paper [p] or Scissors [s]") # raw_input() returns a string, and input() tries to run the input as a Python expression (assumed as python 2)
You can implement it like this:
import random
cts = ["r","p","s"]
def match_assess(ut):
ct = random.choice(cts)
if ut == ct:
print('Draw. You threw:'+ut+' and computer threw:'+ct)
elif (ut=="r" and ct == "p") or (ut == "p" and ct == "s") or (ut == "r" and ct == "p") or (ut == "s" and ct == "r"):
print ('You Loose. You threw:'+ut+' and computer threw:'+ct)
else:
print ('You Win. You threw:'+ut+' and computer threw:'+ct)
a = 0
while a<5: #Play the game 5 times.
ut = raw_input("Enter Rock [r] Paper [p] or Scissors [s]")
if ut in cts and len(ut) == 1:
match_assess(ut)
else:
print("incorrect letter")
a+=1

A local or global name can not be found error [duplicate]

This question already has answers here:
Python NameError from contents of a variable
(2 answers)
Closed 8 years ago.
I'm trying to make a simple rock paper scissors game, and I get an error with in the line, guess = input. It says I need to define the function or variable before I use it in this way and I am unsure of how I can do that. This is using Python/JES programming
#import random module
import random
#main function
def main():
#intro message
print("Let's play 'Rock, Paper, Scissors'!")
#call the user's guess function
number = user_guess()
#call the computer's 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():
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.')
return user_guess()
def is_valid_guess(guess):
if guess == 'rock' or guess == 'paper' or guess == '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()
Using raw_input instead of input seems to solve the problem.
guess = raw_input ("Choose 'rock', 'paper', or 'scissors' by typing that word. ")
and also in
answer = raw_input("Would you like to play again? Enter 'y' for yes or 'n' for no: ")
I'm using Python 2.7.x

Categories