Python rock paper scissors score counter - python

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.

Related

How can I do a cumulative sum of wins, losses and draws here?

I have written the below code for a rock, paper, scissors game as my first bit of independent coding. I've tried every possible solution I can possibly think of to get a cumulative running total of wins, losses and draws, however every time it only shows me the most recent result - i.e. 1 win 0 losses 0 draws even on the 50th game if the most recent game was a win.
Can anybody suggest a way to solve this?
# Rock, Paper, Scissors!
import random
import time
print('Welcome to Rock, Paper, Scissors, a Python recreation of the classic game.')
print('The computer will randomly choose a sign at the start of the run for you to try to beat.')
print('Choose carefully...')
def fullgame():
compguess = random.randint(1, 3)
if compguess == 1:
compsign = 'rock'
elif compguess == 2:
compsign = 'paper'
else:
compsign = 'scissors'
playsign = input('Would you like to throw rock, paper or scissors? ')
while playsign != 'rock' and playsign != 'paper' and playsign != 'scissors':
print('You need to pick a valid sign!')
playsign = input('Would you like to throw rock, paper or scissors? ')
def numberallocator(rps):
if rps == 'rock':
return 1
elif rps == 'paper':
return 2
elif rps == 'scissors':
return 3
else:
print('That\'s not a valid sign!')
playguess = numberallocator(playsign)
numberallocator(playsign)
def game(cg, pg):
print('The computer is deciding...')
time.sleep(1)
print('The computer throws ' + compsign + ' and you throw ' + playsign + '...')
time.sleep(1)
if cg == pg:
print('It\'s a draw! You both picked ' + compsign)
return 'd'
else:
if cg == 1:
if pg == 2:
print('You win! Paper beats rock!')
return 'w'
elif pg == 3:
print('You lose! Rock beats scissors!')
return 'l'
elif cg == 2:
if pg == 1:
print('You lose! Paper beats rock!')
return 'l'
elif pg == 3:
print('You win! Scissors beats paper!')
return 'w'
else:
if pg == 1:
print('You win! Scissors beats rock!')
return 'w'
elif pg == 2:
print('You lose! Scissors beats paper!')
return 'l'
game(compguess, playguess)
playagain = 'y'
gamesplayed = 0
while playagain == 'y' or playagain == 'Y':
fullgame()
gamesplayed = gamesplayed + 1
print('You have played ' + str(gamesplayed) + ' games.')
playagain = input('Play again? y/n: ')
while playagain != 'y' and playagain != 'n':
print('You must pick y or n!')
playagain = input('Play again? y/n: ')
print('Thank you for playing rock, paper, scissors! This has been coded in Python by Ethan Lang!')
Thank you!
If you want to save a variable outside of all the functions, and modify it inside a function, you can use the Python global keyword. Otherwise, when you try to modify the variable inside a function, even if you defined it already outside the function, Python will assume you meant to create a brand-new variable, with its scope only function-level, and the variable with global scope won't be modified. To specify that you want to modify the global variable, you can use
global <variable_name>
as the first line in your function. That way, Python knows that any references to variable_name inside your function refer to the "global" variable (outside the function).
Disclaimer: using global variables is generally regarded as a Bad Idea. It makes it more difficult to fix issues with your code, since any code could possibly be modifying your global variables, which makes it harder to keep track of where it could be going wrong. For more info, see Why are global variables evil?
Wherever possible, you should try to find another solution. In this case, the solution in #JNevill's comment is probably a better idea.

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.

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

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

Categories

Resources