Rock Paper Scissors in Python – A Complete Step-By-Step Guide

Rock Paper Scissors Featured Image

In this article, we will go through the steps for creating our own game of Rock Paper Scissors in Python Language.

About Rock Paper Scissors

The traditional Rock-Paper-Scissors is a two-player game, in which each player simultaneously chooses, either rock, paper or scissors, given that, rock crushes scissors, scissors cuts paper, and paper covers rock. Based on the rules, the winner is decided.

If you are familiar with the popular TV Series, The Big Bang Theory, you might know another version of the game called Rock-Paper-Scissors-Lizard-Spock. The below infographic might help you to understand.

Rpsls
Rock-Paper-Scissors-Lizard-Spock

The direction of the arrow determines the winner. The arrows going out of an entity means, the supremacy of that entity in that particular match-up.


Gameplay Demo


Creating Rock Paper Scissors in Python

The game we will create today supports both versions of Rock-Paper-Scissors. Not everyone would be keen on playing the new version of the game, therefore we need a game menu for separating the fan base. The menu looks like this.

Game Menu
Game Menu

Creating the Data Structures

There are two specific data structures required for the complete functioning of the game.

# The mapping between moves and numbers
game_map = {0:"rock", 1:"paper", 2:"scissors", 3:"lizard", 4:"Spock"}

# Win-lose matrix for traditional game
rps_table = [[-1, 1, 0], [1, -1, 2], [0, 2, -1]]

# Win-lose matrix for new version of the game
rpsls_table = [[-1, 1, 0, 0, 4],[1, -1, 2, 3, 1], [0, 2, -1, 2, 4], [0, 3, 2, -1, 3], [4, 1, 4, 3, -1]]

Mapping Game Moves

We need a certain type of mapping between the possible moves and numbers, in order to determine the winner and the loser. We use a python dictionary for this purpose.

Win-Lose Matrices

The simplest way to check for the winner of rock paper scissors in Python is by referring to the cell corresponding to each player’s input. Below is the matrix for the traditional game:

Rps Table
Win-Lose Matrix

The non-negative values of the matrix denote the winner of the corresponding inputs. Let us take an example, to completely comprehend the matrix.

Suppose, in a certain game, player 1 chooses Scissors (index = 2) and player 2 chooses Paper (index = 1). The cells (2, 1) and (1, 2) in the matrix, denote a match between Scissors and Paper. These cells contain the index of Scissors because Scissors cut Paper.

The cells containing '-1' denote a tie game.

Below is the matrix for new version:

Rpsls Table
Win-Lose Matrix

The above-explained data structures sum up the complete game-logic required to create our game of Rock-Paper-Scissors. Two things that remain are managing player input and computer move.


Building the Game Loop

One of the most crucial parts of the rock paper scissors in Python is the Game Loop. In the context of this game, the game loop is responsible for maintaining a string of matches between players.

# The GAME LOOP
while True:

	# The Game Menu
	print()
	print("Let's Play!!!")
	print("Which version of Rock-Paper-Scissors?")
	print("Enter 1 to play Rock-Paper-Scissors")
	print("Enter 2 to play Rock-Paper-Scissors-Lizard-Spock")
	print("Enter 3 to quit")
	print()

	# Try block to handle the player choice 
	try:
		choice = int(input("Enter your choice = "))
	except ValueError:
		clear()
		print("Wrong Choice")	
		continue

	# Play the traditional version of the game
	if choice == 1:
		rps()

	# Play the new version of the game
	elif choice == 2:
		rpsls()

	# Quit the GAME LOOP 	
	elif choice == 3:
		break

	# Other wrong input
	else:
		clear()
		print("Wrong choice. Read instructions carefully.")

The 'rps()' and 'rpsls()' functions have an inner game loop to handle a series of games of their respective versions.

The ‘clear()' function is responsible for clearing the terminal, to prevent crowding of output.


Game Instructions for Rock Paper Scissors in Python

Before expecting a player to make a move, it is the duty of the programmer to provide a set of instructions to the gamer. We need to create two separate functions for giving instructions for both kinds of games.

# Set of instructions for Rock-Paper-Scissors
def rps_instructions():

	print()
	print("Instructions for Rock-Paper-Scissors : ")
	print()
	print("Rock crushes Scissors")
	print("Scissors cuts Paper")
	print("Paper covers Rock")
	print()

# Set of instructions for Rock-Paper-Scissors-Lizard-Spock
def rpsls_instructions():

	print()
	print("Instructions for Rock-Paper-Scissors-Lizard-Spock : ")
	print()
	print("Scissors cuts Paper")
	print("Paper covers Rock")
	print("Rock crushes Lizard")
	print("Lizard poisons Spock")
	print("Spock smashes Scissors")
	print("Scissors decapitates Lizard")
	print("Lizard eats Paper")
	print("Paper disproves Spock")
	print("Spock vaporizes Rock")
	print("Rock crushes Scissors")
	print()

After displaying the instructions, we ask for player input.


Handling player input

Since our game supports Player vs. Computer scenario, we have to take care of a single move each 0game of rock paper scissors in Python

Input Menu

We need to provide the player with a sense of control of the game. We can do so by providing the options of, “asking for help”, “possible moves” and “quitting the game”. The following input menu takes care of this:

Input Menu
Input Menu

Player’s move

The main focus of handling the player input is converting the string input to the numeric mapping. For the traditional game of rock paper scissors in Python, we accept the following input moves.

# Player Input
inp = input("Enter your move : ")

if inp.lower() == "help":
	clear()
	rps_instructions()
	continue
elif inp.lower() == "exit":
	clear()
	break	
elif inp.lower() == "rock":
	player_move = 0
elif inp.lower() == "paper":
	player_move = 1		
elif inp.lower() == "scissors":
	player_move = 2
else:
	clear()
	print("Wrong Input!!")
	rps_instructions()	
	continue

We can perform the checks conditionally using the if-elif-else statement.


Manage computer moves

To manage an unbiased computer move, we need to take the help of Python’s 'random' library. We select a random move from the possible options.

# Get the computer move randomly
comp_move = random.randint(0, 2)

# Print the computer move
print("Computer chooses ", game_map[comp_move].upper())

Using the 'randint()' function of the random library, we select a random move for the computer.


Decide and declare the winner

Using the win-lose matrix, we can easily select the winner.

# Find the winner of the match
winner = rps_table[player_move][comp_move]

# Declare the winner 
if winner == player_move:
	print(name, "WINS!!!")
elif winner == comp_move:
	print("COMPUTER WINS!!!")
else:
	print("TIE GAME")
print()
time.sleep(2)
clear()

We use the 'sleep()' function to pause the execution of the Python script. In the above example, the script waits for 2 seconds.

This sums up with the explanation of the Python script that runs the game of Rock-Paper-Scissors.


Complete Code for Rock Paper Scissors in Python

Below is the complete code for our game of rock paper scissors in Python.

import random
import os
import time

def clear():
	os.system("clear")

# Set of instructions for Rock-Paper-Scissors
def rps_instructions():

	print()
	print("Instructions for Rock-Paper-Scissors : ")
	print()
	print("Rock crushes Scissors")
	print("Scissors cuts Paper")
	print("Paper covers Rock")
	print()

# Set of instructions for Rock-Paper-Scissors-Lizard-Spock
def rpsls_instructions():

	print()
	print("Instructions for Rock-Paper-Scissors-Lizard-Spock : ")
	print()
	print("Scissors cuts Paper")
	print("Paper covers Rock")
	print("Rock crushes Lizard")
	print("Lizard poisons Spock")
	print("Spock smashes Scissors")
	print("Scissors decapitates Lizard")
	print("Lizard eats Paper")
	print("Paper disproves Spock")
	print("Spock vaporizes Rock")
	print("Rock crushes Scissors")
	print()

def rps():
	
	global rps_table
	global game_map
	global name

	# Game Loop for each game of Rock-Paper-Scissors
	while True:

		print("--------------------------------------")
		print("\t\tMenu")
		print("--------------------------------------")
		print("Enter \"help\" for instructions")
		print("Enter \"Rock\",\"Paper\",\"Scissors\" to play")
		print("Enter \"exit\" to quit")
		print("--------------------------------------")

		print()

		# Player Input
		inp = input("Enter your move : ")

		if inp.lower() == "help":
			clear()
			rps_instructions()
			continue
		elif inp.lower() == "exit":
			clear()
			break	
		elif inp.lower() == "rock":
			player_move = 0
		elif inp.lower() == "paper":
			player_move = 1		
		elif inp.lower() == "scissors":
			player_move = 2
		else:
			clear()
			print("Wrong Input!!")
			rps_instructions()	
			continue

		print("Computer making a move....")

		print()
		time.sleep(2)

		# Get the computer move randomly
		comp_move = random.randint(0, 2)

		# Print the computer move
		print("Computer chooses ", game_map[comp_move].upper())

		# Find the winner of the match
		winner = rps_table[player_move][comp_move]

		# Declare the winner 
		if winner == player_move:
			print(name, "WINS!!!")
		elif winner == comp_move:
			print("COMPUTER WINS!!!")
		else:
			print("TIE GAME")

		print()
		time.sleep(2)
		clear()

def rpsls():
	
	global rpsls_table
	global game_map
	global name

	# Game Loop for each game of Rock-Paper-Scissors-Lizard-Spock
	while True:
		print("--------------------------------------")
		print("\t\tMenu")
		print("--------------------------------------")
		print("Enter \"help\" for instructions")
		print("Enter \"Rock\",\"Paper\",\"Scissors\",\"Lizard\",\"Spock\" to play")
		print("Enter \"exit\" to quit")
		print("--------------------------------------")
		
		print()

		# Player Input
		inp = input("Enter your move : ")

		if inp.lower() == "help":
			clear()
			rpsls_instructions()
			continue
		elif inp.lower() == "exit":
			clear()
			break	
		elif inp.lower() == "rock":
			player_move = 0
		elif inp.lower() == "paper":
			player_move = 1		
		elif inp.lower() == "scissors":
			player_move = 2
		elif inp.lower() == "lizard":
			player_move = 3
		elif inp.lower() == "spock":
			player_move = 4	
		else:
			clear()
			print("Wrong Input!!")
			rps_instructions()	
			continue


		print("Computer making a move....")

		comp_move = random.randint(0, 4)
		print()
		time.sleep(2)

		print("Computer chooses ", game_map[comp_move].upper())

		winner = rpsls_table[player_move][comp_move]
		print()
		if winner == player_move:
			print(name, "WINS!!!")
		elif winner == comp_move:
			print("COMPUTER WINS!!!")
		else:
			print("TIE GAME")		
		print()
		time.sleep(2)
		clear()

# The main function
if __name__ == '__main__':

	# The mapping between moves and numbers
	game_map = {0:"rock", 1:"paper", 2:"scissors", 3:"lizard", 4:"Spock"}

	# Win-lose matrix for traditional game
	rps_table = [[-1, 1, 0], [1, -1, 2], [0, 2, -1]]

	# Win-lose matrix for new version of the game
	rpsls_table = [[-1, 1, 0, 0, 4],[1, -1, 2, 3, 1], [0, 2, -1, 2, 4], [0, 3, 2, -1, 3], [4, 1, 4, 3, -1]]

	
	name = input("Enter your name: ")

	# The GAME LOOP
	while True:

		# The Game Menu
		print()
		print("Let's Play!!!")
		print("Which version of Rock-Paper-Scissors?")
		print("Enter 1 to play Rock-Paper-Scissors")
		print("Enter 2 to play Rock-Paper-Scissors-Lizard-Spock")
		print("Enter 3 to quit")
		print()

		# Try block to handle the player choice 
		try:
			choice = int(input("Enter your choice = "))
		except ValueError:
			clear()
			print("Wrong Choice")	
			continue

		# Play the traditional version of the game
		if choice == 1:
			rps()

		# Play the new version of the game
		elif choice == 2:
			rpsls()

		# Quit the GAME LOOP 	
		elif choice == 3:
			break

		# Other wrong input
		else:
			clear()
			print("Wrong choice. Read instructions carefully.")

							

Conclusion

Creating a game is not a difficult process if the programmer knows the fundamentals of game-logic and design. We hope this article made the reader aware of the above principles of developing a simple terminal-based game. The working code is also present at my Github account.

Thank you for reading. Feel free to ping us in the comments section for any queries.