Code Review for Paper, Rock, Scissors
Larry Hudson
orgnut at yahoo.com
Wed Oct 15 03:56:49 EDT 2014
On 10/14/2014 01:04 AM, Revenant wrote:
> Hi all!
>
> I'm new to Python and programming in general, and am trying to learn as much as I can about it.
>
> Anyway, for a basic first program I made a simple game of Paper, Rock, Scissors. For this program, I incorporated a main menu that presented three different options, allowed the user to play a game of Paper, Rock, Scissors, allowed them to play the game again, and most importantly checked the user's input to make sure the program doesn't fail due to errors.
>
> One thing I want to try to add is a "Press any key to continue" function that occurs at the end of the program when the user decides to quit. I looked at some options online, but haven't quite figured it out yet.
>
> As previously stated, I am new to Python and would also like to see if any of you programming gurus have some suggestions about how I can simplify code, and also if there are any other good starter programs to work on to improve my skills.
>
> Thanks for reading! Code is below:
>
[snip]
You've already received a lot of good advice, which I'm not going to repeat here. Rather, I'm
going to show you the version that I wrote some time ago. Whether this version is
good/bad/indifferent is up to someone else to say, but I'm showing it here just as an example of
a different approach that you might find interesting to study. Although, being new to Python,
some of the things here will probably be unfamiliar to you, particularly the new-style string
formatting which I use a lot.
The key to this approach is to recognize that there are only nine possible combinations. I
handle these in the get_result() function by stitching together pieces of strings in a
dictionary. This function is interesting because, although it has a total of 34 lines, 17 are
comments or blanks, 16 are data definitions, and only 1 line is actual code.
The get_rps() function is used to get the player's rock/paper/scissor choice. It also allows
'quit' as a fourth choice. This makes your proposed "Press any key..." unnecessary, because
this version will continue automatically until you specifically tell it to stop. Also it
accepts an empty input as the same as a 'quit' choice. Whether this is good or bad is
debatable, but it can easily be written either way. It returns the choice as a single
lower-case character, 'r', 'p', 's' or 'q'.
This version also makes heavy use of the constants WIN/LOSE/DRAW, which are defined as globals
at the top of the program. They help the clarity of the source. Normal convention is to make
the names of constants all upper-case. This is a convention only, not a requirement. The
scores are tracked in a three-element list, which use the WIN/LOSE/DRAW constants as the
indexes. The instruction display in my version is very short, but it could easily be replaced
with a longer version like yours.
FWIW, here is my code...
Note the first line is Linux-specific -- Windows will ignore it, or you can remove it.
#------------ Code starts here ------------
#!/usr/bin/env python3
# rps.py -- Rock, Paper, Scissors game
from random import choice
# Global constants
WIN = 0
LOSE = 1
DRAW = 2
def get_result(h, c):
"""Determine who wins this round
Parameters:
h: Human's selection (r, p or s)
c: Computer's selection (r, p or s)
Returns a tuple of the WIN/LOSE/DRAW value
and the string describing the results
"""
# Strings used in results
pr = 'Paper covers Rock. {}'
rs = 'Rock smashes Scissors. {}'
sp = 'Scissors cuts Paper. {}'
ti = 'We both have {}. {}'
# Win/lose/draw strings
wins = ('You win', 'I win', "It's a draw")
# Dictionary defining the results
res = {
'rr' : (DRAW, ti.format('rocks', wins[DRAW])),
'rp' : (LOSE, pr.format(wins[LOSE])),
'rs' : (WIN, rs.format(wins[WIN])),
'pr' : (WIN, pr.format(wins[WIN])),
'pp' : (DRAW, ti.format('paper', wins[DRAW])),
'ps' : (LOSE, sp.format(wins[LOSE])),
'sr' : (LOSE, rs.format(wins[LOSE])),
'sp' : (WIN, sp.format(wins[WIN])),
'ss' : (DRAW, ti.format('scissors', wins[DRAW]))
}
# Return the result tuple
return res[h + c]
def get_rps():
"""Get Rock/Paper/Scissor choice."""
while True:
select = input('\nDo you choose Rock, Paper or Scissors ').lower()
# Check for empty input or quit command
if not select or select in ['q', 'quit']:
return 'q' # return quit code
# Check for valid input
if select in ['r', 'rock', 'p', 'paper', 's', 'scissors']:
return select[0] # return first character
print('What did you say?? Try again please')
#================= Main Program starts here ==============
# Keep track of results:
# scores[0] = number of human wins
# scores[1] = number of computer wins
# scores[2] = number of draws
scores = [0] * 3
things = {'r':'a rock', 'p':'paper', 's':'scissors'}
print("Let's play a game or Rock, Paper, Scissors.\n")
print('Enter "r", "p", "s", "rock", "paper", or "scissors" for your choice.')
print('Use empty input, "q" or "quit" to end the game.')
while True:
computer = choice('rps') # Computer selects
human = get_rps() # Human selects
if human == 'q':
break
print('You have {}, I have {}. '.format(
things[human], things[computer]), end='')
scr, res = get_result(human, computer)
scores[scr] += 1 # Count win/loss/draw
print(res) # And show results
# Show final scores
print('\nTotal scores:')
print('\tYou won {} games'.format(scores[WIN]))
print('\tComputer won {} games'.format(scores[LOSE]))
print('\tThere were {} tie games'.format(scores[DRAW]))
print('\nThanks for playing with me. Bye now.')
#------------ End of code --------------
-=- Larry -=-
More information about the Python-list
mailing list