Mastermind is a two player board game. In this game, one of the player sets a code using different colored pegs and the other player guesses to match that code in certain number of tries. The code setter player is called code-maker and the code guesser player is called code-breaker.The code-maker, after every guess, does provide hints, to the code-breaker. This game is mostly visual and easy to play but by building it as a computer program I learned how human process information differently as compared to a machine. Programming the logic for computing those hints based on the guess answer was probably the hardest problem of the game to solve.
To begin with, I started by building a basic command-line interface game, so as to get the main logic right. Getting the user guess as input and matching with code was fairly straightforward. I generated a random 4-digit code, with each digit in range 0-6. This 4-digit code would essentially serve as basis for representing colored pegs. Thus, when a code-breaker would input his guess, which would be an integer e.g. 4332, I would split that integer into an char array. That char array would be helpful in looping through each digit of guess, making it easy to check if a digit exists in code or is at right positon. For each digit matching the correct position, I would provide "-" sign as a hint and if digit exists in code but is at wrong position i would provide "+" as a hint. No hints would be provided if the digit in guess answer doesn't exists in code.
The logic for computing the hints sounds easy but it isn't. Take an example, when the code is "2331" and code-breaker guesses "1232". lets take the "human thinking" approach. We start with first digit from guess i.e "1", the digit exists in code but is at wrong position so we put output "+" as hint. Next, we have "2", it exists but is also at wrong position so again "+" hint. Now comes "3", it exists but its at two positons one at right and other at wrong but we know that if positions matches we would want to give the "-" and not care about the other position as we are looping through digits of guess only once. Therefore, we output "-" sign hint. But here comes the deal with computer's "thinking", when we loop through code it would first encounter the "3" digit in code at would immediately throw the "+" hint. "But dumb author why don'
t you loop through the guess twice, In first loop checking for "+" hints and in other for "-" hints" you would say that and you would be right about this but there's another problem. You see, even if I first check if digits is at right position and provide "-" hint, the second loop would still provide the "+" hint because it would encounter "3" digit at wrong position. We don't want to output only either a single hint or no hint for each digit in guess answer.
Now, we are on our last digit from guess answer "1232". It's digit, "2", again. This digit exists in code too and it is at wrong position and therefore it would be obvious that we would supply "+" hint but we would be wrong! You see, It's because the code has the "2" digit occurring only once. The code-maker wouldn't want to provide two hints for same digit in code but the computer will and we don't want that.
All in all, these complex edge case had to be taken in account, and so after hours of brute forcing I came up with the following solution.
I built the logic by looping through the guess answer thrice. Although, the first loop is basically creating the copy of guess so only two loops, I guess.
So, at end, I took three loops and some memory space to verify the guess answer.
continued in part 2.
To begin with, I started by building a basic command-line interface game, so as to get the main logic right. Getting the user guess as input and matching with code was fairly straightforward. I generated a random 4-digit code, with each digit in range 0-6. This 4-digit code would essentially serve as basis for representing colored pegs. Thus, when a code-breaker would input his guess, which would be an integer e.g. 4332, I would split that integer into an char array. That char array would be helpful in looping through each digit of guess, making it easy to check if a digit exists in code or is at right positon. For each digit matching the correct position, I would provide "-" sign as a hint and if digit exists in code but is at wrong position i would provide "+" as a hint. No hints would be provided if the digit in guess answer doesn't exists in code.
The logic for computing the hints sounds easy but it isn't. Take an example, when the code is "2331" and code-breaker guesses "1232". lets take the "human thinking" approach. We start with first digit from guess i.e "1", the digit exists in code but is at wrong position so we put output "+" as hint. Next, we have "2", it exists but is also at wrong position so again "+" hint. Now comes "3", it exists but its at two positons one at right and other at wrong but we know that if positions matches we would want to give the "-" and not care about the other position as we are looping through digits of guess only once. Therefore, we output "-" sign hint. But here comes the deal with computer's "thinking", when we loop through code it would first encounter the "3" digit in code at would immediately throw the "+" hint. "But dumb author why don'
t you loop through the guess twice, In first loop checking for "+" hints and in other for "-" hints" you would say that and you would be right about this but there's another problem. You see, even if I first check if digits is at right position and provide "-" hint, the second loop would still provide the "+" hint because it would encounter "3" digit at wrong position. We don't want to output only either a single hint or no hint for each digit in guess answer.
Now, we are on our last digit from guess answer "1232". It's digit, "2", again. This digit exists in code too and it is at wrong position and therefore it would be obvious that we would supply "+" hint but we would be wrong! You see, It's because the code has the "2" digit occurring only once. The code-maker wouldn't want to provide two hints for same digit in code but the computer will and we don't want that.
All in all, these complex edge case had to be taken in account, and so after hours of brute forcing I came up with the following solution.
![]() |
| The actual UI of Harv's mastermind. |
for (int i = 0; i < code.length; i++) {
list.add(code[i]);
}
for (int i = 0; i < guess.length; i++) {
if (code[i] == guess[i]) {
hints.add('-');
list.set(i, 9);
}
}
for (int i = 0; i < guess.length; i++) {
if (list.contains(guess[i]) && (code[i] != guess[i])) { //1232
hints.add('+');
list.set(list.indexOf(guess[i]), 9);
}
}
I built the logic by looping through the guess answer thrice. Although, the first loop is basically creating the copy of guess so only two loops, I guess.
I kept this copy of guess as a list array to keep track of digits that had been verified, this array also helped in avoiding logging of double hints. Let call it "list" from now on.
The first loop is obvious, I created an array list by looping through each digit of code. The next loop is for output of the "-" sign hint. In this loop, I only checked if the digit at nth position in guess is same as digit in nth position in code. If it is/was then I replaced that digit from the list containing copied guess with digit "9". I am using digit "9" because it doesn't exist in range 0-6 and since list was of integer type I had to choose some number.
The third and final loop is for the "+" sign hint. This time I checked if digit in guess at nth position is in list and then also made sure that they both aren't at same position. If the conditions were true, then I would replace the digit at guessed digit's index with digit "9" and also output the "+" sign.
The third and final loop is for the "+" sign hint. This time I checked if digit in guess at nth position is in list and then also made sure that they both aren't at same position. If the conditions were true, then I would replace the digit at guessed digit's index with digit "9" and also output the "+" sign.
So, at end, I took three loops and some memory space to verify the guess answer.
continued in part 2.


Comments
Post a Comment