Rock Paper Scissors in Python - python

I am trying to write a Python program and I am having a hard time getting my score. I have written it as a value returning function and every time I run the program it seems to skip the step where it retrieves the score unless I include an else statement which it will automatcially jump the the else statement.
I will attach the full code below.
Thank you very much for any help, I'm greatful!
This is also my first time posting in this forum I apologize if I screw something up.
#constants
Rock = 1
Paper = 2
Scissors = 3
#Define the main function
def main():
#set control loop
keep_going = 'Y'
#set counter to zero
computer_wins = 0
player_wins = 0
tie_score = 0
#call display message
display_message()
while keep_going == 'y' or keep_going == 'Y':
play_game()
#prompt user to keep going
keep_going = input('would you like to play again? (Y for Yes): ')
print('The computer won', computer_wins, 'times')
print('The player won', player_wins, 'times')
print('There were', tie_score, 'tie scores')
def play_game():
#get random input
computer = get_random()
#get the players input
play = get_play()
#validate input
if play == '1' or play == '2' or play == '3':
play == True
else:
play == False
print('Error: Invalid Entry')
play = input('Please enter 1 for Rock, 2 for Paper, or 3 for Scissors: ')
if play == computer:
print('Tie Score, Please try again')
tie_score += 1
else:
get_score(computer, play)
print('The computer chose:', computer)
print('The player chose: ', play)
#define display message
def display_message():
print('Welcome to Rock Paper Scissors, a game of chance to see who will')
print('outsmart the other. This game is Man VS Computer.')
print('The program will select a random integer and then ask you for an integer')
print('1 for Rock 2 for paper or 3 for Scissors. The program will then tell')
print('you who won the game.')
print('GOOD LUCK!')
print
print
def get_random():
import random
#generate random int
computer = random.randint(1, 3)
return computer
def get_play():
#prompt user to enter an integer 1, 2, or 3
play = input('Select 1 for Rock, 2 for Paper, or 3 for Scissors: ')
return play
def get_score(computer, play):
if computer == 1 and play == 2:
score = 'player wins'
print('Paper covers Rock, Player Wins')
#player wins
player_wins += 1
elif computer == 1 and play == 3:
score = 'computer wins'
print('Scissors cut Paper, Computer Wins')
#computer wins
computer_wins += 1
elif computer == 2 and play == 1:
score = 'computer wins'
print('Paper covers Rock, Computer Wins')
#computer wins
computer_wins += 1
elif computer == 2 and play == 3:
score = 'player wins'
print('Scissors cut Paper, Player Wins')
#player wins
player_wins += 1
elif computer == 3 and play == 1:
score = 'player wins'
print('Rock smashes Scissors, Player Wins')
#player wins
player_wins += 1
elif computer == 3 and play == 2:
score = 'computer wins'
print('Scissors cut Paper, Computer Wins')
#computer wins
computer_wins += 1
#call main function
main()

There's so much wrong with this, it's hard to know where to start (but don't get discouraged)...
First of all, it looks like (mostly from your use of input vs. raw_input and your parens with your print statements) you're using Python 3, which already is going to limit the amount of help you get. Most people are still using Python 2.6 or 2.7. But with that out of the way...
The main remaining issues addressing your question are:
First: you're using strings for player input (e.g. '1', '2', '3'), and numbers for computer choice (e.g. 1, 2, 3). So you need to compare them as such. In other words, instead of:
if computer == 1 and play == 2:
You would need to say:
if computer == 1 and play == '2':
Second: you're trying to reference one function's variables in another one, and that won't work. If you want your computer_wins, etc. variables to be global, you need to initialize them at the global scope, e.g. right after your "#constants" are declared and before you get into main. Then in any function that uses them, you must say e.g. global computer_wins to indicate they are global and not local.
Once you get these issues addressed, it should work a bit better, but you'll still need to do a lot of cleanup and keep working on it!
Keep at it, and soon it will be natural for you.

I answered your question separately, but just for fun here's a little working Rock, Paper, Scissors game to look at. This one is for Python 2.x and probably won't work in Python 3, but it might be helpful for you or somebody in the future searching for this.
# "Rock, Paper, Scissors" demo for Python 2.x
# by Dan Kamins
import random
ROCK = 1
PAPER = 2
SCISSORS = 3
NAMES = { ROCK: 'Rock', PAPER: 'Paper', SCISSORS: 'Scissors' }
WHAT_BEATS_WHAT = { ROCK: SCISSORS, PAPER: ROCK, SCISSORS: PAPER }
WIN_ACTIONS = { ROCK: 'crushes', PAPER: 'smothers', SCISSORS: 'cuts' }
score_player = 0
score_computer = 0
score_ties = 0
def main():
intro()
while main_loop():
pass
summary()
def intro():
print "Welcome to Rock, Paper, Scissors!"
def main_loop():
player = get_player_input()
computer = random.randint(1, 3)
check_result(player, computer)
return ask_play_again()
def check_result(player, computer):
global score_player, score_computer, score_ties
if player == computer:
print "Tie! Computer also chose {0}.".format(NAMES[computer])
score_ties += 1
else:
if WHAT_BEATS_WHAT[player] == computer:
print "Your massive {0} {1} the computer's {2}!".format(
NAMES[player], WIN_ACTIONS[player], NAMES[computer])
score_player += 1
else:
print "The computer's {0} {1} your pathetic {2}!".format(
NAMES[computer], WIN_ACTIONS[computer], NAMES[player])
score_computer += 1
def ask_play_again():
again = raw_input("Enter Y to play again: ")
return again in ('y', 'Y')
def get_player_input():
while True:
print
player = raw_input("Enter 1 for Rock 2 for paper or 3 for Scissors: ")
try:
player = int(player)
if player in (1,2,3):
return player
except ValueError:
pass
print "Please enter a number from 1 to 3."
def summary():
global score_player, score_computer, score_ties
print "Thanks for playing."
print "Player won: ", score_player
print "Computer won: ", score_computer
print "Ties: ", score_ties
if __name__ == '__main__':
main()

A couple quick notes from quickly skimming the code:
In get_score() you could add an else clause to handle any ties that happen and you wouldn't have to check for it explicitly in play_game()
Move the import random to the top of the file. imports are generally always found at the top of the file. Also, there's no need to re-import every time you want a random number.
Not sure if this is a typo, cause play seems to always hold an integer, but you have play == True and play == False inside play_game(). If you want to make play contain either True or False, you need to be using a single equals sign, eg, play = True. But this doesn't seem to make sense because you're comparing play to computer as if they're integers.
Also, what are you trying to accomplish with the score variable in the get_score() method?
Ah, if you made the get_score() method return something so you know who won the match it would be helpful. You can't access computer_wins or player_wins inside the get_score() method because they were defined inside main(). A simple way to do this is return an int from get_score(). here is a rather C-style way of handling it (returning -1/0/1). something like (pseudo code):
def get_score():
score = 0
if computer wins:
score = -1
elif player wins:
score = 1
return score
winner = get_score()
if winner == 0:
print 'tie game'
elif winner == 1
print 'the player won'
else:
print 'the computer won'

Here's another variant that works both in Python 2.x and 3.x:
try: input = raw_input
except NameError: input = input # py3k
import random
import sys
import textwrap
from collections import namedtuple
ROCK, PAPER, SCISSORS = ROCK_PAPER_SCISSORS = range(1, 4)
NAME = dict(zip(ROCK_PAPER_SCISSORS, "Rock Paper Scissors".split()))
Score = namedtuple('Score', 'win verb')
GAME_MATRIX = { # who wins and who does what
(PAPER, ROCK): Score(win=True, verb='covers'),
(SCISSORS, PAPER): Score(win=True, verb='cut'),
(ROCK, SCISSORS): Score(win=True, verb='smashes'),
}
GAME_MATRIX.update(dict(((second, first), Score(not win, verb))
for (first,second), (win,verb) in GAME_MATRIX.items()))
def main():
# keep scores: how many times computer, player win and number of ties
scores = dict(zip("computer player tie".split(), [0]*3))
display_welcome_message()
# set control loop
keep_going = 'Y'
while keep_going.upper() == 'Y':
try: play_game(scores)
except Exception as e:
print("Error: %s" % (e,))
sys.exit(1)
# prompt player to keep going
keep_going = input('Would you like to play again? (Y for Yes): ')
print('\nThe computer won {computer} times\n'
'The player won {player} times\n'
'There were {tie} tie scores'.format(**scores))
def play_game(scores):
# get players choices for this round
computer_choice = random.choice(ROCK_PAPER_SCISSORS)
player_choice = get_player_input()
# print choices
for player, choice in [('computer', computer_choice),
('player', player_choice)]:
print('The {0} chose: {1} ({2})'.format(player, NAME[choice], choice))
# update scores; print who wins
if player_choice == computer_choice:
scores['tie'] += 1
print('Tie Score, Please try again')
else:
score = GAME_MATRIX[computer_choice, player_choice]
if score.win: # computer wins
scores['computer'] += 1
template = '{first} {verb} {second}, Computer wins'
else: # player wins
scores['player'] += 1
template = '{second} {verb} {first}, Player wins'
print(template.format(first=NAME[computer_choice],
second=NAME[player_choice], verb=score.verb))
def display_welcome_message():
print(textwrap.fill(textwrap.dedent("""
Welcome to Rock Paper Scissors, a game of chance to see who
will outsmart the other. This game is Man VS Computer. The
program will select a random integer and then ask you to input
%s for Rock %s for Paper or %s for Scissors. The program will
then tell you who won the game. GOOD LUCK!
""" % tuple(ROCK_PAPER_SCISSORS))))
def get_player_input(ntries=10):
for _ in range(ntries):
try:
choice = int(input('\nSelect %s for Rock, %s for Paper, or '
'%s for Scissors: ' % tuple(ROCK_PAPER_SCISSORS)))
except ValueError:
pass
else:
if choice in ROCK_PAPER_SCISSORS:
return choice # success
print('Error: your choice must be one of: %s' % (
', '.join(map(str, ROCK_PAPER_SCISSORS))))
raise RuntimeError('failed to get player choice in %d tries' % ntries)
if __name__=="__main__":
main()

This code might be a good reference for you. :)
Good Luck !
Note that this is Py2.x code
# Author: Niklas Rosenstein
# Created: 2011/10/23
import sys
import random
PAPER = 0
ROCK = 1
SCISSOR = 2
WIN = 10
LOSS = 11
TIE = 12
TABLE = {
PAPER: 'Paper',
ROCK: 'Rock',
SCISSOR: 'Scissor',
}
if 'expand TABLE':
# just for overvieability
# expands the TABLE conveniently
tableExpand = [
(PAPER,('paper', 'p', '0')),
(ROCK, ('rock', 'r', 'stone', '1')),
(SCISSOR, ('scissor', 's', '2'))
]
exp = None
key = None
for exp in tableExpand:
for key in exp[1]:
TABLE[key] = exp[0]
del tableExpand, exp, key
class Game(object):
wins = 0
losses = 0
ties = 0
def evaluateInput(self, inp):
# evaluate the input
# raises ValueError if input is invalid
# lowercase the string
inp = inp.strip()
inp = inp.lower()
# comparison table
try:
return TABLE[inp]
except KeyError:
raise ValueError, 'Input is invalid.'
def choose(self, choice):
# make a choice and compare it with
# the computers choice
# check if the choice is correct
if choice not in [ROCK, PAPER, SCISSOR]:
raise ValueError, 'Expected Id of either ROCK, PAPER or SCISSOR'
# generate a choice for the computer
com = random.choice([ROCK, PAPER, SCISSOR])
result = choice - com
if result == 0:
self.ties += 1
return TIE, com
elif result < 0:
self.wins += 1
return WIN, com
else:
self.losses += 1
return LOSS, com
TEXT_CHOOSE = 'Choose (or "quit" to quit): '
TEXT_PLAYER_CHOOSE = "You've choosen: "
TEXT_COMPUTER_CHOOSE = 'The computer choosed: '
TEXT_CHOICE_INVALID = 'You choice is invalid.\n'
TEXT_WIN = "You've won this match."
TEXT_LOSS = "You've lost this match."
TEXT_TIE = "This match was tie."
TEXT_GOODBYE = "Thanks for playing."
TEXT_WELCOME = "Welcome to Rock-Paper-Scissor !\n" \
"This game is all about guessing. Try to choose the\n" \
"thing that beats the computers choice. Thereby, the\n" \
"following rules are importan:\n" \
" Paper beats Rock.\n" \
" Rock beats Scissor.\n" \
" Scissor beats Paper.\n" \
"\n" \
"Valid inputs are:\n\n" \
" | for Paper: | p | paper | - | 0 |\n" \
" | for Rock: | r | rock | stone | 1 |\n" \
" | for Scissor: | s | scissor | - | 2 |\n" \
" | To quit the game: | q | quit | - | - |\n" \
"\n" \
"Much fun whishes you: Niklas Rosenstein (2011)\n" \
+ ("-" * 50) + "\n"
def printScores(g):
print "Scores:"
print " Wins: %s" % g.wins
print " Losses: %s" % g.losses
print " Ties: %s" % g.ties
def main():
g = Game()
# play the game ;-)
print TEXT_WELCOME
while True:
inp = raw_input(TEXT_CHOOSE)
if inp.lower() in ('q', 'quit'):
break
try:
inp = g.evaluateInput(inp)
except ValueError:
print TEXT_CHOICE_INVALID
continue
t, com = g.choose(inp)
inp = TABLE[inp]
com = TABLE[com]
print TEXT_PLAYER_CHOOSE, inp
print TEXT_COMPUTER_CHOOSE, com
print
if t == WIN:
print inp, "beats", com + ".",
print TEXT_WIN
elif t == LOSS:
print com, "beats", inp + ".",
print TEXT_LOSS
else:
print inp, "euqals", com + ".",
print TEXT_TIE
print
printScores(g)
print "-" * 50
print
print TEXT_GOODBYE
printScores(g)
print
print "Press any key to exit."
sys.stdin.read(1)
main()

Here is another way to do it:
import random;
print ('Game of chance 1=Rock,2=Paper,3=Scissor');
print ('Type 9 to exit');
while 1:
z=random.randint(1,3);
a=int(input('1=Rock,2=Paper,3=Scissor:--->'));
if a==z:
print ('Tie!!!');
if a==1 and z==2:
print ('Rock covers paper So You Win!!!');
if a==2 and z==3:
print ('Scissor cuts paper so you loose :(');
if a==2 and z==1:
print ('Rock covers paper so you loose :(');
if a==3 and z==2:
print ('Scissor cuts paper So You Win!!!');
if a==9:
break
print ('Thanks for playing the game')

Another way of making Rock, Paper, Scissors but without looping is this...
import random
Rock = '1'
Paper = '2'
Scissors = '3'
print('Welcome to Rock, Paper Scissors! The game of all kids to decide on something. \nIn this game you will have to beat the computer once. \n(Psst if it\'s a draw the start the program again! ;D)\nSo how to play. Well, it\'s simple. Pick 1 for Rock, 2 for Paper and 3 for Scissors. \nSo Rock beats Scissors. Scissors cuts Paper and Paper covers Rock. Got it Lets play')
player=int(input('Please enter number 1 = Rock, 2 = Paper, 3 = Scissors: '))
if player<1 or player>3:
player=int(input('Invalid number. Please enter number 1 = Rock, 2 = Paper, 3 = Scissors: '))
if player<1 or player>3:
print('Well, now you can\'t play this game because you are mucking around. Next time DON\'T!')
else:
computer=random.randint(1, 3)
print(player,computer)
print('Remember Rock = 1, Paper = 2 and Scissors = 3')
if player==1 and computer==1 or player==2 and computer==2 or player==3 and computer==3:
print('It\'s a draw. =l Restart the game if you want to.')
if player==1 and computer==2 or player==2 and computer==3 or player==3 and computer==1:
print('Computer wins! You lose. Sorry. =(')
if player==1 and computer==3 or player==2 and computer==1 or player==3 and computer==2:
print('You have won. Well done. =D')
If that is any help.

Yet another way, adding Lizard and Spock
import random
def winner(p1, p2):
actors = ['Paper', 'Scissors', 'Spock', 'Lizard', 'Rock']
verbs = {'RoLi':'crushes', 'RoSc':'breaks', 'LiSp':'poisons',
'LiPa':'eats', 'SpSc':'smashes', 'SpRo':'vaporizes',
'ScPa':'cut', 'ScLi':'decapitate', 'PaRo':'covers',
'PaSp':'disproves'}
p1, p2 = actors.index(p1), actors.index(p2)
winner, looser = [(p1, p2), (p1, p2), (p2, p1), (p1, p2), (p2, p1)][p1 - p2]
return ' '.join([actors[winner],
verbs.get(actors[winner][0:2] + actors[looser][0:2],
'ties'),
actors[looser]])
more = True
while more:
z=random.randint(0,4);
a=int(input('1=Rock, 2=Paper, 3=Scissors, 4=Lizard, 5=Spock:--->'))-1;
if a==z:
print 'Tie\n';
else:
try:
print winner(a,z) + '\n'
except IndexError:
more = False
print ('Thanks for playing the game')
Output:
1=Rock, 2=Paper, 3=Scissors, 4=Lizard, 5=Spock:--->1
Rock crushes Lizard
1=Rock, 2=Paper, 3=Scissors, 4=Lizard, 5=Spock:--->2
Paper covers Rock
1=Rock, 2=Paper, 3=Scissors, 4=Lizard, 5=Spock:--->3
Scissors tie Scissors
1=Rock, 2=Paper, 3=Scissors, 4=Lizard, 5=Spock:--->4
Lizard poisons Spock

well... I would use a dictionary. If/elif/else statements work fine, but they are often messy. This is how I would approach it.
By the way, I am using Python 2. It seems like you are using Python 3 based on the way you use print and input. Don't copy off this code; just take the idea. I am using Python 2 because I am more comfortable with it; make the changes from both versions.
# Imports
import random
# Constants
SELECTION = ["rock", "paper", "scissors"]
WIN = -1 # This is a dummy assignment: we will return this value later.
WIN_LOSE_DICT = {("rock", "paper"): False,
("paper", "rock"): True,
("paper", "scissors"): False,
("scissors", "paper"): True,
("scissors", "rock"): False,
("rock", "scissors"): True}
# Variables
total_wins = 0
# Functions
def do_round():
comp = random.choice(SELECTION)
player = raw_input("Rock, paper, scissors, SHOOT! ").lower() # Set player response
# to lowercase
# Use input() on Python 3 and not raw_input()
while player not in SELECTION:
player = raw_input("Please choose either rock, paper, or scissors. ").lower()
if player == comp:
print "The computer chose %s: it is a tie." % comp
else:
result = WIN_LOSE_DICT[(player, comp)]
if result: # If you want to be clear, do - if result == True:
print "The computer chose %s: you win!" % comp
return WIN
else:
print "The computer chose %s: you lose" % comp
# Main
if __name__ == "__main__":
running = True
while running:
this_round = do_round()
if this_round == WIN:
total_wins += 1
print "You won %s times so far." % total_wins
continue_ = raw_input("Do you want to play another round (y/n) ?").lower()
if continue_ == "n":
continue
else:
running = False
print "Thank you for playing!"
I might have made a few mistakes here and there, but the concept is still there: use a dictionary and set a constant to be a negative number. You should also work on following PEP8 a bit more.

import random
lst=['rock','scisor','paper']
player_score=0
comp_score=0
print('''Welcome to the game of our childhood Rock, Paper and scisor.
play this game against the computer.You must input the
rock,paper,scisor .So let's start the game.''')
def new_game():
user_input=input("START A NEW GAME![Y/N]: \n")
if user_input.upper()=="Y":
global player_score
player_score=0
global comp_score
comp_score=0
RPS_game()
else:
print("Have a great day ahead!\n")
def again():
user_input=input("WANNA PLAY AGAIN![Y/N]: \n")
if user_input.upper()=="Y":
RPS_game()
else:
print("YOUR FINAL SCORE: ",player_score)
print("COMPUTER'S FINAL CORE: ",comp_score)
if comp_score>player_score:
print("OOPS!YOU LOOSE THE GAME\n")
new_game()
elif comp_score<player_score:
print("GREAT! YOU WON THE GAME\n")
new_game()
else:
print("IT'S A DRAW!\n")
new_game()
def RPS_game():
comp_move=random.choice(lst)
player_move=input("Enter your move: ")
if player_move=='rock' or player_move=='paper' or player_move=='scisor':
print("Computers Move:",comp_move)
if player_move=="rock":
if comp_move=="scisor":
print("YOU WON!")
global player_score
player_score=player_score+1
elif comp_move=="paper":
print("YOU lOOSE!")
global comp_score
comp_score=comp_score+1
elif comp_move=="rock":
print("TRY AGAIN!")
elif player_move=="paper":
if comp_move=="paper":
print("TRY AGAIN!")
elif comp_move=="scisor":
print("YOU lOOSE!")
comp_score=comp_score+1
elif comp_move=="rock":
print("YOU WON!")
player_score+=1
elif player_move=="scisor":
if comp_move=="paper":
print("YOU WON!")
player_score+=1
elif comp_move=="scisor":
print("TRY AGAIN!")
elif comp_move=="rock":
print("YOU LOOSE!")
comp_score=comp_score+1
again()
else:
print('''Enter correct spellings !
as "rock,paper,scisor"''' )
RPS_game()
RPS_game()

Related

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.

Python2.7: What is wrong with this program? It runs but the weird traceback error

The program runs fine. But with this error(screenshot). Its just blank. Its Python 2.7. And I have added Python to Environment Variables as well but nothing shows up on shell as well.
Code for Rock Paper and Scissors
import random
import time
rock = 1
paper = 2
scissors = 3
names = { rock: "Rock" , paper: "Paper" , scissors: "Scissors" }
rules = { rock: scissors , paper :rock , scissors: paper }
player_score = 0
computer_score = 0
def start():
print "Let's play a game of rock paper and scissors"
while game():
pass
scores()
def game():
player = move()
computer = random.randint(1,3)
result(player, computer)
return play_again()
def move():
while True:
print
player = raw_int("Rock = 1\nPaper = 2\nScissors =3\nMake a move: ")
try:
player = int(player)
if player in (1,2,3):
return player
except ValueError:
pass
print "Oops! I didn't understand that. Please enter 1,2 or 3."
def result(player, computer):
print "1..."
time.sleep(1)
print "2..."
time.sleep(1)
print "3..."
time.sleep(0.5)
print "Computer threw {0)!".format(names[computer])
global player_score,computer_score
if player == computer:
print "Tie game."
else:
if rules[player] == computer:
print "Your victory has been assured."
player_score += 1
else:
print" The computer laughs as you realise you have been defeated."
computer_score += 1
def play_again():
answer = raw_input("Would you like to play again? y/n: ")
if answer in ("Y", "Y" , "yes" , "Yes" , "Of course!"):
return answer
else:
print "Thank you very much for playing our game.See your next time!"
def scores():
global player_score,computer_score
print "High Scores"
print "Player:" , player_score
print "Computer:", computer_score
if _name_ == '_main_':
start()
Error:
Traceback (most recent call last): File
"C:/Users/Sarthak/Desktop/RPS.py", line 80, in
if name == 'main': NameError: name 'name' is not defined
You should fix your indentations and all other errors:
import random
import time
rock = 1
paper = 2
scissors = 3
names = { rock: "Rock" , paper: "Paper" , scissors: "Scissors" }
rules = { rock: scissors , paper :rock , scissors: paper }
player_score = 0
computer_score = 0
def start():
print "Let's play a game of rock paper and scissors"
while game():
pass
scores()
def game():
player = move()
computer = random.randint(1,3)
result(player, computer)
return play_again()
def move():
while True:
print #this is not how you could get int input in Python
player = raw_int("Rock = 1\nPaper = 2\nScissors =3\nMake a move: ")
try:
player = int(player)
if player in (1,2,3):
return player
except ValueError:
pass
print "Oops! I didn't understand that. Please enter 1,2 or 3." #note the indentation here
def result(player, computer):
print "1..."
time.sleep(1)
print "2..."
time.sleep(1)
print "3..."
time.sleep(0.5)
print "Computer threw {0)!".format(names[computer])
global player_score,computer_score
if player == computer:
print "Tie game."
else:
if rules[player] == computer:
print "Your victory has been assured."
player_score += 1
else:
print" The computer laughs as you realise you have been defeated."
computer_score += 1
def play_again(): #again, indentation
#and this is not how you could get string input in Python
answer = raw_input("Would you like to play again? y/n: ")
if answer in ("Y", "Y" , "yes" , "Yes" , "Of course!"):
return answer
else:
print "Thank you very much for playing our game.See your next time!"
def scores(): #note the indentation here
global player_score,computer_score
print "High Scores"
print "Player:" , player_score
print "Computer:", computer_score
if __name__ == '__main__': #note the underscores here
start()

Rock Paper Scissors Program Not Working (Python)

Problems:
Program does not seem to accept the integers entered. Won't add to win/loss/draw count and does not display computer choice in debug mode
Basics Design of the Program:
Write a program that lets the user play the game of Rock, Paper, Scissors against the computer.
The program should work as follows.
A menu is displayed:
Score: 0 wins, 0 draws, 0 losses
(D)ebug to show computer's choice
(N)ew game
(Q)uit
If the user enters "Q" or "q" the program would end. "N" or "n" for a new game, "D" or "d" for debug mode, anything else would cause an error message to be displayed.
When a game begins, a random number in the range of 1 through 3 is generated. If the number is 1, then the computer has chosen rock. If the number is 2, then the computer has chosen paper. If the number is 3, then the computer has chosen scissors. (Don't display the computer's choice yet unless we are in "D"ebug mode.)
The user enters his or her choice of “1-rock”, “2-paper”, or “3-scissors” at the keyboard.
The computer's choice is displayed.
A winner is selected according to the following rules:
• If one player chooses rock and the other player chooses scissors, then rock wins.
(The rock smashes the scissors.)
• If one player chooses scissors and the other player chooses paper, then scissors wins.(Scissors cuts paper.)
• If one player chooses paper and the other player chooses rock, then paper wins.
(Paper wraps rock.)
• If both players make the same choice, the game is a draw.
Your program would keep a running total of the number of wins, loses and draws.
Re-display the menu and repeat the game loop.
My Program:
import random
def main():
continuing = "y"
win = 0
lose = 0
draw = 0
while continuing == "y":
print("Score:", win,"wins,", draw, "draws,", lose,"losses")
print("(D)ebug to show computer's choice")
print("(N)ew game")
print("(Q)uit")
choice = input(" ")
if choice == "n" or choice == "N":
win, draw, lose = playgame(win, draw, lose)
elif choice == "d" or choice == "D":
win, draw, lose = playgame2(win, draw, lose)
elif choice == "q" or choice == "Q":
break
def playgame(win, draw, lose):
computer = random.randint(1,3)
player = input("Enter 1 for Rock, 2 for Paper, or 3 for Scissors: ")
if computer == 1 and player == 2:
Score = "You won"
win += 1
elif computer == 1 and player == 3:
Score = "You lost"
lose += 1
elif computer == 2 and player == 1:
Score = "You lost"
lose += 1
elif computer == 2 and player == 3:
Score = "You won"
win += 1
elif computer == 3 and player == 1:
Score = "You won"
win += 1
elif computer == 3 and player == 2:
Score = "You lost"
lose += 1
elif computer == player:
Score = "Draw"
draw += 1
return (win, draw, lose)
def playgame2(win, draw, lose):
computer = random.randint(1, 3)
player = input("Enter 1 for Rock, 2 for Paper, or 3 for Scissors: ")
if computer == 1 and player == 2:
Score = "You won"
print("Computer chose rock")
win += 1
elif computer == 1 and player == 3:
Score = "You lost"
print("Computer chose rock")
lose += 1
elif computer == 2 and player == 1:
Score = "You lost"
print("Computer chose paper")
lose += 1
elif computer == 2 and player == 3:
Score = "You won"
print("Computer chose paper")
win += 1
elif computer == 3 and player == 1:
Score = "You won"
print("Computer chose scissors")
win += 1
elif computer == 3 and player == 2:
Score = "You lost"
print("Computer chose scissors")
lose += 1
elif computer == player:
Score = "Draw"
print("Computer chose the same as you")
draw += 1
return (win, draw, lose)
main()
I'm no Pythonista, but at a guess, input returns strings, and you'll need to convert to integer before comparing to the computer's int.
I also think you are missing a trick in DRYing up your code - you should be able to have a single playgame method, which takes an additional boolean parameter debugmode, which instead of calling print directly, calls an indirection, e.g.:
def debugPrint(debugString, debugMode)
if debugMode
print(debugString)
Hope this makes sense?
This would work in Python 2.x, but, not in Python 3.x
In Python 3.x, input() returns strings. Thus, the player's input would be of the form "1" or "2" or "3". Since 1 and "1" are different, the program will not execute any of the lines in the if and elif blocks in playgame() and playgame2().
Here is a Python 3.x example:
>>> a = input("Input = ")
Input = 1
>>> print a
SyntaxError: Missing parentheses in call to 'print'
>>> print(a)
1
>>> a
'1'
>>> type(a)
<class 'str'>
Thus, you should use i = int(input("Input = ")) wherever you want an integer input.
However, in Python 2.x, input() will take 1 as 1 itself and not as "1". But, when you want to type a string as an inpu, you will have to give the quotes also. Here is an exxample:
>>> a1 = input("Input = ")
Input = 1
>>> a1
1
>>> type(a1)
<type 'int'>
>>> #I want to input a string now:
>>> a2 = input("Input = ")
Input = string
Traceback (most recent call last):
File "<pyshell#12>", line 1, in <module>
a2 = input("Input = ")
File "<string>", line 1, in <module>
NameError: name 'string' is not defined
>>> a2 = input("Input = ")
Input = "string"
>>> a2
'string'
>>> type(a2)
<type 'str'>
>>> a3 = raw_input("Input = ")
Input = hello
>>> a3
'hello'
>>> type(a3)
<type 'str'>
>>>
In Python 2.x, the raw_input() function takes the input as a string.

How do I compare random result against dictionary keys with 2 values?

I'm just starting out in Python, and I'm trying to modify a simple rock paper scissors game to be rock paper scissors lizard spock. As a result I now need to compare a randomly generated computer choice against not 1, but 2 dictionary items which indicate loosing values:
#!/usr/bin/python
import random
import time
rock = 1
paper = 2
scissors = 3
lizard = 4
spock = 5
names = { rock: "Rock", paper: "Paper", scissors: "Scissors", lizard: "Lizard", spock: "Spock"}
rules = { rock: [scissors, lizard], paper: [rock, spock], scissors: [paper, lizard], lizard: [paper, spock], spock: [rock, scissors]}
player_score = 0
computer_score = 0
def start():
print "Let's play a game of Rock, Paper, Scissors, Lizard, Spock"
while game():
pass
scores()
def game():
player = move()
computer = random.randint(1, 5)
result (player, computer)
return play_again()
def move():
while True:
print
player = raw_input("Rock = 1\nPaper = 2\nScissors = 3\nLizard = 4\nSpock = 5\nMake a move: ")
try:
player = int(player)
if player in (1,2,3,4,5):
return player
except ValueError:
pass
print "Oops! I didn't understand that. Please enter 1, 2, 3, 4, or 5."
def result(player, computer):
# print "1..."
# time.sleep(1)
# print "2..."
# time.sleep(1)
# print "3!"
# time.sleep(0.5)
print "Computer threw {0}!".format(names[computer])
global player_score, computer_score
for i in rules[player]:
if i == computer:
global outcome
outcome = "win"
if outcome == "win":
print "Your victory has been assured."
player_score += 1
elif player == computer:
print "Tie game."
else:
print "The computer laughs as you realise you have been defeated."
computer_score += 1
def play_again():
answer = raw_input("Would you like to play again? y/n: ")
if answer in ("y", "Y", "yes", "Yes", "Of course!"):
return answer
else:
print "Thank you very much for playing. See you next time!"
def scores():
global player_score, computer_score
print "HIGH SCORES"
print "Player: ", player_score
print "Computer: ", computer_score
if __name__ == '__main__':
start()
Unfortunately this code results in the player always winning... what am I doing wrong?
Thanks very much for your help :)
You've got outcome as a global, but you never set it to anything other than "win". So once you've won once, the value of outcome will always be "win".
def result(player, computer):
outcome = ""
You don't use outcome anywhere else, so there's no reason to make it a global anyway.
You really don't even need that variable at all. Combining this with what Hyperboreus' mentioned in his/her answer, your result method could start like this, with everything else being the same:
def result(player, computer):
print "Computer threw {0}!".format(names[computer])
global player_score, computer_score
if computer in rules[player]:
print "Your victory has been assured."
...
Let's say player and otherPlayer hold the codes for the hand forms they made. Then you can check losing by checking if one players' code is contained in the losing conditions of the other player's code.
if player in rules [otherPlayer]: doSomething()
Without criticising your code, I personally would implement it somehow along these lines. Maybe you can grab an idea of two from it, or even some patterns, you surely won't want to use:
import random
rules = '''Scissors cut paper
Paper covers rock
Rock crushes lizard
Lizard poisons Spock
Spock smashes scissors
Scissors decapitate lizard
Lizard eats paper
Paper disproves Spock
Spock vaporizes rock
Rock crushes scissors'''
rules = rules.lower ().split ()
rules = [_ for _ in zip (rules [::3], rules [2::3] ) ]
names = list (set (name for name, _ in rules) )
def turn ():
ai = random.choice (names)
player = input ('Enter your choice: ').lower ()
if player not in names: raise Exception ('Sheldon out of bounds.')
print ('AI chose {}.'.format (ai) )
if (ai, player) in rules:
print ('AI won.')
return (0, 1)
if (player, ai) in rules:
print ('You won.')
return (1, 0)
print ('Draw.')
return (0, 0)
score = (0, 0)
while True:
you, ai = turn ()
score = (score [0] + you, score [1] + ai)
print ('The score is Human:Machine {}:{}'.format (*score) )
if input ('Play again? [n/*] ').lower () == 'n': 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