Python 3 rock, paper, scissors issue - python

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

Related

Incrementing a score system in Python

: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.

Unable to verify user input in game

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.

NameError: free variable 'player_one_rps' referenced before assignment in enclosing scope

I'm quite new to coding, and I've been trying to make a text-based game with a menu. The game itself works fine, but once I try to incorporate a menu, i get the error "NameError: free variable 'player_one_rps' referenced before assignment in enclosing scope".
I have been googling it like a mad for some time now, but the few answers I find uses too advanced code for me to understand it yet.
(I tried changing the scopes and indents, I tried calling different functions at different indents, I tried assigning an argument to the functions, also, to have the main menu as the last function in the code – the list goes on..)
Here is the code for the menu and game option 1:
def main():
print("\t\t*** Welcome to this totally adequate game! ***")
def game_menu():
"""Displays game menu and prompts user for input"""
menu_choice = input("""What do you want to do?
1 - One player: rock, paper, scissor, lizard, spock
2 - Two player: rock, paper, scissor, lizard, spock
3 - Surprise! Bonus feature
4 - User guide
5 - Quit
Enter the menu number to access: """)
while True:
if menu_choice == "1":
print("One player: rock, paper, scissor, lizard, spock")
player_one_rps()
break
elif menu_choice == "2":
print("Two player: rock, paper, scissor, lizard, spock")
player_two_rps()
break
elif menu_choice == "3":
print("Surprise! Bonus feature")
dad_jokes()
break
elif menu_choice == "4":
print("User guide")
user_info()
elif menu_choice == "5":
print("Quit game")
exit()
elif menu_choice != 1 - 5:
print("Error, choose a valid number")
# print(menu_choice)
game_menu()
main()
# First game
def player_one_rps():
"""One player rock, paper, scissor, lizard, spock - game"""
import random
def instructions():
"""Displays menu and simple instructions on how to play"""
print("Welcome to rock, paper, scissor, lizard, spock!")
play = input("\nNavigate by \"yes\", \"no\", and numbers.\nNew game?:").lower()
if play == "yes":
print("1. Rock")
print("2. Paper")
print("3. Scissors")
print("4. Lizard")
print("5. Spock")
elif play != "no":
print("an error has occured. Please type \"yes\" or \"no\":")
instructions()
def get_user_choice():
"""Prompts the player to pick a 'weapon'"""
choice = int(input("What do you choose?: "))
if choice > 5:
print("Invalid number, please try again....")
get_user_choice()
elif choice < 1:
print("Invalid number, please try again....")
get_user_choice()
elif choice == 1:
print("You chose rock")
elif choice == 2:
print("You chose paper")
elif choice == 3:
print("You chose scissor")
elif choice == 4:
print("You chose lizard")
elif choice == 5:
print("You chose spock")
return choice
def get_pc_choice():
"""The computer chooses a random weapon"""
choice = random.randint(1, 5)
if choice == 1:
print("PC chose rock")
elif choice == 2:
print("PC chose paper")
elif choice == 3:
print("PC chose scissor")
elif choice == 4:
print("PC chose lizard")
elif choice == 5:
print("PC chose spock")
return choice
def winner(user_choice, pc_choice, user_wins, pc_wins, ties):
"""Calculates if the player or computer won the match"""
if user_choice == 1 and pc_choice == 3 or pc_choice == 4:
print("\nYou win.")
user_wins = user_wins.append(1)
elif user_choice == 2 and pc_choice == 1 or pc_choice == 5:
print("\nYou win.")
user_wins = user_wins.append(1)
elif user_choice == 3 and pc_choice == 2 or pc_choice == 4:
print("\nYou win.")
user_wins = user_wins.append(1)
elif user_choice == 4 and pc_choice == 2 or pc_choice == 5:
print("\nYou win.")
user_wins = user_wins.append(1)
elif user_choice == 5 and pc_choice == 1 or pc_choice == 3:
print("\nYou win.")
user_wins = user_wins.append(1)
elif user_choice == pc_choice:
print("\nTie")
ties = ties.append(1)
else:
print("\nPC won")
pc_wins = pc_wins.append(1)
return
def game_total(user_wins, pc_wins, ties):
"""Displays the total score"""
user_wins = sum(user_wins)
pc_wins = sum(pc_wins)
ties = sum(ties)
print("Your final score: ", user_wins)
print("PC\'s final Score: ", pc_wins)
print("Total ties: ", ties)
def main_one_p():
"""Main instructions for how the game runs"""
user_choice = 0
user_wins = []
pc_choice = 0
pc_wins = []
ties = []
final_user_wins = 0
final_pc_wins = 0
final_ties = 0
Continue = "yes"
instructions()
while Continue == "yes":
user_choice = get_user_choice()
pc_choice = get_pc_choice()
winner(user_choice, pc_choice, user_wins, pc_wins, ties)
Continue = input("Would you like to play again: ").lower()
if Continue == "no":
print("This is the final scores.")
break
game_total(user_wins, pc_wins, ties)
main_one_p()
player_one_rps()
game_menu() # Returns player to the main menu
(sorry if it is quite long)
Could anyone help point me in the direction of my mistake? Explanations and tips on how to fix it would also be greatly appreciated :)
In general, I'm thankful for all feedback, as i really want to become better at coding.
The global function must have a higher declarative code than where it is called. Simply reposition the function. The function game_menu must be below the function play_one_rps. The other functions are the same.

Python rock, paper, scissors game. not always give correct answers

I'm trying to make a simple Rock, Paper, Scissors game in python 3.4 and it works to a certain degree but some time i get an output of "You Won Rock crushes Rock" even though i thought i have stop this from happening and only allowed certain outcomes of the code with my elif and if statements. So can anyone tell me why isn't this working sometimes. :)
import random
count = 0
OPTIONS = ['rock', 'paper', 'scissors']
# then check if the user lose's, wins ties
def computer():
return random.choice(OPTIONS)
print("\n"+"-=-"*11)
print("Welcome to ROCK, PAPER, SCISSORS")
print(" GAME")
print(" It's you Vs. the computer!")
print("-=-"*11)
while True:
user = input("What do you choose Rock, Paper, Scissors: ").lower()
if user in OPTIONS:
# Possible user time a user can succeeds rock beats sicissor, sicissors cuts paper, paper covers rock
if user == computer():
print("tie")
elif user == 'rock' and computer() == 'scissors':
print("\nYou Won! {} crushes {}".format(user.title(), computer().title()))
elif user == 'scissors' and computer() =='rock':
print("\nComputer Won! {} crushes {}".format(computer().title(), user.title() ))
elif user == 'scissors' and computer() == 'paper':
print("\nYou Won! {} cuts {}".format(user.title(), computer().title()))
elif user == 'paper' and computer() == 'scissors':
print("\nComputer Won! {} cuts {}".format(computer().title(), user.title()))
elif user == 'paper' and computer() == 'rock':
print("\nYou Won! {} covers {}".format(user.title(), computer().title()))
elif user == 'rock' and computer() == 'paper':
print("\nComputer Won! {} covers {}".format(computer().title(), user.title()))
else:
print("\nMake sure you choose ethier Rock, Paper or Scissors")
enter code here
elif user == 'rock' and computer() == 'scissors':
print("\nYou Won! {} crushes {}".format(user.title(), computer().title()))
Every time you call computer(), it generates a completely new value, independent of any previous calls. For example, in the code above it's entirely possible that the first computer() call returns "scissors", and the second one returns "rock".
Call computer() only once in the loop, and store the result. Then use that value for the rest of your code.
while True:
user = input("What do you choose Rock, Paper, Scissors: ").lower()
if user in OPTIONS:
computer_move = computer()
# Possible user time a user can succeeds rock beats sicissor, sicissors cuts paper, paper covers rock
if user == computer_move:
print("tie")
elif user == 'rock' and computer_move == 'scissors':
print("\nYou Won! {} crushes {}".format(user.title(), computer_move.title()))
#etc
Your computer() function calls a random number. So every time you call computer() in you code you are choosing 'at random' a completely new number. Because there are only three answers, you may actually end up with the right answer quite often.
Think of calling the function as rolling a die (with 3 sides, whoa). So now your program looks like this:
def RollDice():
return random.choice(OPTIONS)
#...
while True:
user = input("What do you choose Rock, Paper, Scissors: ").lower()
if user in OPTIONS:
# Possible user time a user can succeeds rock beats scissor, scissors cuts paper, paper covers rock
if user == RollDice:
print("tie")
elif user == 'rock' and RollDice == 'scissors':
print("\nYou Won! {} crushes {}".format(user.title(), RollDice.title()))
elif user == 'scissors' and RollDice =='rock':
print("\nComputer Won! {} crushes {}".format(RollDice.title(), user.title() ))
#...
Now you see what the problem is.What you really want is to save the value of 'one' random choice at the very beginning of your if statement:
if user in OPTIONS:
computerChoice = computer()
if user == computerChoice:
print("tie")
elif user == 'rock' and computerChoice == 'scissors':
print("\nYou Won! {} crushes {}".format(user.title(), computerChoice.title()))
elif user == 'scissors' and computerChoice =='rock':
print("\nComputer Won! {} crushes {}".format(computerChoice.title(), user.title() ))
#....
That way you have one constant choice saved in a variable to call on.
P.S. It would also be better to use raw_input instead of input so that the program will automatically change the users input into a string.
Disclaimer, the answer has been given, this is merely to peak the interest in generalizing the game.
To make any type of Rock-Paper-Scissor game you can realize that it is in fact a round-robin table of wins.
For instance if you do this:
P-R-S..P-R-S
you can see that the previous letter always wins on the next letter.
Using this approach it becomes easy to create custom rock-paper-scissor games using look-around tables:
import random
from collections import OrderedDict
# Important to retain order of "kill"
OPTIONS = OrderedDict([('P', 'Paper'),
('R', 'Rock'),
('S', 'Scissors')])
# N_KILLS determines how many letters in front it is killing
N_KILLS = 1
OPTIONS = OrderedDict([('P', 'Princess'),
('J', 'Knight'),
('W', 'Wizard'),
('D', 'Dragon'),
('K', 'King')])
N_KILLS = 2
# Create lookup table
LOOKUP = OPTIONS.keys()
# Number of items
N_ITEMS = len(LOOKUP)
# Options to choose from
STR_OPTIONS = ' ,'.join( OPTIONS.values() )
def computer():
return random.randint(0,N_ITEMS-1)
print("\n"+"-=-"*11)
print("Welcome to "+STR_OPTIONS)
print(" GAME")
print(" It's you vs. the computer!")
print("-=-"*11)
while True:
# Convert user option to integer
uidx = computer()
if uidx >= 0:
# Get computer index
cidx = computer()
d = cidx - uidx
# Correct for wrap-arounds
if d > N_KILLS:
d = d - N_ITEMS
elif d < -N_KILLS:
d = d + N_ITEMS
print(' You choose: '+OPTIONS[LOOKUP[uidx]] + ' computer chooses: '+OPTIONS[LOOKUP[cidx]])
if d == 0:
print(' Tie ...')
elif d > 0 and d <= N_KILLS:
print(' You WIN ...')
elif d < 0 and -d <= N_KILLS:
print(' You LOOSE ...')
else:
# This will only occur if N_KILLS*2+1<N_ITEMS
print(' Tie ...')
Not only is the code easier to read (in my opinion), but it becomes extremely easy to implement several new games. For instance check this amazing game out: http://www.umop.com/rps101.htm
You almost had it correct, as has been mentioned, for each game, the call to computer() should only be made once. It would also make sense to display the two player's choices. Also as you are working in title case, it would make sense to convert everything to use that to avoid needing to call .title() so many times.
import random
OPTIONS = ['Rock', 'Paper', 'Scissors']
# then check if the user lose's, wins ties
def computer():
return random.choice(OPTIONS)
print("\n"+"-=-"*11)
print("Welcome to ROCK, PAPER, SCISSORS")
print(" GAME")
print(" It's you Vs. the computer!")
print("-=-"*11)
while True:
user_choice = input("\nWhat do you choose Rock, Paper, Scissors: ").title()
computer_choice = computer()
print("User: {} Computer: {}".format(user_choice, computer_choice))
if user_choice in OPTIONS:
# Possible user_choice time a user_choice can succeeds rock beats sicissor, sicissors cuts paper, paper covers rock
if user_choice == computer_choice:
print("tie")
elif user_choice == 'Rock' and computer_choice == 'Scissors':
print("You Won! {} crushes {}".format(user_choice, computer_choice))
elif user_choice == 'Scissors' and computer_choice == 'Rock':
print("Computer Won! {} crushes {}".format(computer_choice, user_choice ))
elif user_choice == 'Scissors' and computer_choice == 'Paper':
print("You Won! {} cuts {}".format(user_choice, computer_choice))
elif user_choice == 'Paper' and computer_choice == 'Scissors':
print("Computer Won! {} cuts {}".format(computer_choice, user_choice))
elif user_choice == 'Paper' and computer_choice == 'Rock':
print("You Won! {} covers {}".format(user_choice, computer_choice))
elif user_choice == 'Rock' and computer_choice == 'Paper':
print("Computer Won! {} covers {}".format(computer_choice, user_choice))
else:
print("Make sure you choose either Rock, Paper or Scissors")
So a game would look like:
-=--=--=--=--=--=--=--=--=--=--=-
Welcome to ROCK, PAPER, SCISSORS
GAME
It's you Vs. the computer!
-=--=--=--=--=--=--=--=--=--=--=-
What do you choose Rock, Paper, Scissors: rock
User: Rock Computer: Scissors
You Won! Rock crushes Scissors

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