Rock Paper Scissors Lizard Spock

simple simulation of a game of chance with python

Bonnie Cooper

Rock, Paper, Scissors, Lizard, Spock: about RPSLS

    RPSLS is an extention of the popular game Rock, Paper, Scissors (RPS). RPS is a game of chance where each match players signal for rock with a closed fist, paper with an open hand or scissors with with pointer and middle fingers extended. By conventional rules: rock smashes scissors, paper covers rock and scissors cuts paper. RPS and similar games have a long and interesting history. In fact, variants are reported to have been played in China as early as the Han dynasty (206BB - 220AD) (1)
    RPSLS improves on it’s more popular predecessor by adding lizard and spock as two extra response options for each player. Each response beats 2 other options but loses to the remaining two. The original rules state “Scissors cuts paper covers rock crushes lizard poisons spock smashes scissors decaipates lizard eats paper disproves spock vaporizes rock crushes scissors” (2) and were popularized in the sitcom Big Bang Theory:

The rules are summarized here:

player wins against loses to
Rock Lizard & Scissors Paper & Spock
Paper Rock & Spock Scissors & Lizard
Scissors Paper & Lizard Spock & Rock
Lizard Sock & Paper Scissors & Rock
Spock Scissors & Rock Lizard & Paper


The addition of Spock & Lizard improves upon RPS by reducing the the chance of games ending in a draw. RPS works pretty well for 2 players competing in a best of three game. However, when more players are added the chances of a tie are \(\frac{1}{n}\) therefore, adding two more options adds variety and improved playability to the game.


Getting started

This R markdown notebook will be running python and there are a few steps necessary to get this set up:

Will need to include the R reticulate library & will have to point to the right python version to use:

## [1] "3.7.6 (default, Jan  8 2020, 20:02:53) \n[GCC 7.3.0]"


Now to import the python libraries that will be used:

## We are calling python from R in this R chunk

RPSLS Helper functions & accesories

Great! Now that the environment is set up, we will begin by defining a few helper functions for the RPSLS simulation as well as a few accesories.
The following code builds a few lists that will be referenced to help visualize the simulation and to make things a little more fun/creative. The lists hold multi-line strings of ascii art text generated by a Text to Ascii Art Generator. Here, the font from ‘Doom’ was used, because, frankly, it would be wrong not to.

stringPlayers = (
"""
______           _     
| ___ \         | |    
| |_/ /___   ___| | __ 
|    // _ \ / __| |/ / 
| |\ \ (_) | (__|   <  
\_| \_\___/ \___|_|\_\   """,
"""
 _____                  _    
/  ___|                | |   
\ `--. _ __   ___   ___| | __
 `--. \ '_ \ / _ \ / __| |/ /
/\__/ / |_) | (_) | (__|   < 
\____/| .__/ \___/ \___|_|\_\\
      | |                    
      |_|                    
      """,
"""
______                     
| ___ \                    
| |_/ /_ _ _ __   ___ _ __ 
|  __/ _` | '_ \ / _ \ '__|
| | | (_| | |_) |  __/ |   
\_|  \__,_| .__/ \___|_|   
          | |              
          |_|              
          """,
"""
 _     _                      _ 
| |   (_)                    | |
| |    _ __________ _ _ __ __| |
| |   | |_  /_  / _` | '__/ _` |
| |___| |/ / / / (_| | | | (_| |
\_____/_/___/___\__,_|_|  \__,_|
                                
                                """,
"""
 _____      _                        
/  ___|    (_)                       
\ `--.  ___ _ ___ ___  ___  _ __ ___ 
 `--. \/ __| / __/ __|/ _ \| '__/ __|
/\__/ / (__| \__ \__ \ (_) | |  \__ \\
\____/ \___|_|___/___/\___/|_|  |___/
                                     
                                                        
""")

stringOutcomes = (
"""
 _____ ________  _________ _   _ _____ ___________ 
/  __ \  _  |  \/  || ___ \ | | |_   _|  ___| ___ \\
| /  \/ | | | .  . || |_/ / | | | | | | |__ | |_/ /
| |   | | | | |\/| ||  __/| | | | | | |  __||    / 
| \__/\ \_/ / |  | || |   | |_| | | | | |___| |\ \ 
 \____/\___/\_|  |_/\_|    \___/  \_/ \____/\_| \_|
                                                   
                                                   
 _    _ _____ _   _  _____   _ _ _                 
| |  | |_   _| \ | |/  ___| | | | |                
| |  | | | | |  \| |\ `--.  | | | |                
| |/\| | | | | . ` | `--. \ | | | |                
\  /\  /_| |_| |\  |/\__/ / |_|_|_|                
 \/  \/ \___/\_| \_/\____/  (_|_|_)                
                                                   
                                                   """,
"""
 _   _ _   ____  ___  ___   _   _                  
| | | | | | |  \/  | / _ \ | \ | |                 
| |_| | | | | .  . |/ /_\ \|  \| |                 
|  _  | | | | |\/| ||  _  || . ` |                 
| | | | |_| | |  | || | | || |\  |                 
\_| |_/\___/\_|  |_/\_| |_/\_| \_/                 
                                                   
                                                   
 _    _ _____ _   _  _____   _ _ _                 
| |  | |_   _| \ | |/  ___| | | | |                
| |  | | | | |  \| |\ `--.  | | | |                
| |/\| | | | | . ` | `--. \ | | | |                
\  /\  /_| |_| |\  |/\__/ / |_|_|_|                
 \/  \/ \___/\_| \_/\____/  (_|_|_)                
                                                   
                                                   
        __                                         
       / _|                                        
      | |_ ___  _ __   _ __   _____      __        
      |  _/ _ \| '__| | '_ \ / _ \ \ /\ / /        
 _ _ _| || (_) | |    | | | | (_) \ V  V /   _ _ _ 
(_|_|_)_| \___/|_|    |_| |_|\___/ \_/\_/   (_|_|_)
                                                   
                                                   """,
"""
         _   _          _                                   
        | | (_)        | |                                  
  __ _  | |_ _  ___  __| |   __ _  __ _ _ __ ___   ___      
 / _` | | __| |/ _ \/ _` |  / _` |/ _` | '_ ` _ \ / _ \\     
| (_| | | |_| |  __/ (_| | | (_| | (_| | | | | | |  __/     
 \__,_|  \__|_|\___|\__,_|  \__, |\__,_|_| |_| |_|\___|     
                             __/ |                          
                            |___/                           
  ___                     _                _            __  
 / / |                   | |              (_)           \ \\ 
| || |__   _____      __ | |__   ___  _ __ _ _ __   __ _ | |
| || '_ \ / _ \ \ /\ / / | '_ \ / _ \| '__| | '_ \ / _` || |
| || | | | (_) \ V  V /  | |_) | (_) | |  | | | | | (_| || |
| ||_| |_|\___/ \_/\_/   |_.__/ \___/|_|  |_|_| |_|\__, || |
 \_\                                                __/ /_/ 
                                                   |___/    """
)


The following code estaplishes a pandas dataframe structure that will relate the proper action verbs with paired options (e.g. Spock vaporizes Rock).

##    W_Choice  L_Choice       Action
## 0  scissors     paper         cuts
## 1     paper      rock       covers
## 2      rock    lizard      crushes
## 3    lizard     spock      poisons
## 4     spock  scissors      smashes
## 5  scissors    lizard  decapitates
## 6    lizard     paper         eats
## 7     paper     spock    disproves
## 8     spock      rock    vaporizes
## 9      rock  scissors      crushes


These helper functions will associate a number to a name and the same name to the corresponding number. This is necessary to relate the user input to the randomly generated ‘computer’ result.

## spock
## 1



The next function controls the logic of a RPSLS game:

def rpsls( player_choice, display ): 
    """
    Takes a name as input, generates a random selection, calculates the game outcome. Takes a second parameter to indicate if the results should be displayed
    player_choice: string
    display: bool. True to display game outcome
    """
    player_choice = str.lower( player_choice )
    player_number = name_to_number( player_choice )
    # compute random result to simulate the input's competition using random.randrange()
    comp_number = random.randrange( 0, 4 )
    #convert comp_number to comp_choice using number_to_name()
    comp_choice = number_to_name( comp_number );
    #compute difference of comp_number and player_number modulo five
    difference = (comp_number - player_number) % 5
    #determine winner
    if( difference == 1 or difference == 2 ):
        gameOutcome = 0
        action = outcomeActions_df.query("L_Choice==@player_choice and     W_Choice==@comp_choice")['Action']
        gameAction = comp_choice + ' ' + action.values[0] + ' ' + player_choice + ' therefore: '
        gameOutcome = -1
    elif ( difference == 4 or difference == 3 ):
        gameOutcome = 1
        action = outcomeActions_df.query("W_Choice==@player_choice and L_Choice==@comp_choice")['Action']
        gameAction = player_choice + ' ' + action.values[0] + ' ' + comp_choice + ' therefore: '
        gameOutcome = 1
    elif( difference == 0 ):
        gameOutcome = 2
        gameAction = ' == '
        gameOutcome = 0
    if display:    
        print( "\n" )
        print( "Player chooses: " )
        print( stringPlayers[player_number])  
        print( "Computer chooses: ")
        print( stringPlayers[comp_number], '\n')
        print( gameAction, '\n' )
        print( stringOutcomes[gameOutcome] )
        print( '\n' )    
    return gameOutcome    

RPSLS Simulations:

## 
## 
## Player chooses: 
## 
##  _____                  _    
## /  ___|                | |   
## \ `--. _ __   ___   ___| | __
##  `--. \ '_ \ / _ \ / __| |/ /
## /\__/ / |_) | (_) | (__|   < 
## \____/| .__/ \___/ \___|_|\_\
##       | |                    
##       |_|                    
##       
## Computer chooses: 
## 
##  _____                  _    
## /  ___|                | |   
## \ `--. _ __   ___   ___| | __
##  `--. \ '_ \ / _ \ / __| |/ /
## /\__/ / |_) | (_) | (__|   < 
## \____/| .__/ \___/ \___|_|\_\
##       | |                    
##       |_|                    
##        
## 
##  ==  
## 
## 
##  _____ ________  _________ _   _ _____ ___________ 
## /  __ \  _  |  \/  || ___ \ | | |_   _|  ___| ___ \
## | /  \/ | | | .  . || |_/ / | | | | | | |__ | |_/ /
## | |   | | | | |\/| ||  __/| | | | | | |  __||    / 
## | \__/\ \_/ / |  | || |   | |_| | | | | |___| |\ \ 
##  \____/\___/\_|  |_/\_|    \___/  \_/ \____/\_| \_|
##                                                    
##                                                    
##  _    _ _____ _   _  _____   _ _ _                 
## | |  | |_   _| \ | |/  ___| | | | |                
## | |  | | | | |  \| |\ `--.  | | | |                
## | |/\| | | | | . ` | `--. \ | | | |                
## \  /\  /_| |_| |\  |/\__/ / |_|_|_|                
##  \/  \/ \___/\_| \_/\____/  (_|_|_)                
##                                                    
##                                                    
## 
## 
## 0


2.

## 
## 
## Player chooses: 
## 
## ______           _     
## | ___ \         | |    
## | |_/ /___   ___| | __ 
## |    // _ \ / __| |/ / 
## | |\ \ (_) | (__|   <  
## \_| \_\___/ \___|_|\_\   
## Computer chooses: 
## 
## ______                     
## | ___ \                    
## | |_/ /_ _ _ __   ___ _ __ 
## |  __/ _` | '_ \ / _ \ '__|
## | | | (_| | |_) |  __/ |   
## \_|  \__,_| .__/ \___|_|   
##           | |              
##           |_|              
##            
## 
## paper covers rock therefore:  
## 
## 
##          _   _          _                                   
##         | | (_)        | |                                  
##   __ _  | |_ _  ___  __| |   __ _  __ _ _ __ ___   ___      
##  / _` | | __| |/ _ \/ _` |  / _` |/ _` | '_ ` _ \ / _ \     
## | (_| | | |_| |  __/ (_| | | (_| | (_| | | | | | |  __/     
##  \__,_|  \__|_|\___|\__,_|  \__, |\__,_|_| |_| |_|\___|     
##                              __/ |                          
##                             |___/                           
##   ___                     _                _            __  
##  / / |                   | |              (_)           \ \ 
## | || |__   _____      __ | |__   ___  _ __ _ _ __   __ _ | |
## | || '_ \ / _ \ \ /\ / / | '_ \ / _ \| '__| | '_ \ / _` || |
## | || | | | (_) \ V  V /  | |_) | (_) | |  | | | | | (_| || |
## | ||_| |_|\___/ \_/\_/   |_.__/ \___/|_|  |_|_| |_|\__, || |
##  \_\                                                __/ /_/ 
##                                                    |___/    
## 
## 
## -1


3.

## -1

1000 RPSLS Simulations


print a summary of the simulation outcome

## There were  24.8 % tied games 
## the 'player' won  50.3 % of games
## the computer won  24.9 % of games


Next we will run the same simulation however, for the previous run, the the ‘player’ always selected ‘Lizard’. This simulation will functionalize the for loop and have the player now randomly chosing an option as well.

## There were  24.5 % tied games 
## the 'player' won  37.5 % of games
## the computer won  38.0 % of games


Conclusions

    The theoretical number of ties predicted for this game is \(\frac{1}{n}\) where n is the number of options available to the player. RPSLS has 5 possible outcomes, so the predicted number of ties is 20%. The last simulation approximates 20% \(\pm\) a few percents (variable across simulations). Noteably, the percent of games won by the ‘player’ and the computer are much more equivalent in the second simulation compared to the first simulation where the ‘player’ selection was fixed to ‘Lizard’.

Future directions

  1. Move to a GUI
  2. incorporate pictures
  3. Is there a war to display python code inline in R Markdown? Hmmmmm