Computing · Teaching

Thinking Task #2: Mastermind – you need to be!

I thought I’d go with my own recommendation from my first post, and write a piece of code for my A2 students who are currently revising for their programming AS module in January to analyse. A Lower 6th student had suggested that a task could be to implement the “Mastermind” game which I had played as a child. I think this is a fairly standard programming task, but it did actually cause me a little bit of aggro!

Required knowledge: Functions, Selection, Iteration, Lists (arrays), String functions e.g. upper(), Random

The basic premise of the game is that the problem setter picks a combination of four coloured pegs (usually from a choice of white, black, red, yellow, green, blue) and hides them. The guesser then has to guess the exact sequence. They give a series of guesses, to which the setter replies with how many are the right colour in the right place (denoted by a black peg), and how many are the right colour in the wrong place (a white peg). By a process of deduction the guesser can eventually figure out what the combination is.

So far, so easy. By FAR the hardest part was figuring out how to return the correct result for the white peg. Black peg was a piece of cake, but I kept being caught out with multiple counting of correct colours in the wrong places, and tying myself in knots trying to debug things. I *think* this solution works, and even if it does I am sure there is probably a way more elegant solution that someone who is more mathematical than me could come up with.

Some things students could do with this code

(there are of course many more!)

1. Add comments to this code to explain what is happening at each stage of the program. There is no need to comment every line.
2. Why is it necessary to use the line tempGuess = list(guess) instead of tempGuess = guess?
3. Why do we need to make a copy of the lists anyway?
4. Why do we keep a track of which letters we have checked using the list lettersChecked?
5. What is the purpose of validation and why is it important?
6. Which naming convention has been used in this code? Why are naming conventions important?
7. Why do we bother to initialise our variables?
8. At the moment, what happens when the player exceeds the number of guesses allowed? Can you add some code to let the user know when they have lost?
9. Draw up a test plan for 5 black box tests on this code, each test being from a different group of test data.
10. Supposing you wished to add the colour Blue as a valid colour, could you alter the code to include this whilst keeping input simple for the user?
11. The line while True: near the beginning of the validateInput() function is an infinite loop. Why doesn’t this result in the program running forever?

I’m not going to ask them to do this, but this code would be an excellent introduction to programs with a GUI – you could write the algorithm with a text based output and then once they have learnt how to display things on a GUI, ask them to revisit it and make it graphical.

Another obvious extension that I think is rather more university level, although there appear to be various algorithms documented, would be to add an option for the user to be the setter and the computer to be the solver. However, a useful discussion about efficiency could come about if you asked students to consider what the computer’s guessing strategy should be, and then compared their answers to the algorithms.

Of course, if you are not using Python as your language of choice, you could easily translate this code to most other languages.

If you have any other suggestions of possible questions or improvements I could set for my upper 6th, do share them.

Here is the (deliberately uncommented) Python code:

import random

def validateInput():
    inputGuess = raw_input("Enter your guess as 4 letters e.g. XXXX:")

    while True:
        if len(inputGuess) != 4:
           inputGuess = raw_input("Enter your guess as 4 letters e.g. XXXX:")
        else:
            wordList = list( inputGuess.upper() )

            invalidLetters = False
            for letter in wordList:
                if letter not in ['R','G','Y','B','W']:
                    invalidLetters = True 

            if invalidLetters == True:
                print "Possible colours are R G Y B W"
                inputGuess = raw_input("Enter your guess as 4 letters e.g. XXXX:") 

            else:
                return wordList

guessesRemaining = 12
code = []
guess = []
correctPosition = 0
correctColour = 0

for i in range(4):
    code.append(random.choice(['R','G','Y','B','W']))

print "Guess my sequence of four colours, in the correct order."
print "\nPossible colours are R G Y B W"

while guessesRemaining > 0:

    correctPosition = 0
    correctColour = 0
    lettersChecked = []

    guess = validateInput()
    guessesRemaining -= 1 # Deduct one guess

    tempGuess = list(guess)
    tempCode = list(code)

    for i in range(4):
        if guess[i] == code[i]:
            correctPosition += 1
            tempGuess[i] = "X"
            tempCode[i] = "X"

    for j in range(4):

        if tempGuess[j] in tempCode and tempGuess[j] != "X" and tempGuess[j] not in lettersChecked:

            if tempCode.count(guess[j]) > tempGuess.count(tempGuess[j]):
                correctColour += tempGuess.count(tempGuess[j])

            else:
                correctColour += tempCode.count(tempGuess[j])

            lettersChecked.append(tempGuess[j])

    if correctPosition > 0:
        print "You had",correctPosition,"correct colours in the correct place"
    if correctColour > 0:
        print "You had",correctColour,"correct colours in the wrong place"

    if correctPosition == 0 and correctColour == 0:
        print "No correct colours"

    if correctPosition == 4:
        print "You won in",12-guessesRemaining,"guesses, congratulations!"
        guessesRemaining = 0

print "Thanks for playing"
Advertisements

2 thoughts on “Thinking Task #2: Mastermind – you need to be!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s