Rock, Paper, Scissors game

Larry Hudson orgnut at yahoo.com
Fri Aug 16 22:55:38 EDT 2013


Some time ago there was a post asking for help on a rock/paper/scissors
game.  I read that thread at the time it was posted, but since it
received several answers I didn't pay too much attention to it.  But I
can't find that thread again right now.  However, the subject stuck
(loosely) in my mind, and it finally fermented enough that I wanted to
try writing a version myself.

My approach is very different from the original.  It is based on the
fact that there are only nine possible combinations.  I calculate a
value based on the combination (it's effectively calculating the value
of a ternary number) and use this value as an index into a tuple of
Results strings and a tuple of win/lose/draw codes.

Probably the least obvious and most confusing aspect is how I piece
together these output strings, using the new-style print formatting
syntax.  The rest of the program should be pretty straight-forward.
I think it's fairly well commented.

Of course, I don't claim this to be optimum, or even necessarily a
good approach -- but it works.  And I thought some people might find
it interesting look at and try.

(An irrelevant side-note:  I wrote it on a Raspberry Pi.)

===========  <Code starts here>  ==========

#!/usr/bin/env python3

#   rps.py -- Rock, Paper, Scissors game

from random import choice

WIN  = 0
LOSE = 1
DRAW = 2

def get_result(h, c):
     """Determine who wins this round,
         return appropriate string and win/lose/draw code.

         h:  Human's selection (r, p or s)
         c:  Computer's selection (r, p or s)
     """
     def val(c):
         """Convert charcter r, p or s to values 0, 1 or 2"""
         return 'rps'.index(c)

     #   Strings used in results
     rp = 'Paper covers Rock.  {}'
     rs = 'Rock smashes scissors.  {}'
     ps = 'Scissors cuts paper.  {}'
     ti = 'We both have {}.  {}'
     #   Win/lose/draw codes
     win = (DRAW, WIN, LOSE, LOSE, DRAW, WIN, WIN, LOSE, DRAW)
     #   Win/lose/draw strings
     wins = ('You win', 'I win', "It's a draw")
     #   Results strings
     res = (
         ti.format('rocks', wins[DRAW]), #   r-r
         rp.format(wins[WIN]),           #   r-p
         rs.format(wins[LOSE]),          #   r-s
         rp.format(wins[LOSE]),          #   p-r
         ti.format('paper', wins[DRAW]), #   p-p
         ps.format(wins[WIN]),           #   p-s
         rs.format(wins[WIN]),           #   s-r
         ps.format(wins[LOSE]),          #   s-p
         ti.format('scissors', wins[DRAW]) # s-s
     )
     score = val(h) + 3 * val(c)         #   Calculate score
     return res[score], win[score]       #   Result string & win code

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='')
     res, scr = get_result(human, computer)
     scores[scr] += 1                    #   Count win/lose/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.')

==========  <Code ends here>  ==========

      -=- Larry -=-



More information about the Python-list mailing list