Mastermind (a How-to in Python)

Nic Basilio
6 min readSep 24, 2020

--

A mastermind is a person of outstanding intellect, but you don’t need to be a mastermind to follow this tutorial on how to build a simple game from scratch. Let’s begin!

*Disclaimer: The tutorial assumes basic knowledge in Python3.

*All constants used in the code are linked here

Mastermind board game
Mastermind board game

The board game consists of two players: a code maker (may be a bot) and a code breaker. We can code the game without using classes, but since Python is an object-oriented language, we can take advantage of this feature.

Knowing that the game involves two players, we create two classes: CodeMaker and CodeBreaker. I decided to create two separate files for my two classes.

CodeBreaker

In codeBreaker.py, we write all methods (functions associated with a class) for the CodeBreakerclass. To help us begin coding, we have to think about what we want the code breaker to be able to do. Based on the game description, the code breaker has one role: make guesses.

We initiate our class and define the __init__ method that will create an instance of CodeBreaker:

In the above example, the keyword self represents the instance of a class.

Our next step is to define a method that lets the CodeBreaker make guesses …valid guesses. To make this happen we code our method makeGuess that will keep asking our code breaker for their guess until they input a valid one. Any helper functions will be made into protected methods.

We see in the above example that we call a helper function _validateUserInput that validates the guess and another, _printUserFriendlyErrorMessage that prints the error message if the guess is invalid. The only type of valid guess is a string of 4 colors separated by spaces. If the user enters an invalid guess, they are prompted to enter a new one. The end result is a guess of 4 colors in a list.

The helper functions are defined as follows:

_validateUserInput and _printUserFriendlyErrorMessage methods

We can see that _validateUserInput checks if there are 4 items in the player’s guess and if they are all valid colors. _printUserFriendlyErrorMessage prints an error message based on the error code it receives from _validateUserInput.

CodeMaker

In the file codeMaker.py, we will be writing all methods (functions relating to a class) for the CodeMaker class. To help us decide what methods should go in this class, we brainstorm what it is that CodeMaker does:

  1. if the code breaker decides to play with a bot, CodeMaker will provide a randomly-generated code that the code breaker will try to guess
  2. if the code breaker is playing with another person, the second player will type in their own code
  3. CodeMaker will validate the code that the second player enters
  4. CodeMaker checks if the code breaker guessed the code correctly and if not, provide feedback to the code breaker

We start by defining the class:

In the above example, the keyword self represents the instance of a class.

We then define createRandomCode that returns a randomly-generated code by using the random module. Don’t forget to import random! In this example, we use choice to create a list consisting of 4 random colors that are picked from our PEG_COLORS list as shown below:

We also define createCodethat returns a validated code, which is a list of 4 colors. This is the same idea of validation as the method in the CodeBreakerclass, but this time for user-generated code. Don’t forget to write your helper functions (_validateUserInputand _printUserFriendlyErrorMessage) in this class as well.

Now we get to talk about my favorite part: the feedback algorithm. The feedback colors are red and white. Red means right color and position, while white means right color wrong position. In this algorithm, we check for all ‘reds’ then once we find all ‘reds,’ we look for ‘whites.’

For example, the code maker gives us a code of [blue, orange, black, purple]. The code breaker guesses the code to be [orange, orange, purple, green].

code: [blue, orange, black, purple]

guess: [blue, orange, purple, green]

We expect provideFeedback to return a feedback of [red, red, white]. Here’s what happens under the hood:

  • We look for matching colors on the same index of both the code and guess list: code[i] == guess[i]
  • If the colors match at any given index, we change these items of the lists to ‘ ’ and ‘-’ in the code list and guess list, respectively. We do not want to utilize these colors when we check for white feedback, and that’s the reason for ‘removing’ them from the list. The reason we use ‘ ’ and ‘-’ and not ‘-’ and ‘-’ or ‘ ’ and ‘ ’, is to also avoid giving an incorrect number of white feedback. Our lists look like this now:

code: [ , , black, purple]

guess: [ -, -, purple, green]

  • We look for any colors in guess that appears in code, but is in the wrong position. Do you see why we have to change the colors to ‘ ’ and ‘-’ now? If we change the items in both lists to be of the same character, we will get a false white feedback because code[1] and guess[0] will match and code[0]and guess[1] will also match as shown below:

code: [ -, - , black, purple]

guess: [ -, -, purple, green]

  • As you can see in the above examples, we expect to get a white feedback for purple being the wrong position. We do this by checking if a color at any given index in guess appears in code: guess[i] in code. Once we see a match, we find the index where that color appears in code. The position is returned and we ‘remove’ the color from the lists again: guess[2]=’-’and code[3]==' ‘. We end up with the following lists and a feedback list is returned:

code: [ , , black, ]

guess: [ -, -, -, green]

Here is how I implemented the provideFeedback method in my code:

Another method in the same class is _checkWinnerStatus. This method simply checks if the feedback list consists of all ‘reds.’ If so, a winner code is returned. If not, the game prints the feedback list for the player.

Main.py

Main is the point of execution of the entire game. The steps to code it are as follows:

  1. Import all necessary modules
  2. Print a welcome message
  3. Ask for whether the player wants to play with a bot
  4. Generate or enter code (if code is manually entered, clear the console)
  5. Let player guess and print feedback for the guess
  6. Reduce the number of guesses by 1 for any valid guess
clear function to clear the console

The Gameflow

The above example is for a code breaker who chooses to play with another player and not a bot. Once Player 2 enters the code, the console is cleared to hide the code from the code breaker. This is what follows:

Once the player wins, a winning message is displayed:

This project was solely coded by me for Hack Day for the SF campus at Holberton school.

Find the code and instructions to play on my GitHub repo here. Happy coding!

--

--

Nic Basilio
Nic Basilio

Written by Nic Basilio

0 Followers

Holberton School — Software Engineering student

No responses yet