Hello i'm doing some personal python learning and i have a practice problem i'm trying to figure out. The main goal is to play paper rock scissors with the computer. Your supposed to input "paper" "rock" or "Scissors" as a user answer and the computer will randomly generate a number from 1-3 that corresponds to a particular choice. I can get the program to work fine if the user inputs a number from 1-3 but that's not what the question asks. I feel like i've tried everything like assigning each name to the corresponding number, creating an if then statement that then reassigns the choice to the numerical value but it always just gets stuck after the input prompt and doesn't move forward with the code. I know the issue lies most likely in the line 6 because thats the last spot it executes.. not sure how to fix it. Also if anyone can give me some pointers on how this could look a little cleaner or if this is roughly what is should look like in terms of efficiency and cleanliness. Keep in mind i have not learned anything too advanced like dictionaries lists ect. Problem should be solved using basic stuff for now. Thank you!
import random
def main():
global user_answer
print('lets play paper rock scissors')
number = comp_answer()
user_answer = int(input('What do you choose?')) <--- # i know the change would be
while number = comp_answer(): # here.... maybe str(input(' '))
tie(number) # then define the choices? tried
paper_rock_scissors(number) # that and failed not sure if i'm
# doing it wrong.
def comp_answer():
number = random.randint(1,4)
return number
def tie(number):
print("its a tie!")
print ("tie breaker")
user_answer = input('What do you choose?')
def paper_rock_scissors(number):
if number == 3 and user_answer == 1:
print("computer: scissors")
print("you: ",user_answer )
print("you won!")
print("rocks smashes scissors")
elif number == 3 and user_answer == 2:
print("computer: scissors")
print("you: ",user_answer )
print("Game over")
print("scissors cuts paper")
elif number == 1 and user_answer == 3:
print("computer: rock")
print("you: ",user_answer )
print("Game over")
print("rocks smashes scissors")
elif number == 2 and user_answer == 3:
print("computer: paper")
print("you: ",user_answer )
print("you won!")
print("scissors cuts paper")
elif number == 1 and user_answer == 2:
print("computer: rock")
print("you: ",user_answer )
print("you won!")
print("paper covers rock")
elif user_answer == 1 and number == 2:
print("computer: paper")
print("you: ",user_answer )
print("Game over")
print("paper covers rock")
main()
In the while loop condition you don't compare the user's choice to the program's.
def main():
global user_answer
print('lets play paper rock scissors')
number = comp_answer()
user_answer = int(input('What do you choose?'))
while user_answer == number:
tie(number)
number = comp_answer()
paper_rock_scissors(number)
Fix this by comparing user_answer and number instead. You also need to specify that user_answer is global in tie. The fact that comp_answer is recomputed in the while condition will make it so that number has the incorrect value when passed to rock_paper_scissors. Those Three changes should fix the issue.
As for cleanliness, global variables are generally bad practice. You could change this by changing tie(number) to user_answer = tie(number) and adding user_answer as an argument to rock_paper_scissors. The tie function also doesn't use it's argument so it could easily be removed.
The problem in your program lies in
"while number = comp_answer():"
It should be a "==" for comparison. "=" is used for assignment and what we need here is an equal to evaluation.
Also,
while number == comp_answer():
doesn't really equate to a tie. It just checks whether the stored value number is equal to the output from comp_answer(). You might wanna equate "user_input" with "number" to check for the same.
P.S. the comp_answer() should be called again in tie function
Try this:
I've put the print statements to a new function that makes the program a big easier to read and shorter.
import random
def main():
global user_answer
print('lets play paper rock scissors')
number = comp_answer()
user_answer = int(input('What do you choose?'))
while number == user_answer:
tie()
paper_rock_scissors(number)
def comp_answer():
number = random.randint(1,4)
return number
def tie():
global number
print("its a tie!")
print ("tie breaker")
number = comp_answer()
user_answer = input('What do you choose?')
def print_ans(computer, user, explanation, win):
print("computer: ", computer)
print("you: ", user)
print(explanation)
if win:
print("you won!")
else:
print("Game over")
def paper_rock_scissors(number):
if number == 3:
if user_answer == 1:
print_ans("scissors", "rock", "rocks smashes scissors", win=True)
else:
print_ans("scissors", "paper", "scissors cut paper", win=False)
elif number == 1:
if user_answer == 3:
print_ans("rock", "scissors", "rocks smashes scissors", win=False)
else:
print_ans("rock", "paper", "paper covers rock", win=True)
else:
if user_answer == 1:
print_ans("paper", "rock", "paper covers rock", win=False)
else:
print_ans("paper", "scissors", "scissors cut paper", win=True)
main()
If you want the user to input string instead of integers, the code will look somewhat like this (mind you I will be using dictionaries as it makes things easier and I think it is important for everyone to know about them, so read up a bit on them):
import random
num_mappings = {"rock":1 , "paper":2 , "scissors":3}
def main():
global user_answer
print('lets play paper rock scissors')
number = comp_answer()
user = input('What do you choose?')
user_answer = num_mappings[user]
while number == user_answer:
tie()
paper_rock_scissors(number)
def comp_answer():
number = random.randint(1,4)
return number
def tie():
global number
print("its a tie!")
print ("tie breaker")
number = comp_answer()
user = input('What do you choose?')
user_answer = num_mappings[user]
def print_ans(computer, user, explanation, win):
print("computer: ", computer)
print("you: ", user)
print(explanation)
if win:
print("you won!")
else:
print("Game over")
def paper_rock_scissors(number):
if number == 3:
if user_answer == 1:
print_ans("scissors", "rock", "rocks smashes scissors", win=True)
else:
print_ans("scissors", "paper", "scissors cut paper", win=False)
elif number == 1:
if user_answer == 3:
print_ans("rock", "scissors", "rocks smashes scissors", win=False)
else:
print_ans("rock", "paper", "paper covers rock", win=True)
else:
if user_answer == 1:
print_ans("paper", "rock", "paper covers rock", win=False)
else:
print_ans("paper", "scissors", "scissors cut paper", win=True)
main()
However, keep in mind, your code will fail if the user types anything other than "rock", "paper" or "scissors". I suggest you look into exception handling to get a good grasp and improve on those aspects.
Related
import random
user_wins = 0
computer_wins = 0
options = ["Rock", "Paper", "Scissors"]
while True:
user_input = input("Type Rock/Paper/Scissors or Q to quit: ")
if user_input == "q":
break
if user_input not in [options]:
continue
random_number = random.randint(0, 2)
# rock: 0, paper: 1, scissors: 2
computer_pick = options[random_number]
print("computer picked", computer_pick + ".")
if user_input == "rock" and computer_pick == "scissors":
print("You won!")
user_wins += 1
elif user_input == "scissors" and computer_pick == "paper":
print("You won!")
user_wins += 1
elif user_input == "paper" and computer_pick == "rock":
print("You won!")
user_wins += 1
else:
print("You lost!")
computer_wins += 1
print("You won", user_wins, "times.")
print("The cpu won", computer_wins, "times.")
print("Goodbye!")
I'm sorry if im not using this site the correct way but I've been following along with Tech With Tim on youtube trying to write 5 mini python games to just practice. I expect if i put q it will break, but now that i'm typing this i'm realizing that if it were to break i shouldn't get the print statements on line 37,38, and 39. either way, when i input rock , paper, or scissors it comes back as "Type Rock/Paper/Scissors or Q to quit:". I'm having a hard time understanding why my code doesnt work, while Tim has the exact same code, line for line, and his works fine. Any and all help would be appreciated.. even if its directing me to slow my roll
if user_input not in [options] isn't correct. [options] is a list containing one element: all of options. A string can never be all of options, so user_input not in [options] will always be true.
You want
if user_input not in options:
I'm trying to make a rock, paper, and scissors game that receives input from a user that plays against a robot that randomly selects rock, paper, or scissors. Here is my main() code:
"""
Name: Scott Houston
Date: January 19th, 2021
Program Description: Game of classic rock, paps
"""
import random
import gameFunctions2
def main():
while True:
computer_move = random.randint(1, 3)
print("Welcome to rock, paper, scissors! Rock beats scissors, scissors beats paper,"
" and paper beats rock. ")
user_input = input("Press 'A' for rock, 'B' for paper, and 'C' for scissors!\n"
"A. Rock\n"
"B. Paper\n"
"C. Scissors\n")
if gameFunctions2.tie(user_input, computer_move) == False:
if user_input == "A" or user_input == "a":
if computer_move == 2:
print("Your opponent has chosen paper! Paper wraps rock! You lose! ")
else:
print("Your opponent has chosen scissors! Rock breaks scissors! You win! ")
elif user_input == "B" or user_input == "b":
if computer_move == 3:
print("Your opponent has chosen scissors! Paper is cut by scissors! You lose! ")
else:
print("Your opponent has chosen rock! Paper wraps rock! You win! ")
elif user_input == "C" or user_input == "c":
if computer_move == 1:
print("Your opponent has chosen rock! Scissors loses to rock! You lose! ")
else:
print("Your opponent has chosen paper! Scissors beats paper! You win! ")
if gameFunctions2.input_detection(user_input) == True:
print()
else:
print()
user_play_again = input("Would you like to play again? Type 'y' if you'd like to play again. ")
if user_play_again == "y":
print()
else:
print("Have a great day! ")
break
# Calls the Main Function
main()
Here is my helper function (gameFunctions2):
def input_detection(user_input):
if user_input == "A" or user_input == "a" or user_input == "B" or user_input == "b" or user_input == "C" or user_input == "c":
return True
else:
print("Please enter a valid option! ")
return False
def tie(user_input, computer_move):
if user_input == user_input.lower in ["a"] and computer_move == "1":
print("It's a tie!")
return True
if user_input == user_input.lower in ["b"] and computer_move == "2":
print("It's a tie!")
return True
if user_input == user_input.lower in ["c"] and computer_move == "3":
print("It's a tie!")
return True
else:
return False
The problem that I'm facing right now is that there will never be a tie between the user and the computer. I've tried to implement the function tie(user_input, computer_move) into main(), but to no success. I have to use helper functions for this assignment, so I'm trying my best to do so. Also, if there's any place that I can make my code more efficient, it would be fantastic if you could point out where :))
Change your tie function to this:
def tie(user_input, computer_move):
if user_input.lower() == "a" and computer_move == 1:
print("It's a tie!")
return True
elif user_input.lower() == "b" and computer_move == 2:
print("It's a tie!")
return True
elif user_input.lower() == "c" and computer_move == 3:
print("It's a tie!")
return True
else:
return False
You cant compare String and Int like this: computer_move == "1" when computer_move is Int.
Simplify the user_input.lower() == "a" statement.
Here is what you can use to make your code more readable:
Use dictionary to translate users input into integers.
Then you can also easily check all the conditions.
Here is the code (I have only added the part where I have get rid of the tie function):
import random
choose = "Start"
symbols = {"rock":1, "paper":2, "scissors":3}
while True:
choose = input("Hi welcome to my game! Choose between Rock, Paper, Scissors! End the game with 'End':\n")
choose = choose.lower()
computer = random.randint(1,3)
if choose in symbols: #Check if input is in a string and if its in symbols
choose = symbols[choose]
elif choose == "end":
break
else:
print("You have written down something ... weird ... next round.")
continue
if choose == computer:
print("It's a tie!")
else:
#Choose who wins ...
pass
There are a lot of minor issues in your code that can be streamlined and a few major ones, but the one causing your issues is that you are defining computer_move as an integer in the main function (computer_move = random.randint(1, 3)), but in your tie function, you are comparing it to a string (eg, computer_move == "1") The first half of your if statement also is not doing what you want: Rewrite that function as such:
def tie(user_input, computer_move):
if user_input.lower() == "a" and computer_move == 1:
print("It's a tie!")
return True
if user_input.lower() == "b" and computer_move == 2:
print("It's a tie!")
return True
if user_input() == "c" and computer_move == 3:
print("It's a tie!")
return True
else:
return False
If you don't want to have a different if statement for each possible outcome, you can try this:
def outcomes(user_input, computer_move):
end_states = {"tie": [["a", 1], ["b",2], ["c",3]],
"user_win": ["LISTS OF USER WIN STATES"]}
if [user_input.lower(), computer_move] in end_states["tie"]:
print("tie")
if [user_input.lower(), computer_move] in end_states["user_win"]:
print("user wins")
else:
print("computer wins")
A few of the fixes:
user_input = input("Press 'A' for rock, 'B' for paper, and 'C' for scissors!\n"
"A. Rock\n"
"B. Paper\n"
C. Scissors\n")
can be changed to:
user_input = input("Press 'A' for rock, 'B' for paper, and 'C' for scissors!\n"
"A. Rock\n"
"B. Paper\n"
C. Scissors\n").lower()
so that you don't need to check for both upper and lower cases each time (you would also be able to remove .lower() from the tie function.
You should move the input_detection function to right after the user makes the input, and you can rewrite the check as such:
if not gameFunctions2.input_detection(user_input):
continue
Which roughly translates to, if it returns "False", return to the start of your while loop (You can also remove the checks for uppercase and lowercase letters, if you use the previous edit).
For checking if the player wants to play again, add .lower() to the end of the input, and you can change the last lines as such:
if user_play_again != "y":
print("Have a great day! ")
break
You don't need to have a statement that evaluates if user_play_again == "y" just to have the else statement (unless you want there to be a separate action for it). You can evaluate the opposite (if user_play_again != "y") alone.
As I began to do earlier, you can put each ending variation into dictionaries and instead of having a different line for each end state check, you can evaluate the dictionary as a whole to streamline things a bit too.
These might not be the only things, and others might disagree with my changes, but it's a start of how I would rewrite the code.
The other answers have resolved the bugs in your code. This answer is meant to give you some ideas about how you might do things differently - specifically, a more object-oriented approach, and taking advantage of the standard library a bit more.
from enum import Enum
class Move(Enum):
ROCK = 0
PAPER = 1
SCISSOR = 2
def get_user_move():
moves = dict(zip("ABC", Move))
print("Options:")
for option, move in moves.items():
print(f"{option:>5}. {move.name.title()}")
prompt = "Enter your selection: "
while True:
user_input = input(prompt).upper()
if user_input in moves:
break
prompt = "Try again: "
return moves[user_input]
def main():
from random import choice
while True:
user_move = get_user_move()
computer_move = choice(tuple(Move))
print(f"\nYou picked {user_move.name.title()}")
print(f"The computer picked {computer_move.name.title()}")
if user_move is computer_move:
print("It's a tie!\n")
else:
winner = ("The computer", "You")[(computer_move.value + 1) % len(Move) is user_move.value]
print(f"The winner is: {winner}!\n")
return 0
if __name__ == "__main__":
import sys
sys.exit(main())
:D I've make a little rock paper scissors game in Python just for fun and practice and I've been trying to implement a little scoring system that doesn't seem to want to work properly and I'm not sure how to solve the problem.
import random
import messages
def gameOn():
choice = ["rock", "paper", "scissors"]
computer_choice = random.choice(choice)
player_choice = input("Please chose Rock/Paper/Scissors: ")
player_choice = player_choice.lower()
total_score = 0
while True:
#Makes sure the user enters a valid option.
if player_choice not in("rock", "paper", "scissors"):
print("Choice is not correct!")
#Prints in case both the computer and the player chose the same option.
elif computer_choice == player_choice:
print("You chose the same.")
#Computer choses ROCK.
elif computer_choice == "rock" and player_choice == "paper":
print(messages.win[0])
total_score += 1
print(total_score)
elif computer_choice == "rock" and player_choice == "scissors":
print(messages.lose[0])
#Computer choses PAPER.
elif computer_choice == "paper" and player_choice == "rock":
print(messages.lose[1])
elif computer_choice == "paper" and player_choice == "scissors":
print(messages.win[1])
total_score += 1
print(total_score)
#Computer choses SCISSORS.
elif computer_choice == "scissors" and player_choice == "rock":
print(messages.win[2])
total_score += 1
print(total_score)
elif computer_choice == "scissors" and player_choice == "paper":
print(messages.lose[2])
#Asks the user if he/she wants to play again and restarts the loop if so.
answer = input("Would you like to play again or see your score? Yes/No/Score ")
if answer in ("yes", "Yes", "y", "Y", "yup"):
print("Game starting again!")
gameOn()
elif answer in ("Score", "score"):
print("Your total score is " + str(total_score))
answer = input("Would you like to play again or see your score? Yes/No/Score ")
print("Game starting again!")
gameOn()
else:
print("Goodbye!")
break
gameOn()
The incrementation in itself works but what I want to do is, if the player wins multiple round and at the end writes "score" he should be able to see all the points he has earned. At the moment the score variable get reset every time a new game starts so the score of the use is always either 0 or 1 if he won the round. How could I prevent this behavior?
Thank you very much :D and I hope it's not a too stupid question.
I would not advise using recursion for this. You also shouldn't need to use global variables.
I would rather just loop with while True in your gameOn function and break if the player wants to exit, so that your score is kept in scope.
Also your "Choice is not correct!" was not working because of the indentation.
import random
import messages
def gameOn():
choice = ["rock", "paper", "scissors"]
total_score = 0
while True:
computer_choice = random.choice(choice)
player_choice = input("Please chose Rock/Paper/Scissors: ")
player_choice = player_choice.lower()
while True:
#Makes sure the user enters a valid option.
if player_choice in("rock", "paper", "scissors"):
break
print("Choice is not correct!")
#Prints in case both the computer and the player chose the same option.
elif computer_choice == player_choice:
print("You chose the same.")
#Computer choses ROCK.
elif<computer_choice == "rock" and player_choice == "paper":
print(messages.win[0])
total_score += 1
print(total_score)
elif computer_choice == "rock" and player_choice == "scissors":
print(messages.lose[0])
#Computer choses PAPER.
elif computer_choice == "paper" and player_choice == "rock":
print(messages.lose[1])
elif computer_choice == "paper" and player_choice == "scissors":
print(messages.win[1])
total_score += 1
print(total_score)
#Computer choses SCISSORS.
elif computer_choice == "scissors" and player_choice == "rock":
print(messages.win[2])
total_score += 1
print(total_score)
elif computer_choice == "scissors" and player_choice == "paper":
print(messages.lose[2])
#Asks the user if he/she wants to play again and restarts the loop if so.
answer = input("Would you like to play again or see your score? Yes/No/Score ")
if answer in ("Score", "score"):
print("Your total score is " + str(total_score))
answer = input("Would you like to play again or see your score? Yes/No/Score ")
print("Game starting again!")
elif answer in ("yes", "Yes", "y", "Y", "yup"):
print("Game starting again!")
else:
print("Goodbye!")
break #this makes your game stop
gameOn()
I would suggest defining a parameter to your gameOn function, so it looks like this:
def gameOn(total_score=0):
# REMOVE this following line:
total_score = 0
# because we already defined it on parameter
# when user wins, and you call the function again,
# give current total_score to it
gameOn(total_score)
since in each function call you are giving the current score, now your app should be able to keep track of actual total score
There are 2 different ways to answer this, depending on the meaning of «every time a new game starts».
Do you want to persist the score if you call the gameOn function multiple times?
Or do you want to persist the score also if you run the program again?
Persisting the score between gameOn calls
The problem is the scope of your total_score variable, which is local. Hence it’s cleaned after each gameOn execution. The simplest way to work around this is to set it as global:
import random
import messages
# Total score is initialized outside of any game
total_score = 0
def gameOn():
choice = ["rock", "paper", "scissors"]
computer_choice = random.choice(choice)
player_choice = input("Please chose Rock/Paper/Scissors: ")
player_choice = player_choice.lower()
global total_score
# Then the rest of your existing function
# ...
Advice: With time, you’ll get better in Python, and you’ll realize such global variable is usually considered bad, because of the lack of isolation it has. For larger projects, relying on globally defined stuff makes the code more difficult to evolve, increases the cognitive load of the developer, makes it harder to test... but for such a small script it’s just perfectly fine.
My point is: it’s handy, but please keep in mind there are other ways to do it. They are more complex, and over-engineered in this case, but the key take away shouldn’t be thought as "I need to use global variable as soon as I want to persist a state" ;)
Persisting the score between runs.
If your goal is to keep the score between every time you run the script, then you need to save it "outside" of the current Python session memory.
A very simple way to do this is to save it to a file. Python’s built-in pickle library is made for that (there are many other options, depending on if you want this to be usable by other programs or not, or by humans. When it’s just for Python, pickle is super simple and fast and reliable)
In this case, what you would need is to:
load the existing score when the game starts, if an existing score exists
save it at the end of the game
import random
import messages
import pickle
import os
def gameOn():
choice = ["rock", "paper", "scissors"]
computer_choice = random.choice(choice)
player_choice = input("Please chose Rock/Paper/Scissors: ")
player_choice = player_choice.lower()
score_file = "score.dat"
# Check if an existing score existed
if os.path.isfile(score_file):
with open(score_file, "rb") as f:
total_score = pickle.load(f)
else:
total_score = 0
# Then the rest of your existing function
# ...
# and at the end of the function, we save the score to the file
with open(score_file, "wb") as f:
pickle.dump(total_score, f)
This should give you pointers to what you exactly want to achieve.
Hi i'm making a rock paper scissors game and i have made the following script so far:
def main():
from random import randint
UserChoices = input("'rock', 'paper' or 'scissors'? \n Input: ")
if UserChoices == "rock":
UserChoice = 1
elif UserChoices == "paper":
UserChoice = 2
elif UserChoices == "scissors":
UserChoice = 3
CpuChoice = randint(1,3)
if UserChoice == CpuChoice:
print("DRAW!")
elif UserChoice == "1" and CpuChoice== "3":
print("Rock beats scissors PLAYER WINS!")
main()
elif UserChoice == "3" and CpuChoice== "1":
print("Rock beats scissors CPU WINS")
main()
elif UserChoice == "1" and CpuChoice== "2":
print("Paper beats rock CPU WINS!")
main()
elif UserChoice == "2" and CpuChoice== "1":
print("paper beats rock PLAYER WINS!")
main()
elif UserChoice == "2" and CpuChoice== "3":
print("Scissors beats paper CPU WINS!")
main()
elif UserChoice == "3" and CpuChoice== "2":
print("Scissors beats paper PLAYER WINS!")
main()
elif UserChoice == "1" and CpuChoice== "2":
print("cpu wins")
main()
else:
print("Error: outcome not implemented")
main()
but when I run it I get the error I made "Error: outcome not implemented" Can someone tell me why this is? thank you.
This and all the other comparisons similar to it:
elif UserChoice == "1" and CpuChoice == "3":
... should be:
elif UserChoice == 1 and CpuChoice == 3:
In other words, you should be comparing ints with ints, instead of ints with strings as is happening right now.
User choice is set to an integer, however you compare it to a string. It should be as follows
if userChoice == 1: #Note no quotation marks
Also, you are allowing the CPU to choose from 3 integers, which works. However, it may save lines and be more efficient to choose a random from an array
CPU_Moves = ['Rock','Paper','Scissors']
cpuchoice = random.choice(CPUMoves)
This will set cpuchoice to one of the random from the array, and you can then use it in the comparison of user input to the cpuchoice. This would mean you wouldn't need to set userChoice at all, you could use what the user enters directly.
As the previous answers say, you ended up comparing a string against an integer.
It would be a good idea to avoid using so many conditionals. Here's a "compact version" I've written, in case you're interested:
from random import randrange
def RPS(user_choice = ''):
choices = ('rock', 'paper', 'scissors')
results = ('Draw!', 'You Win!', 'Cpu Wins!')
while user_choice not in choices:
user_choice = input("Choose: rock, paper or scissors? ")
user_num = choices.index(user_choice)
cpu_num = randrange(3)
diff = (user_num - cpu_num) % 3
print("You chose:", user_choice, "-", "Cpu chose:", choices[cpu_num])
print(results[diff])
RPS('rock') # User choice can be passed as an argument.
Notice how you can calculate the winner with a subtraction and a modulo operation. This is even more useful in a Rock, paper, scissors, lizzard, Spock game, where you have 5 choices instead of 3.
remove the quotes from your if else statement. the conditionals are looking for a string to compare while rock paper and scissors are assigned as integers. these are not handled the same way. you need to change your if elif to not have quotes around the numbers. it prints out DRAW because its comparing like items and it give and error because it is not the same variable type.
I am working on a rock paper scissors game. Everything seems to be working well except the win/loss/tie counter. I have looked at some of the other games people have posted on here and I still cannot get mine to work. I feel like I am soooooo close but I just can't get it! thanks for any help guys. this is my first time posting in here so I am sorry if I messed up the formatting.
I edited the code but still cannot get the program to recognize the counter without using global variables. at one point of my editing I managed to get it to count everything as a tie... i dont know how and I lost it somewhere along my editing. lol. -thanks again everyone!
here is what I get when I run the program:
Prepare to battle in a game of paper, rock, scissors!
Please input the correct number according
to the object you want to choose.
Select rock(1), paper(2), or scissors(3): 1
Computer chose PAPER .
You chose ROCK .
You lose!
Play again? Enter 'y' for yes or 'n' for no. y
Prepare to battle in a game of paper, rock, scissors!
Please input the correct number according
to the object you want to choose.
Select rock(1), paper(2), or scissors(3): 2
Computer chose PAPER .
You chose PAPER .
It's a tie!
Play again? Enter 'y' for yes or 'n' for no. y
Prepare to battle in a game of paper, rock, scissors!
Please input the correct number according
to the object you want to choose.
Select rock(1), paper(2), or scissors(3): 3
Computer chose SCISSORS .
You chose SCISSORS .
It's a tie!
Play again? Enter 'y' for yes or 'n' for no. n
Your total wins are 0 .
Your total losses are 0 .
Your total ties are 0 .
#import the library function "random" so that you can use it for computer
#choice
import random
#define main
def main():
#assign win, lose, and tie to zero for tallying
win = 0
lose = 0
tie = 0
#control loop with 'y' variable
play_again = 'y'
#start the game
while play_again == 'y':
#make a welcome message and give directions
print('Prepare to battle in a game of paper, rock, scissors!')
print('Please input the correct number according')
print('to the object you want to choose.')
#Get the player and computers choices and
#assign them to variables
computer_choice = get_computer_choice()
player_choice = get_player_choice()
#print choices
print('Computer chose', computer_choice, '.')
print('You chose', player_choice, '.')
#determine who won
winner_result(computer_choice, player_choice)
#ask the user if they want to play again
play_again = input("Play again? Enter 'y' for yes or 'n' for no. ")
#print results
print('Your total wins are', win, '.')
print('Your total losses are', lose, '.')
print('Your total ties are', tie, '.')
#define computer choice
def get_computer_choice():
#use imported random function from library
choice = random.randint(1,3)
#assign what the computer chose to rock, paper, or scissors
if choice == 1:
choice = 'ROCK'
elif choice == 2:
choice = 'PAPER'
else:
choice = 'SCISSORS'
#return value
return choice
#define player choice
def get_player_choice():
#assign input to variable by prompting user
choice = int(input("Select rock(1), paper(2), or scissors(3): "))
#Detect invalid entry
while choice != 1 and choice != 2 and choice != 3:
print('The valid numbers are rock(type in 1), paper(type in 2),')
print('or scissors(type in 3).')
choice = int(input('Enter a valid number please: '))
#assign what the player chose based on entry
if choice == 1:
choice = 'ROCK'
elif choice == 2:
choice = 'PAPER'
else:
choice = 'SCISSORS'
#return value
return choice
#determine the winner from the variables
def winner_result(computer_choice, player_choice):
#if its a tie, add 1 to tie variable and display message
if computer_choice == player_choice:
result = 'tie'
print("It's a tie!")
#if its a win, add to win tally and display message
elif computer_choice == 'SCISSORS' and player_choice == 'ROCK':
result = 'win'
print('ROCK crushes SCISSORS! You win!')
elif computer_choice == 'PAPER' and player_choice == 'SCISSORS':
result = 'win'
print('SCISSORS cut PAPER! You win!')
elif computer_choice == 'ROCK' and player_choice == 'PAPER':
result = 'win'
print('PAPER covers ROCK! You win!')
#if it does not match any of the win criteria then add 1 to lose and
#display lose message
else:
result = 'lose'
print('You lose!')
def result(winner_result,player_choice, computer_choice):
# accumulate the appropriate winner of game total
if result == 'win':
win += 1
elif result == 'lose':
lose += 1
else:
tie += 1
return result
main()
Your winner_result function returns before it increments the win counters. If you remove all the return statements from it, the counters should be updated. The return statements aren't needed anyway because the if/elif/else structure ensures that only one of the possible outcomes will be executed.
As Junuxx says in a comment, you also need to assign values to the winner_result variable properly, i.e. winner_result = 'win' instead of winner_result == 'win'. I'd also rename the winner_result variable or the function, because it's confusing to have both use the same name.
And the win/lose/tie variables are currently local, which means that main and winner_result will have their own copies of these variables, so main's values will always be zero. What you can do is make them global variables: Assign them to zero in the global scope (outside any function), and add the line global win, lose, tie inside the function winner_result.
Obviously been a few years since this question was answered but it came up while I was looking the same info. Here's my code if anyone is interested.
#! usr/bin/python3
import random
def game():
computer_count = 0
user_count = 0
while True:
base_choice = ['scissors', 'paper', 'rock']
computer_choice = random.choice(base_choice)
user_choice = input('(scissors, paper, rock) Type your choice: ').strip().lower()
print()
computer_wins = 'The computer wins!'
you_win = 'You win!'
print(f'You played {user_choice}, the computer played {computer_choice}')
if user_choice == 'scissors' and computer_choice == 'rock' or \
user_choice == 'paper' and computer_choice == 'scissors' or \
user_choice == 'rock' and computer_choice == 'paper':
print(computer_wins)
computer_count += 1
elif user_choice == 'rock' and computer_choice == 'scissors' or \
user_choice == 'scissors' and computer_choice == 'paper' or \
user_choice == 'paper' and computer_choice == 'rock':
print(you_win)
user_count += 1
else:
if user_choice == computer_choice:
print('Its a draw!')
computer_count += 1
user_count += 1
print(f'Computer: {computer_count} - You: {user_count}')
print()
game()
I was trying to do the same project, and I have found a solution that works well for me.
from random import randint
win_count = 0
lose_count = 0
tie_count = 0
# create a list of play options
t = ["Rock", "Paper", "Scissors"]
# assign a random play to the computer
computer = t[randint(0, 2)]
# set player to false
player = False
print()
print("To stop playing type stop at any time.")
print()
while player == False:
# set player to True
player = input("Rock, Paper or Scissors? ")
if player.lower() == "stop":
print()
print(
f"Thanks for playing! Your final record was {win_count}-{lose_count}-{tie_count}")
print()
break
if player.title() == computer:
print()
print("Tie!")
tie_count += 1
print()
elif player.title() == "Rock":
if computer == "Paper":
print()
print(f"You lose. {computer} covers {player.title()}.")
lose_count += 1
print()
else:
print()
print(f"You win! {player.title()} smashes {computer}.")
win_count += 1
print()
elif player.title() == "Paper":
if computer == "Scissors":
print()
print(f"You lose. {computer} cuts {player.title()}.")
lose_count += 1
print()
else:
print()
print(f"You win!, {player.title()} covers {computer}.")
win_count += 1
print()
elif player.title() == ("Scissors"):
if computer == "Rock":
print()
print(f"You lose. {computer} smashes {player.title()}.")
lose_count += 1
print()
else:
print()
print(f"You win! {player.title()} cuts {computer}.")
win_count += 1
print()
else:
print()
print("Sorry, we couldn't understand that.")
print()
# player was set to True, but we want it to be false to continue loop
print(f"Your record is {win_count}-{lose_count}-{tie_count}")
print()
player = False
computer = t[randint(0, 2)]
This works (kinda)
there are many issues with the code at the top of the page.
Firstly, Scoring doesn't work.
Secondly, nothing is indented meaning that nothing inside of the other def functions will work.
Thirdly, The other def functions are referred to in the first def main statement which causes Python to show an invalid syntax due to Python not knowing the other functions as they were referred to before they were introduced to python.