Create Mastermind Game in Python – Code a code-breaking game

Mastermind Game Featured Image

Mastermind is a two-player code-breaking game, in which one player hides a code consisting of colors, while the other player has to guess it using clues given by the former player for each turn.

In this tutorial, we will be creating our own Mastermind Game using Python Language. In our version of Mastermind, the computer will randomly select a secret code and the user tries to guess it, based on the deterministic clues given by the computer.


Mastermind Game in Python – Demo

Mastermind Game Demo

Without any further ado, let us get into the design part of the game.

Mastermind Game Design

The original mastermind board is shown below.

Mastermind
Mastermind Board

The shielded end of the board hides the secret code, whereas the entirety of the board is based on guesses made by the code-breaker. The game ends as soon as the user identifies the hidden code.

The right side of the board in the figure contains a series of white and red pegs, which are used to denote the clues related to each try.

  • Red – One of the chosen colors is in the right position as in the secret code
  • White – One of the chosen colors is present in the code, but the position is incorrect.

The implementation of the board in the terminal looks like:

Mastermind Game Design
Game Design on Terminal

The top end of the board hides the secret code and is revealed when the player is out of chances or breaks the code. Until that moment, “UNK” for “unknown” is shown.

Each section of the board denotes a turn made by the player. The game supports six colors, RED, GREEN, YELLOW, BLUE, BLACK, ORANGE. The leftmost panel denotes the clues based on each turn. ‘W’ for WHITE and ‘R’ for RED are used with the original meaning behind them

In the figure displayed above, three of the four colors selected by the user are correct, but neither of them is the correct position according to the secret code, hence three ‘W’s in the clues.

# Function to print the mastermind board
def print_mastermind_board(passcode, guess_codes, guess_flags):

	print("-----------------------------------------")
	print("\t      MASTERMIND")
	print("-----------------------------------------")

	print("    |", end="")
	for x in passcode:
		print("\t" + x[:3], end="")
	print()	

	for i in reversed(range(len(guess_codes))):
		print("-----------------------------------------")
		print(guess_flags[i][0], guess_flags[i][1], "|")
		

		print(guess_flags[i][2], guess_flags[i][3], end=" |")
		for x in guess_codes[i]:
			print("\t" + x[:3], end="")

		print()	
	print("-----------------------------------------")

The above code snippet is responsible for displaying the mastermind board on the Terminal.


Data Structures – Game variables

For the convenient development of the game logic, we need a few data structures.

  • colors – A list of colors involved in the game
  • colors_map – A mapping between numbers and the colors
  • passcode – The secret code
  • show_passcode – The secret code to be shown to the user, a list of Unknowns
  • guess_code – A list of lists of guesses made by the player
  • guess_flags – A list of lists of clues given to the player
# The Main function
if __name__ == '__main__':

	# List of colors
	colors = ["RED", "GREEN", "YELLOW", "BLUE", "BLACK", "ORANGE"]

	# Mapping of colors to numbers	
	colors_map = {1:"RED", 2:"GREEN", 3:"YELLOW", 4:"BLUE", 5:"BLACK", 6:"ORANGE"}

	# Randomly selecting a passcode
	random.shuffle(colors)
	passcode = colors[:4]
	
	# Number of chances for the player
	chances = 8

	# The passcode to be shown to the user
	show_passcode = ['UNK', 'UNK', 'UNK', 'UNK']

	# The codes guessed by the player each turn
	guess_codes = [['-', '-', '-', '-'] for x in range(chances)]

	# The clues provided to the player each turn
	guess_flags = [['-', '-', '-', '-'] for x in range(chances)]

Each of these data structures come handy when dealing with game logic for our implementation of Mastermind game.


The Game loop

One of the most crucial parts of game development is the game loop, which is responsible for the proper functioning of the player moves and updates to game variables.

# The current turn
turn = 0

# The GAME LOOP
while turn < chances:

The Game Loop is dependent on the number of chances and the current turn. It is supposed to stop the game whenever the player’s chances are exhausted.


The Game Menu

The Game Menu is as a simple aspect of the game, which helps the programmer to interact with the player with instructions or rules.

Our Game Menu looks like this:

Mastermind Game Menu
Game Menu
# The GAME MENU
print("-----------------------------------------")
print("\t\tMenu")
print("-----------------------------------------")
print("Enter code using numbers.")
print("1 - RED, 2 - GREEN, 3 - YELLOW, 4 - BLUE, 5 - BLACK, 6 - ORANGE")
print("Example: RED YELLOW ORANGE BLACK ---> 1 3 6 5")
print("-----------------------------------------")
print_mastermind_board(show_passcode, guess_codes, guess_flags)

The game menu must be plain and apt.


Handling the Player Input

Handling player input involves three basic steps: Accepting the player input, applying some sanity checks on it, and if everything is in order, storing it into our data structures.

Accepting the Player Input

As mentioned in the game menu, the player needs to enter four numbers, each corresponding to a specific color, separated by spaces.

Our job is to parse this player input into a list of integers for retrieving the proper colors.

# Accepting the player input 
try:	
	code = list(map(int, input("Enter your choice = ").split()))
except ValueError:
	clear()
	print("\tWrong choice!! Try again!!")
	continue

Note: The clear() function is responsible for keeping the terminal clean, by flushing out the previous output. It requires Python’s os library.

Check the complete code below for function declaration of clear().


Applying sanity checks

Next up is doing some sanity checks on the player input.

# Check if the number of colors nunbers are 4
if len(code) != 4:
	clear()
	print("\tWrong choice!! Try again!!")
	continue

# Check if each number entered corresponds to a number
flag = 0
for x in code:
	if x > 6 or x < 1:
		flag = 1

if flag == 1:			
	clear()
	print("\tWrong choice!! Try again!!")
	continue	

Storing the player moves

After we know the player has made a valid move, we can store it in the game containers.

# Storing the player moves
for i in range(4):
	guess_codes[turn][i] = colors_map[code[i]]	

Set up the clues for each move

There are two set of flags to be assigned, ‘R’ if a color is in the right position as in the secret code, and ‘W’ if the color is right but in the wrong position.

# Process to apply clues according to the player input	
dummy_passcode = [x for x in passcode]	

pos = 0

# Loop to set up clues for the player move
for x in code:
	if colors_map[x] in dummy_passcode:
		if code.index(x) == passcode.index(colors_map[x]):
			guess_flags[turn][pos] = 'R'
		else:
			guess_flags[turn][pos] = 'W'
		pos += 1
		dummy_passcode.remove(colors_map[x])

random.shuffle(guess_flags[turn])				

One small thing to remember is rearranging the flags, since it may give hints related to the positions of colors.


Check for the win condition

All we have to do is check the latest input with the hidden code.

# Check for win condition
if guess_codes[turn] == passcode:
	clear()
	print_mastermind_board(passcode, guess_codes, guess_flags)
	print("Congratulations!! YOU WIN!!!!")
	break

As soon as the player enters the correct code, we display a win message and finish the game.


Update the turn number

One small yet very important task is to update the turn number after each successful player move.

# Update turn	
turn += 1			
clear()

The last but not the least is handling the loss condition.


Check for the loss condition

When the player has exhausted the number of chances, the player loses. We need to display appropriate message when this happens.

# Check for loss condiiton	
if turn == chances:
	clear()
	print_mastermind_board(passcode, guess_codes, guess_flags)
	print("YOU LOSE!!! Better luck next time!!!")	

This concludes the explanation for creating mastermind using Python language.


The Complete Code

import random
import os

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

# Function to print the mastermind board
def print_mastermind_board(passcode, guess_codes, guess_flags):


	print("-----------------------------------------")
	print("\t      MASTERMIND")
	print("-----------------------------------------")

	print("    |", end="")
	for x in passcode:
		print("\t" + x[:3], end="")
	print()	

	for i in reversed(range(len(guess_codes))):
		print("-----------------------------------------")
		print(guess_flags[i][0], guess_flags[i][1], "|")
		

		print(guess_flags[i][2], guess_flags[i][3], end=" |")
		for x in guess_codes[i]:
			print("\t" + x[:3], end="")

		print()	
	print("-----------------------------------------")

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

	# List of colors
	colors = ["RED", "GREEN", "YELLOW", "BLUE", "BLACK", "ORANGE"]

	# Mapping of colors to numbers	
	colors_map = {1:"RED", 2:"GREEN", 3:"YELLOW", 4:"BLUE", 5:"BLACK", 6:"ORANGE"}

	# Randomly selecting a passcode
	random.shuffle(colors)
	passcode = colors[:4]
	
	# Number of chances for the player
	chances = 8

	# The passcode to be shown to the user
	show_passcode = ['UNK', 'UNK', 'UNK', 'UNK']

	# The codes guessed by the player each turn
	guess_codes = [['-', '-', '-', '-'] for x in range(chances)]

	# The clues provided to the player each turn
	guess_flags = [['-', '-', '-', '-'] for x in range(chances)]
	
	clear()

	# The current turn
	turn = 0

	# The GAME LOOP
	while turn < chances:
		
		print("-----------------------------------------")
		print("\t\tMenu")
		print("-----------------------------------------")
		print("Enter code using numbers.")
		print("1 - RED, 2 - GREEN, 3 - YELLOW, 4 - BLUE, 5 - BLACK, 6 - ORANGE")
		print("Example: RED YELLOW ORANGE BLACK ---> 1 3 6 5")
		print("-----------------------------------------")
		print_mastermind_board(show_passcode, guess_codes, guess_flags)

		# Accepting the player input 
		try:	
			code = list(map(int, input("Enter your choice = ").split()))
		except ValueError:
			clear()
			print("\tWrong choice!! Try again!!")
			continue	

		# Check if the number of colors nunbers are 4
		if len(code) != 4:
			clear()
			print("\tWrong choice!! Try again!!")
			continue

		# Check if each number entered corresponds to a number
		flag = 0
		for x in code:
			if x > 6 or x < 1:
				flag = 1

		if flag == 1:			
			clear()
			print("\tWrong choice!! Try again!!")
			continue	

		# Storing the player input
		for i in range(4):
			guess_codes[turn][i] = colors_map[code[i]]	

		# Process to apply clues according to the player input	
		dummy_passcode = [x for x in passcode]	

		pos = 0

		# Loop to set up clues for the player move
		for x in code:
			if colors_map[x] in dummy_passcode:
				if code.index(x) == passcode.index(colors_map[x]):
					guess_flags[turn][pos] = 'R'
				else:
					guess_flags[turn][pos] = 'W'
				pos += 1
				dummy_passcode.remove(colors_map[x])

		random.shuffle(guess_flags[turn])				


		# Check for win condition
		if guess_codes[turn] == passcode:
			clear()
			print_mastermind_board(passcode, guess_codes, guess_flags)
			print("Congratulations!! YOU WIN!!!!")
			break

		# Update turn	
		turn += 1			
		clear()

# Check for loss condiiton	
if turn == chances:
	clear()
	print_mastermind_board(passcode, guess_codes, guess_flags)
	print("YOU LOSE!!! Better luck next time!!!")	

Conclusion

The task of creating our own games may seem daunting at first for any novice Python programmer. We hope this article simplified certain Python concepts and made the task look achievable to the reader.

Feel free to comment below for any suggestions or queries. Thank you for reading.