MasterMind – A Game of Logic

Disclaimer:

I am not a VBA expert and some portions of this code may not follow the standard coding practices. It is what it is.

Assumptions:

I assume you have some experience with Excel VBA and its infrastructure (how to view project, general knowledge of the coding syntax etc…)

Other Notes:

I don’t plan to explain everything about this game (as it would just be too long). I hope to provide a sequence of events in order to help you replicate and improve on it further for your interest and knowledge.

The entire game is free for download from this link. The gameplay can be viewed from this link. Please let me know your thoughts and comments on this article below.

Before I begin to describe and explain the sequence of events on this project, I should explain that there are 3 difficulties in this game which you can choose from, hence 3 sets of codes. Each difficulty can be accessed in the workbook sheets.

 


The difficulty levels are as follows;

  • Easy Mode (5 Colours)
  • Normal Mode (8 Colours)
  • Difficult Mode (8 Colours(2)) – Colours may get repeated

The VBA coding behind the easy & normal mode are fairly similar to each other (or pretty much the same tbf). The only difference lies in the number of colours being displayed.

The VBA coding behind the difficult mode however is different. As this mode incorporates repeated colours, the VBA code behind this section needed to be changed significantly.  

For the purpose of this article I will only concern myself with the Normal Mode & Difficult Mode.

As in all my posts; I will first breakdown the process into their individual components and then describe each section as best as I can.

Game Setup

  • A random colour code would need to be generated by the Mastermind (in this case VBA)

Gameplay

  • Player must place a guess starting from the right most side of the screen
  • Ensure the guess consists of 4 colours.
  • The guess must be evaluated in order to determine;
    • how many colours are in the correct spot
    • how many colours are correct but in the wrong spot
    • how many colours are not correct.
  • The results should be displayed in a random order so as not to provide a direct solution to the user. i.e Check Box 1 should not represent Colour 1.
  • If the guess matches the MasterMind’s colour code, the player wins

NOTES:

  1. For the purpose of explanation, I plan to work in numbers in order to represent a colour.
  2. In order to proceed I would first need to know the colours I plan to use and its RGB values.

I have taken note of these values and assigned numbers to each of the colours as follows; (1-Red, 2 –Yellow etc…)

 

  • If the colour is placed in the correct spot: “1” would be displayed in the checkbox
  • If the colour is correct but in the wrong spot: “0” would be displayed in the checkbox
  • If the colour does not exist in the mastermind’s code: “NA” would be displayed in the checkbox

Game Setup

Normal Mode

The first step would be to generate a Random Colour Code combination to solve. When I say random, it essentially means scrambled numbers from 1 to 8.

Two sets of random numbers would need to be generated.

The first set would establish the Masterminds code. The second set would be the random positioning inside the check boxes. i.e Checkbox1 would represent the 3rd colour etc…

We first step into the subroutine NewGame.EIGHTRandom()

Dim a(8), i, j, RN As Integer
Dim flag As Boolean

flag = False
i = 1
a(j) = 1

Do While i <= 8
    Randomize
    RN = CInt(Int((8 * Rnd()) + 1))
    
    For j = 1 To i
    
        If (a(j) = RN) Then
            flag = True
            Exit For
        End If
        
    Next
    
    If flag = True Then
        flag = False
    Else
        a(i) = RN
        i = i + 1
    End If
Loop

Range("AX12") = a(1)
Range("AY12") = a(2)
Range("AZ12") = a(3)
Range("BA12") = a(4)

Call EIGHTrandom2

The random numbers generated from this code do not repeat itself. It essentially scrambles itself and extracts the first 4 digits from the array. A similar code is run for the next subroutine EIGHTRandom2().

The results are as follows;

Difficult Mode

This VBA code unlike the normal mode generates a random number between 1 – 8 (and the numbers may get repeated).The following code is used to generate the Random Colour Code combination;

Range("AX12") = Int((8 - 1 + 1) * Rnd + 1)
Range("AY12") = Int((8 - 1 + 1) * Rnd + 1)
Range("AZ12") = Int((8 - 1 + 1) * Rnd + 1)
Range("BA12") = Int((8 - 1 + 1) * Rnd + 1)

Call EIGHTrandom2

Once the mastermind’s code has been generated, the player would need to place his first guess. 

The player can select his choice of colours and select “Check”. There are two possible outcomes once this happens;  

The first outcome occurs if the colours have NOT been placed in all the boxes (and there are no repeated colours etc…). This would end in an error.  

 

The second outcome would output the result of the guess. At this point, the “gamecheck” subroutine will be called.

 

The code for this check for both outcomes can be seen below;

If Not Intersect(Target, Range("AM11")) Is Nothing Then
    Range("AM11").Interior.Color = Range("I34").Interior.Color
ElseIf Not Intersect(Target, Range("AM13")) Is Nothing Then
    Range("AM13").Interior.Color = Range("I34").Interior.Color
ElseIf Not Intersect(Target, Range("AM15")) Is Nothing Then
    Range("AM15").Interior.Color = Range("I34").Interior.Color
ElseIf Not Intersect(Target, Range("AM17")) Is Nothing Then
    Range("AM17").Interior.Color = Range("I34").Interior.Color
ElseIf Not Intersect(Target, Range("AM23")) Is Nothing Then
    If Range("AM11").Interior.Color = RGB(255, 255, 255) Or Range("AM13").Interior.Color = RGB(255, 255, 255) _
    Or Range("AM15").Interior.Color = RGB(255, 255, 255) Or Range("AM17").Interior.Color = RGB(255, 255, 255) Then
        MsgBox ("Please make sure you place a colour in all the boxes before selecting 'CHECK' "), vbExclamation
        Exit Sub
    Else
        If Range("AM11").Interior.Color = Range("AM13").Interior.Color And Range("AM11").Interior.Color = Range("AM15").Interior.Color Then
            MsgBox ("3 of the same colours will never appear"), vbExclamation
            Exit Sub
        ElseIf Range("AM11").Interior.Color = Range("AM15").Interior.Color And Range("AM11").Interior.Color = Range("AM17").Interior.Color Then
            MsgBox ("3 of the same colours will never appear"), vbExclamation
            Exit Sub
        ElseIf Range("AM11").Interior.Color = Range("AM13").Interior.Color And Range("AM11").Interior.Color = Range("AM17").Interior.Color Then
            MsgBox ("3 of the same colours will never appear"), vbExclamation
            Exit Sub
        End If
        
        If Range("AM13").Interior.Color = Range("AM11").Interior.Color And Range("AM13").Interior.Color = Range("AM15").Interior.Color Then
            MsgBox ("3 of the same colours will never appear"), vbExclamation
            Exit Sub
        ElseIf Range("AM13").Interior.Color = Range("AM15").Interior.Color And Range("AM13").Interior.Color = Range("AM17").Interior.Color Then
            MsgBox ("3 of the same colours will never appear"), vbExclamation
            Exit Sub
        ElseIf Range("AM13").Interior.Color = Range("AM11").Interior.Color And Range("AM13").Interior.Color = Range("AM17").Interior.Color Then
            MsgBox ("3 of the same colours will never appear"), vbExclamation
            Exit Sub
        End If
        
        If Range("AM15").Interior.Color = Range("AM11").Interior.Color And Range("AM15").Interior.Color = Range("AM13").Interior.Color Then
            MsgBox ("3 of the same colours will never appear"), vbExclamation
            Exit Sub
        ElseIf Range("AM15").Interior.Color = Range("AM11").Interior.Color And Range("AM15").Interior.Color = Range("AM17").Interior.Color Then
            MsgBox ("3 of the same colours will never appear"), vbExclamation
            Exit Sub
        ElseIf Range("AM15").Interior.Color = Range("AM13").Interior.Color And Range("AM15").Interior.Color = Range("AM17").Interior.Color Then
            MsgBox ("3 of the same colours will never appear"), vbExclamation
            Exit Sub
        End If
                   
        If Range("AM17").Interior.Color = Range("AM11").Interior.Color And Range("AM17").Interior.Color = Range("AM13").Interior.Color Then
            MsgBox ("3 of the same colours will never appear"), vbExclamation
            Exit Sub
        ElseIf Range("AM17").Interior.Color = Range("AM11").Interior.Color And Range("AM17").Interior.Color = Range("AM15").Interior.Color Then
            MsgBox ("3 of the same colours will never appear"), vbExclamation
            Exit Sub
        ElseIf Range("AM17").Interior.Color = Range("AM13").Interior.Color And Range("AM17").Interior.Color = Range("AM15").Interior.Color Then
            MsgBox ("3 of the same colours will never appear"), vbExclamation
            Exit Sub
        End If
                   
        Range("AM23") = ""
        Call gamecheck
    End If
    
End If

Gameplay

Now comes the challenging section of the entire game.  We would now need to move back to the worksheets in order to access the “gamecheck” subroutine

The normal mode has a fairly straightforward thought process as compared to the difficult mode. Let’s first go through the normal mode.

Normal Mode

Let’s say the mastermind’s code is 1234 and the initial guess placed is 4321. The computer logic would be;

  • Check if guess matches the mastermind’s code
  • If guess matches code –> VICTORY!
  • If guess does not match, Inspect each digit

This process would loop through each digit of the guess.

  • Check the number against the corresponding code number (4 against 1, 2 against 3 etc…)
  • If the code matches number, display 1
  • If number does not match, check if the number appears in another position
  • If number appears in another position, display 0
  • If number does not appear, display NA
  • Randomize the order in which it is displayed inside the checkbox
  • Continue with next guess

The result would be 0, 0, 0, and 0

This is fairly easy to manage and can be seen by the VBA code below.

If Cells(11, n).Interior.Color = RGB(R1, G1, B1) And Cells(13, n).Interior.Color = RGB(R2, G2, B2) _
And Cells(15, n).Interior.Color = RGB(R3, G3, B3) And Cells(17, n).Interior.Color = RGB(R4, G4, B4) Then
    MsgBox ("Congratulations! You Won!")
    Range("Y34") = "You Won!"
    Range("N3").Interior.Color = RGB(R1, G1, B1)
    Range("R3").Interior.Color = RGB(R2, G2, B2)
    Range("V3").Interior.Color = RGB(R3, G3, B3)
    Range("Z3").Interior.Color = RGB(R4, G4, B4)
    
    Range("N3") = ""
    Range("R3") = ""
    Range("V3") = ""
    Range("Z3") = ""
    Exit Sub
End If
    
If Cells(11, n).Interior.Color = RGB(R1, G1, B1) Then
    Range("AX" & m) = 1
ElseIf Cells(11, n).Interior.Color = RGB(R2, G2, B2) Or Cells(11, n).Interior.Color = RGB(R3, G3, B3) _
Or Cells(11, n).Interior.Color = RGB(R4, G4, B4) Then
    
    Z = n
    If Cells(11, Z).Interior.Color = Cells(13, Z).Interior.Color Then
        If Cells(13, Z).Interior.Color = RGB(R2, G2, B2) Then
            Range("AX" & m) = "NA"
        Else
            If Range("AX25") >= 1 Then
                Range("AX" & m) = "NA"
            Else
                Range("AX" & m) = 0
                Range("AX25") = Range("AX25") + 1
            End If
        End If
    ElseIf Cells(11, Z).Interior.Color = Cells(15, Z).Interior.Color Then
        If Cells(15, Z).Interior.Color = RGB(R3, G3, B3) Then
            Range("AX" & m) = "NA"
        Else
            If Range("AY25") >= 1 Then
                Range("AX" & m) = "NA"
            Else
                Range("AX" & m) = 0
                Range("AY25") = Range("AY25") + 1
            End If
        End If
    ElseIf Cells(11, Z).Interior.Color = Cells(17, Z).Interior.Color Then
        If Cells(17, Z).Interior.Color = RGB(R4, G4, B4) Then
            Range("AX" & m) = "NA"
        Else
            If Range("AZ25") >= 1 Then
                Range("AX" & m) = "NA"
            Else
                Range("AX" & m) = 0
                Range("AZ25") = Range("AZ25") + 1
            End If
        End If
    Else
        Range("AX" & m) = 0
    End If
Else
    Range("AX" & m) = "NA"
End If

Difficult Mode

The difficult mode contains a few more challenges as the numbers may repeat themselves. Hence the logic is fairly long.

Let’s say the mastermind’s code is 1225 and the initial guess placed is 1124.

  • Check if guess matches code
  • If guess matches code –> VICTORY!
  • If guess does not match, inspect each digit

This process would loop through each digit of the guess

  • Check the number against the corresponding code number (1 against 1, 1 against 2 etc…)
  • If the code matches number, display 1
  • If the number does not match, check if the number appears in another position.
  • If number appears in another position. Check if the current number has been placed twice
  • If current number has been placed twice, Check if the number in that position matches the code in the exact same position
  • If it does NOT match, display 0
  • If it does match display NA (When the guess checks the digit which matches it would display a 1)
  • Randomize the order in which it is displayed inside the checkbox

The result would be 1, NA, 1 and NA

The logic behind is fairly weird, but in these sort of situations, it would be best to find the solution first and then build the code from back to front.

This portion of the VBA code can be seen here.

If Cells(11, n).Interior.Color = RGB(R1, G1, B1) And Cells(13, n).Interior.Color = RGB(R2, G2, B2) _
And Cells(15, n).Interior.Color = RGB(R3, G3, B3) And Cells(17, n).Interior.Color = RGB(R4, G4, B4) Then
    MsgBox ("Congratulations! You Won!")
    Range("Y34") = "You Won!"
    Range("N3").Interior.Color = RGB(R1, G1, B1)
    Range("R3").Interior.Color = RGB(R2, G2, B2)
    Range("V3").Interior.Color = RGB(R3, G3, B3)
    Range("Z3").Interior.Color = RGB(R4, G4, B4)
    
    Range("N3") = ""
    Range("R3") = ""
    Range("V3") = ""
    Range("Z3") = ""
    Exit Sub
End If
    
If Cells(11, n).Interior.Color = RGB(R1, G1, B1) Then
    Range("AX" & m) = 1
ElseIf Cells(11, n).Interior.Color = RGB(R2, G2, B2) Or Cells(11, n).Interior.Color = RGB(R3, G3, B3) _
Or Cells(11, n).Interior.Color = RGB(R4, G4, B4) Then
    
    Z = n
    
    If Cells(11, Z).Interior.Color = RGB(255, 0, 0) Then
        colour = 1
    ElseIf Cells(11, Z).Interior.Color = RGB(255, 255, 0) Then
        colour = 2
    ElseIf Cells(11, Z).Interior.Color = RGB(255, 155, 0) Then
        colour = 3
    ElseIf Cells(11, Z).Interior.Color = RGB(0, 175, 80) Then
        colour = 4
    ElseIf Cells(11, Z).Interior.Color = RGB(0, 175, 240) Then
        colour = 5
    ElseIf Cells(11, Z).Interior.Color = RGB(110, 50, 160) Then
        colour = 6
    ElseIf Cells(11, Z).Interior.Color = RGB(255, 100, 200) Then
        colour = 7
    ElseIf Cells(11, Z).Interior.Color = RGB(155, 100, 50) Then
        colour = 8
    End If

If Cells(11, Z).Interior.Color = Cells(13, Z).Interior.Color Then
    If Cells(13, Z).Interior.Color = RGB(R2, G2, B2) Then

        If Range("AZ12") = colour Then
            Range("AX" & m) = 0
        ElseIf Range("BA12") = colour Then
            Range("AX" & m) = 0
        Else
            Range("AX" & m) = "NA"
        End If
       
    Else
        If Range("AX25") >= 1 Then
            Range("AX" & m) = "NA"
        Else
            Range("AX" & m) = 0
            Range("AX25") = Range("AX25") + 1
        End If
    End If
ElseIf Cells(11, Z).Interior.Color = Cells(15, Z).Interior.Color Then
    If Cells(15, Z).Interior.Color = RGB(R3, G3, B3) Then
    
        If Range("AY12") = colour Then
            Range("AX" & m) = 0
        ElseIf Range("BA12") = colour Then
            Range("AX" & m) = 0
        Else
            Range("AX" & m) = "NA"
        End If

    Else
        If Range("AY25") >= 1 Then
            Range("AX" & m) = "NA"
        Else
            Range("AX" & m) = 0
            Range("AY25") = Range("AY25") + 1
        End If
    End If
ElseIf Cells(11, Z).Interior.Color = Cells(17, Z).Interior.Color Then
    If Cells(17, Z).Interior.Color = RGB(R4, G4, B4) Then
    
        If Range("AY12") = colour Then
            Range("AX" & m) = 0
        ElseIf Range("AZ12") = colour Then
            Range("AX" & m) = 0
        Else
            Range("AX" & m) = "NA"
        End If
        
    Else
        If Range("AZ25") >= 1 Then
            Range("AX" & m) = "NA"
        Else
            Range("AX" & m) = 0
            Range("AZ25") = Range("AZ25") + 1
        End If
    End If
Else
    Range("AX" & m) = 0
End If

Else
    Range("AX" & m) = "NA"
End If

New things I would consider if I were to re-build this game?

Why limit this game to a 4 coloured combination? Maybe a 6 coloured combination would be more challenging? or the colour combination could be any form (4 colours of the same kind :O)

I hope someone out there would use this as a means to generate something new and different. Whether it works or not is irrelevant, it’s more of the experience. These are just fun projects to kill time and help you build challenges to overcome.

1 comment

Leave a comment

Your email address will not be published. Required fields are marked *