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:
- For the purpose of explanation, I plan to work in numbers in order to represent a colour.
- 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.
Brilliant! Something to look forward to when I am bored.