import random
#1 = Rock, 2 = Paper, 3 = Scissors
random_number = random.randint(1,3)
try:
input = int(input("1 for rock, 2 for paper, 3 for scissors: "))
except ValueError:
print("You didn't enter a number. You lose.")
if input == random_number:
if input == 1:
input = "Rock"
elif input == 2:
input = "Paper"
else:
input = "Scissors"
if random_number == 1:
random_number = "Rock"
elif random_number == 2:
random_number = "Paper"
else:
random_number = "Scissors"
print(f"You chose {input} and the computer chose {random_number}. You Tie.")
elif (input==1 and random_number==2) or (input==2 and random_number==3) or (input==3 and random_number==1):
if input == 1:
input = "Rock"
elif input == 2:
input = "Paper"
else:
input = "Scissors"
if random_number == 1:
random_number = "Rock"
elif random_number == 2:
random_number = "Paper"
else:
random_number = "Scissors"
print(f"You chose {input} and the computer chose {random_number}. You Lose.")
elif (input==1 and random_number==3) or (input==2 and random_number==1) or (input==3 and random_number==2):
if input == 1:
input = "Rock"
elif input == 2:
input = "Paper"
else:
input = "Scissors"
if random_number == 1:
random_number = "Rock"
elif random_number == 2:
random_number = "Paper"
else:
random_number = "Scissors"
print(f"You chose {input} and the computer chose {random_number}. You Win.")
else:
if type(input) is int:
print("You chose an invalid number. You Lose.")
This code plays the "Rock, Paper, Scissors" game against the user. I was wondering how exactly should I handle my repeated nesting. I am looking for more organized code.
2 Answers 2
Error
I get an indentation error on my version of Python. Perhaps you are using a more forgiving version or you had a problem copying your code into the question.
DRY
Yes, the repeated code can be simplified greatly using a dictionary to map the input numerical guesses to strings for the output display and by factoring the code into a function. Here is an alternate version with these changes:
import random
random_number = random.randint(1,3)
try:
input = int(input("1 for rock, 2 for paper, 3 for scissors: "))
except ValueError:
print("You didn't enter a number. You lose.")
def print_result(result):
guess_string = {
1 : "Rock",
2 : "Paper",
3 : "Scissors"
}
print(f"You chose {guess_string[input]} and the computer chose {guess_string[random_number]}. You {result}.")
if input == random_number:
print_result('Tie')
elif (input==1 and random_number==2) or (input==2 and random_number==3) or (input==3 and random_number==1):
print_result('Lose')
elif (input==1 and random_number==3) or (input==2 and random_number==1) or (input==3 and random_number==2):
print_result('Win')
else:
if type(input) is int:
print("You chose an invalid number. You Lose.")
Naming
You could give the variables more meaningful names. For example, random_number
might be better
as computer_guess
, and input
as user_guess
.
input
is a poor name for a variable because it matches the builtin function of the same name.
Comments
The comment can be deleted because it is redundant with the input
function
prompt message.
Documentation
The code should have a header docstring comment describing the purpose of the code:
"""
Rock, paper scissors game.
Here's how it works...
"""
-
2\$\begingroup\$ This condition
(input==1 and random_number==2) or (input==2 and random_number==3) or (input==3 and random_number==1)
translates torandom_number - (input % 3) == 1
. Same for the winning condition. \$\endgroup\$Alexander Ivanchenko– Alexander Ivanchenko2024年09月25日 15:22:10 +00:00Commented Sep 25, 2024 at 15:22
1. Variable name
Do not use input
as the variable name. Since input
is also a function, if you define a variable name input
you can no longer call the input
function.
Use more descriptive names for variables. In my example, I use computer_choice
and player_choice
to represent the number generated and user enter respectively.
2. Repetition
When you find that you need to repeat your code, try to check your control flow and condition. Most of the time you can avoid those repetitions; in my example, I compute the stuff that needs to be computed before going to one level of nesting.
3. Learn more about data structure
There are a lot of useful data structures e.g. lists, dictionaries, sets, that can help you simplify complex tasks. In my example, I use list
to store the text of the Rock
, Paper
, and Scissors
, to make a shortcut to converting number to str.
4. Function and early return
One of the ways to avoid nesting is to extract code into functions; that way you can early return. In your code, if user didn't enter a number, you catch the exception but didn't exit gracefully and will continue to run and meet another error (you can use quit()
to exit the program). In my example, I put the codes into a function and can early return.
Example
import random
def main():
# Random Computer Choice
computer_choice = random.randint(1,3)
# Player Input Choice
try:
player_choice = int(input("1 for rock, 2 for paper, 3 for scissors: "))
except ValueError:
print("You didn't enter a number. You lose.")
return
# We define some win condition
# They are tuple define as (player_choice, computer_choice)
computer_win_condition = [(1, 2), (2, 3), (3, 1)]
# We first check if player and computer choice are the same
# if so, result is Tie
if computer_choice == player_choice:
game_result = "Tie"
# then we check for the computer win condition
# if the tuple is in computer_win_condition, we know player lose
elif (player_choice, computer_choice) in computer_win_condition:
game_result = "Lose"
# If it is not tie and lose, it mean that the player wins
else:
game_result = "Win"
# We create a new list such that rps[1] = "Rock" ...
# This will allow us to easily convert integer to responding str
rps = ["", "Rock", "Paper", "Scissors"]
computer_str = rps[computer_choice]
player_str = rps[player_choice]
print(f"You chose {player_str} and the computer chose {computer_str}. You {game_result}.")
if __name__ == "__main__":
main()
Explore related questions
See similar questions with these tags.
constant
has a special meaning in programming, it refers to variables that cannot be changed, and we refer to it as deeply nested. And it is not nested too deep in your example, you may want to look into python dictionary for converting numbers to text for starter \$\endgroup\$