Unable to verify user input in game - python

I am creating a rock, paper, scissors game. I want it to be best of 3 matches and to be able to verify user input. I keep running into issues with the user input. I have tried multiple variations but I can't seem to figure it out. I know my code is probably messy, so any input on how to clean it up would be greatly appreciated. Thank you so much for your time.
import random
import sys
import time
print("Hello and welcome to the Rock, Paper, Scissors tournament.\n"
"The tournament will be the best of 3 wins.\n"
"It will be you against our highly intelligent computer opponent.\n"
"Good luck!")
# Create a function for the game
def play_game():
user_count = 0
comp_count = 0
tie_game = 0
while comp_count < 2 and user_count < 2:
user_choice = (int(input("-------------------------------------------"
"\nEnter choice by typing 1 2 or 3: \n 1. Rock \n 2. paper \n 3. scissor \n"
"-------------------------------------------\n")))
if user_choice == 1:
user_choice_name = 'Rock'
elif user_choice == 2:
user_choice_name = 'Paper'
elif user_choice == 3:
user_choice_name = 'Scissor'
else:
print("Please pick a valid number")
print(f"\nYou have chosen: {user_choice_name}")
print("\nNow it's the computer's turn to pick......")
time.sleep(3)
comp_choice = random.randint(1, 3)
if comp_choice == 1:
comp_choice_name = 'Rock'
elif comp_choice == 2:
comp_choice_name = 'Paper'
else:
comp_choice_name = 'Scissor'
print(f"\nComputer has chosen: {comp_choice_name}\n")
if user_choice == 1 and comp_choice == 2:
comp_count += 1
print("Computer wins this round with Paper! "
f"\n Computer: {comp_count}"
f"\n You: {user_count} \n\n")
elif user_choice == 1 and comp_choice == 3:
user_count += 1
print("You win this round with Rock!"
f"\n Computer: {comp_count}"
f"\n You: {user_count} \n\n")
elif user_choice == 2 and comp_choice == 1:
user_count += 1
print("You win this round with Paper!"
f"\n Computer: {comp_count}"
f"\n You: {user_count} \n\n")
elif user_choice == 2 and comp_choice == 3:
comp_count += 1
print("Computer wins this round with Scissor!"
f"\n Computer: {comp_count}"
f"\n You: {user_count} \n\n")
elif user_choice == 3 and comp_choice == 2:
user_count += 1
print("You win this round with Scissor!"
f"\n Computer: {comp_count}"
f"\n You: {user_count} \n\n")
elif user_choice == 3 and comp_choice == 1:
user_count += 1
print("Computer wins this round with Rock!"
f"\n Computer: {comp_count}"
f"\n You: {user_count} \n\n")
else:
if user_choice == comp_choice:
tie_game += 1
print(f"This round was a tie! Both choosing {user_choice_name}, try again!"
f"\n Computer: {comp_count}"
f"\n You: {user_count} \n\n")
else:
print(f'The game is now over with a score of: \n You:{user_count} \n to \n Computer:{comp_count}')
again = str(input("Do you want to play again, type 'yes' or 'no' \n"))
if again.lower() == "no":
print('Thank you for playing!')
sys.exit()
else:
play_game()
play_game()

Since I had a few minutes to kill with a cup of coffee, here's a rewrite of your program with a bunch of improvements, the validation you asked about and some tips on coding style:
import random
import time
print("Hello and welcome to the Rock, Paper, Scissors tournament.\n"
"The tournament will be the best of 3 wins.\n"
"It will be you against our highly intelligent computer opponent.\n"
"Good luck!")
# to avoid repeating these values over and over and changing numbers in to string,
# just defining them here. Name in capitals because it's global (generally bad)
# an even nicer solution would be to write a Game() class and put everything in
# there, but it would be a bit more advanced
RSP_OPTIONS = {
1: 'Rock',
2: 'Scissor',
3: 'Paper'
}
def get_user_choice():
# keep asking until a valid value is returned
while True:
# this is a bit fancy, but let's say you want to reuse the game for similar games
# with different options from rock, scissor, paper, you'd want this code to still work
# get a list of string versions of the numbers
numbers = list(map(str, RSP_OPTIONS.keys()))
# join them together like you presented them: 1, 2 or 3
options = ', '.join(numbers[:-1]) + ' or ' + numbers[-1] + ':\n'
# add the descriptions
options = options + ''.join(f'{n}: {name}\n' for n, name in RSP_OPTIONS.items())
try:
user_choice = (int(input("-------------------------------------------\n"
f"Enter choice by typing {options}"
"-------------------------------------------\n")))
except ValueError:
# any invalid option
user_choice = -1
# check if it's one of the valid options
if user_choice in RSP_OPTIONS:
return user_choice
else:
# it makes sense to generate a new line where you want it, instead of having
# to put new line characters at the start of other strings
print("Please pick a valid number\n")
def beats(choice1, choice2):
# choice1 beats choice2 if it's one greater, except when choice2 == 3 and choice1 == 1
# but to make it even nicer and have it work for other similar games, you could say
# "except when choice1 == the max choice and choice2 == the min choice"
return (choice2 - choice1 == 1 or
(choice1 == max(RSP_OPTIONS.keys()) and choice2 == min(RSP_OPTIONS.keys())))
# Create a function for the game
def play_game():
user_count = 0
comp_count = 0
tie_game = 0
# this is what you really want, best out of three, ties not counted?
while comp_count + user_count < 3:
user_choice = get_user_choice()
print(f"You have chosen: {RSP_OPTIONS[user_choice]}\n")
print("Now it's the computer's turn to pick......\n")
# this wait is not very nice, the user might try to hit enter or something
# you could consider printing the countdown, or telling the user to please wait
# even then, it's kind of silly to pretend the computer has to work hard here
time.sleep(3)
# this choice is always valid, so no problem
comp_choice = random.randint(1, 3)
# note that you don't need the name, you can just look it up whenever in RSP_OPTIONS
print(f"\nComputer has chosen: {RSP_OPTIONS[comp_choice]}\n")
# getting rid of some repetition, note how the code really reads like what is intended
if beats(comp_choice, user_choice):
comp_count += 1
# nice to also say what really beat them
print(f"Computer wins this round with {RSP_OPTIONS[comp_choice]} over {RSP_OPTIONS[user_choice]}!\n")
elif beats(user_choice, comp_choice):
user_count += 1
print(f"You win this round with {RSP_OPTIONS[user_choice]} over {RSP_OPTIONS[comp_choice]}!\n")
else:
# you can only get here on a tie
tie_game += 1
print(f"This round was a tie! Both choosing {RSP_OPTIONS[user_choice]}, try again!\n")
# you always print this, so just do it after the options:
print(f"Computer: {comp_count}\n"
f"You: {user_count}\n\n")
else:
print(f'The game is now over with a score of:\n You:{user_count}\n to\n Computer:{comp_count}\n')
again = str(input("Do you want to play again, type 'yes' or 'no' \n"))
# let's quit on anything starting with n
if again.lower()[0] == "n":
print('Thank you for playing!\n')
# instead of exiting hard, maybe just return, telling the caller we don't want to play again
return False
else:
# you were calling play_game again, but that causes the game to get more and more calls
# on top of each other, ultimately reaching an error state
# by returning first and then calling again, you avoid that problem
return True
# the function returns whether it should play again
while play_game():
pass
# once it leaves the loop, the game stops automatically here, no more code
There's still a lot of room for improvement though; try implementing some more advanced forms of RSP, or make the computer more intelligent than just playing random, but have it use some kind of strategy, perhaps with a bit of randomness mixed in.
And code-wise, try separating the game from the way it is presented on the screen; what if you decided to do this on the web instead of on a console, or in a graphics window? You could also consider putting all the code in a nice class, getting rid of global variables and allowing you to create more copies of the game as needed.

Related

How to make a helper function work - please see code below

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())

Python: Rock Paper Scissors While Loop Issue

I'm having an issue with my programming of Rock, Paper, Scissors for Python. My issue occurs when there is a tie. When there is a tie, my program is supposed to going into a while loop within the if statement of the tie and reask the player the same question, rock, paper or scissors again until it breaks out of the tie. I have attached the link to the image of the issue:
In Round 5: you can see the issue.
I am taking an intro to programming class so I'm still a beginner and I do not know what I am doing wrong.
A Python program for the Rock, Paper, Scissors game.
import random
def rock_paper_scissors():
playerscore = 0
computerscore = 0
rounds = input('\nHow many points does it take to win?: ')
count = 1
while playerscore or computerscore != int(rounds):
print('\n********************* ROUND #',count,'*********************')
player = input('\nPick your throw: [r]ock, [p]aper, or [s]cissors?: ')
computerthrow = random.randint(0,2)
if (computerthrow == 0):
computer = "rock"
computer = 'r'
elif (computerthrow == 1):
computer = "paper"
computer = 'p'
elif (computerthrow == 2):
computer = "scissors"
computer = 's'
if (player == computer):
print('Tie!')
while (player == computer):
player = input('\nPick your throw: [r]ock, [p]aper, or [s]cissors?: ')
computerthrow = random.randint(0,2)
if (computerthrow == 0):
computer = "rock"
computer = 'r'
elif (computerthrow == 1):
computer = "paper"
computer = 'p'
elif (computerthrow == 2):
computer = "scissors"
computer = 's'
print(computer)
elif (player == 'r'):
if (computer == "p"):
print('Computer threw paper, you lose!')
computerscore=computerscore+1
else:
print('Computer threw scissors, you win!')
playerscore = playerscore+1
#count = count + 1
elif (player == 'p'):
if (computer == "r"):
print('Computer threw rock, you win!')
playerscore = playerscore+1
else:
print('Computer threw scissors, you lose!')
computerscore=computerscore+1
#count = count + 1
elif (player == 's'):
if (computer == "p"):
print('Computer threw paper, you win!')
playerscore = playerscore+1
else:
print('Computer threw rock, you lose!')
computerscore=computerscore+1
count = count + 1
print('\nYour score: ',playerscore)
print('Computer''s score: ',computerscore,'\n')
print('********************* GAME OVER ********************')
def main():
print('ROCK PAPER SCISSORS in Python')
print()
print('Rules: 1) Rock wins over Scissors.')
print(' 2) Scissors wins over Paper.')
print(' 3) Paper wins over Rock.')
rock_paper_scissors()
main()
Your problem comes from the way you have structured your control statements (if, elif, else). When you enter your tie while loop, you are constantly running it until someone wins and that looks like it works no problem. The issue is that once you do that, the python interpreter skips all elif and else statements in that control block (if I say if x == 3: do this else: do that) I don't want python to follow through with the else condition if x does indeed == 3). Sorry if that is confusing, long story short you need to make sure that even when your tie block gets executed you still move on to scoring the round and starting a new one. The easy way to do that is just change the elif (player == "r") to an if statement. That way the interpreter treats the scoring control sequence as its own block and it will always be executed once you assign the throws each player makes.
Example:
def f(x):
if (x == 0):
print("1")
x += 1
elif (x == 1):
print("2")
print("Done!")
def g(x):
if (x == 0):
print("1")
x += 1
if (x == 1):
print("2")
print("Done!")
if you call f(0):
Python will print out 1 and then Done!
if you call g(0):
Python will print out 1 then 2 then Done!
Your immediate problem is that you have the handling code for a tie in the same if/elif chain as the handling for the other scoring.
You say something like:
if tied
stuff
elif player == r
...
As a result, when there is a tie the game correctly loops until there is no tie. But then is skips over the code that updates the score, because that is how if/elif/else works!
An immediate fix would be to break that if/elif chain, and put the tie-handling into a separate if block:
if tied:
loop until not tied
# now do scoring
if player == 'r':
... etc
With that said, let me add a few more things:
You are assigning two values to the same variable, in sequence:
computer = 'rock'
computer = 'r'
This doesn't do anything, because the second overwrites the first. You should just delete the first line in each of those pairs.
You should probably write a function that repeatedly asks the user to pick one, until it gets either rock, paper, or scissors. Use a while loop.
There is a function in the random module that will pick an item from a list, tuple, or string and return it. You can use that to make the computer pick r,p,s directly.
You can simplify your code by determining the outcome in advance. Say you have the computer pick first. Then if the computer picks 'r', you know 'p' is a win and 's' is a lose. Store the win/lose picks in a pair of variables, and all your testing can be boiled down to one test:
computer = computer_pick()
if computer == 'r':
winner = 'p'
computer = 'rock'
elif computer == 'p':
...
player = player_pick()
if tied ...
if player == winner:
print("Computer picked", computer, "- you win!")
else:
...

Rock paper scissors, skipping a result

import random
for i in range(3):
user = str(input("Please enter your choice: "))
if (random.randrange(3)) == 0 :
print("Computer chooses Rock")
if user == "scissors" :
print("computer wins")
elif user == "paper" :
print("player wins")
else :
print("tie")
elif (random.randrange(3)) == 1 :
print("Computer chooses Paper")
if user == "rock" :
print("computer wins")
elif user == "scissors" :
print("player wins")
else :
print("tie")
elif (random.randrange(3)) == 2 :
print("Computer chooses Scissors")
if user == "paper" :
print("computer wins")
elif user == "rock" :
print("player wins")
else :
print("tie")
The formatting is a bit weird on here (havent used this website before). I dont know the reason but i dont know why this code sometimes skips a result. if anyone could help that would be great.
This is what is produced when it is run a couple of times
enter your choice: scissors
Computer chooses Rock
computer wins
enter your choice: scissors
Computer chooses Scissors
tie
enter your choice: scissors
Computer chooses Rock
computer wins
================================ RESTART ================================
Please enter your choice: scissors
Please enter your choice: rock
Computer chooses Rock
tie
Please enter your choice: rock
Computer chooses Rock
tie
I dont understand why it skips a result. Seems to happen randomly
you should not use random.randrange(3) three times. This may e.g. give you the following numbers: 1, 2 and then 0. So the code which is then executed would be:
if (1 == 0):
...
elif (2 == 1):
...
elif (0 == 2):
...
and none of the conditional blocks of the if statements would be executed.
Instead do something like this:
computerChoice = random.randrange(3)
...
if computerCoice == 0:
...
elif computerChoice == 1:
...
elif computerChoice == 2:
...
else
raise Exception("something is definitively wrong here")
you have used random.randrange(3) multiple times and each time there is a possibility of it being a different number.. So i would suggest you assign the value to a variable and then use that in your if statements:
x = random.randrange(3)
I see that you've accepted the excellent answer of Andre, that takes you to understand clearly your error. As I commented your Q saying that there are simpler ways to award a hand, here it is my take
import random
c = random.randrange(3)
u = int(input('1=scissors, 2=paper, 3=rock: '))-1
if u==c:
print '... tie ...'
elif (u==0 and c==1) or (u==1 and c==2) or (u==2 and c==0):
print 'User wins!'
else:
print 'Computer wins... Booh!'
but I'm not sure if it is simpler... shorter for sure it is, but simpler?
One can make it even shorter
import random
def hand():
c = random.randrange(3)
u = int(input('1=scissors, 2=paper, 3=rock: '))-1
print "User played",['scissors,', 'paper,', 'rock,'][u],
print "computer played",['scissors.', 'paper.', 'rock.'][c]
print ['Tie.', 'User wins!', 'Computer wins...'][(c-u)%3]
This is an example session:
>>> hand()
1=scissors, 2=paper, 3=rock: 3
User played rock, computer played scissors.
User wins!
>>>
Yes, it is happening randomly. :)
if (random.randrange(3)) == 0 :
# computer "chooses" a random number
elif (random.randrange(3)) == 1 :
# now the computer's choice is a new choice from 0..2
elif (random.randrange(3)) == 2 :
# and now it's different again
Your mistake is here :
if (random.randrange(3)) == 0 :
elif (random.randrange(3)) == 1 :
elif (random.randrange(3)) == 2 :
In the if statement random.randrange(3) will generate a random number if it doesn't match, it will go to elif statement and random.randrange(3) will generate another random number and it may not be the same as the previously generated random number . Some time because of this your code will skip one , two , three or none of the statement .
If you want your code to be good , you should assign the random number to an integer and then use that integer in your answer .
It should be
ran=random.randrange(3)
if ran == 0 :
elif ran == 2 :
elif ran == 3 :

Python 3 rock, paper, scissors issue

I am working on a rock, paper, scissors game for a programming homework assignment and I have run into a little snag. The program is suppose run by the user selecting 1 of 4 options, 1) rock, 2) paper, 3) scissors and 4) quit. Once the player selects an option the computers selection is displayed and the winner is announced and the program will ask if you would like to play another game. If y is select you go back to the main menu to choose another option, anything else will bring up the amount of games won, lost and how many games ended in a tie. If the player selects 4 the program should say "Exiting program..." and the game results should display.
Here are my issues:
Once you make the first selection, the winner is displayed and the program returns to main menu. If you make a second selection it will inform you of what the computer chose and then ask if you would like to play again. Y will take you back to the main menu, the computers selection will never change and no matter what you select the game will always end in the same result as the very first game. If you choose not to play again then the amount of games won, lost and tied will appear (this seems to be functioning correctly).
The quit option takes you back to the main menu instead of displaying the game results. I am not sure where to put that if statement.
Any help with these issues would be appreciated.
Thank you
#import module
import random
def main():
#create a variable to control the loop
play_again = 'y'
#create a counter for tied games, computer games and player games
tied_games = 0
computer_games = 0
player_games = 0
#display opening message
print("Let's play rock, paper scissors!")
computer_choice = process_computer_choice()
player_choice = process_player_choice()
winner = determine_winner(player_choice, computer_choice)
#setup while loop for playing multiple games
while play_again == 'y' or play_again == 'Y':
process_computer_choice()
process_player_choice()
#use a if else statement to print the computers choice
if computer_choice == 1:
print('computer chooses rock.')
elif computer_choice == 2:
print('computer chooses paper.')
else:
print('computer chooses scissors.')
#call the determine winner function
determine_winner(player_choice, computer_choice)
#check who won the game and add 1 to the correct counter
if winner == 'computer':
computer_games += 1
elif winner == 'player':
player_games += 1
else:
tied_games += 1
#ask the user if they would like to play again
play_again = input('would you like to play again? (enter y for yes): ')
#display number of games that were won by the computer, the player and that were tied
print()
print('there was', tied_games, 'tied games.')
print('the player won', player_games, 'games.')
print('The computer won', computer_games,'games.')
#define the process computer function
def process_computer_choice():
#setup computer to select random integer between 1 and 3
choice1 = random.randint(1, 3)
#return the computers choice
return choice1
#define the process player function
def process_player_choice():
#add input for players choice
print()
print(' MENU')
print('1) Rock!')
print('2) Paper!')
print('3) Scissors!')
print('4) Quit')
print()
player_choice = int(input('Please make a selection: '))
#add if statement for quit option
if player_choice == 4:
print('Exiting program....')
#validate if the user enters a correct selection
while player_choice != 1 and player_choice != 2 and player_choice != 3 and player_choice != 4:
#print a error message if the wrong selection is entered
print('Error! Please enter a correct selection.')
player_choice = int(input('Please make a selection: '))
#return the players choice
return player_choice
#define the determine winner function
def determine_winner(player_choice, computer_choice):
#setup if else statements for each of the 3 computer selections
if computer_choice == 1:
if player_choice == 2:
print('Paper wraps rock. You win!')
winner = 'player'
elif player_choice == 3:
print('Rock smashes scissors. The computer wins!')
winner = 'computer'
else:
print('The game is tied. Try again.')
winner = 'tied'
if computer_choice == 2:
if player_choice == 1:
print('Paper wraps rock. The computer wins!')
winner = 'computer'
elif player_choice == 3:
print('Scissors cut paper. You win!')
winner = 'player'
else:
print('The game is tied. Try again.')
winner = 'tied'
if computer_choice == 3:
if player_choice == 1:
print('Rock smashes scissors. You win!')
winner = 'player'
elif player_choice == 2:
print('Scissors cut paper. The computer wins!')
winner = 'computer'
else:
print('The game is tied. Try again.')
winner = 'tied'
return winner
main()
For issue 1, it's because you set the computer and player choices before your loop, and never update them. Change the beginning of your loop to:
while play_again == 'y' or play_again == 'Y':
computer_choice = process_computer_choice()
player_choice = process_player_choice()
You can also remove the lines of code before the loop that check the inputs and winner, as it's technically redundant for the first round.
For issue 2, just add the results after a 4 is chosen, like so:
if player_choice == 4:
print('Exiting program....')
print('there was', tied_games, 'tied games.')
print('the player won', player_games, 'games.')
print('The computer won', computer_games,'games.')
sys.exit() # be sure you add 'import sys' to the beginning of your file
Also, the line in your main loop determine_winner(player_choice, computer_choice) is indented so it will only be called if the computer chooses scissors, so you should unindent that :)
You aren't assigning to computer_choice or player_choice again, but using it's value.
while play_again == 'y' or play_again == 'Y':
process_computer_choice()
process_player_choice()
Should be
while play_again == 'y' or play_again == 'Y':
computer_choice = process_computer_choice()
player_choice = process_player_choice()
As for quitting just break in the quit choice. You have to return early from the process_player_choice and also do something in main.
So in process_player_choice:
if player_choice == 4:
print('Exiting program....')
return
and in main:
player_choice = process_player_choice()
if player_choice == 4:
return
winner = determine_winner(player_choice, computer_choice)
#setup while loop for playing multiple games
while play_again == 'y' or play_again == 'Y':
computer_choice = process_computer_choice()
player_choice = process_player_choice()
if player_choice == 4:
break

Python rock paper scissors score counter

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.

Categories

Resources