The Game of MasterMind
MasterMind is a game of logic with two players, a code maker and a code guesser. The code is a sequence of four colored pegs, peg1, peg2, peg3 and peg4. Each peg is one of six colors (red, orange, yellow, green, blue or white). The code maker secretly selects a color for each of the four pegs. Repeated colors are allowed (so two or more of the pegs may have the same color). The code guesser then has ten chances to "break the code". After each guess, the code maker provides the guesser with two pieces of information about the current guess and the actual code. These pieces of information are:
  1. (Hint 1) The number of pegs in the guess that are the correct color and in the correct position.
  2. (Hint 2) The number of pegs in the guess that are the correct color.
The second number above is always bigger than or equal to the first number. Here is a sample code, some sample guesses, and the corresponding values of the two hints.
 
 
peg 1 peg 2 peg 3 peg 4 Hint 1 Hint 2
Code 1 red blue red white
Guess 1 orange red green yellow 0 1
Guess 2 red red yellow red 1 2
Guess 3 blue red red orange 1 3

Our goal is to design and implement a MasterMind class that plays the role of the code maker and allows the user to play the role of the code guesser. A skeleton source code file is located in the folder G:\Lintont\COSC135b\Pickup\MasterMind\ (copy the entire folder to your H:\ drive), or the source code is located here.

  1. We will use the correspondence red = 0, orange = 1, yellow = 2, green = 3, blue = 4, and white = 5. Note: the colors go in the same order that they appear in a rainbow (except for white of course). In situations like this, it is best to define constants that represent this correspondence. Just after the GUI design area in the file MasterMind.java, add constants for each color-number correspondence. The one for red would be:
final int RED = 0;
If you define constants, you should use them wherever appropriate, thus, if you need to check if a variable is holding the code for the red color, rather than asking peg1 == 0; you should ask peg1 == RED; Constants (like ours) are allowed as the cases in a switch statement. Once you've entered each of the constants, make the code fragment below the body of your buttonClicked method.

results.setText(" " + RED + WHITE + BLUE + GREEN + YELLOW + ORANGE);

Compile and run the project. Click the button and record what is printed in the TextArea below:
 
 
 
 
 
 
 

  1. In the final version of our program, we will need to print the secret code (in words, not numbers), when the code guesser loses the game (they fail to guess the correct code in 10 tries). Our message should print something like:
The secret code was red, white, red, blue.
For this, we could use a method that translates our integers 0 to 5 (or the constants RED, ORANGE, etc.), to Strings for our colors, "red", "orange", "yellow", etc. Our method will input an integer and output a String. If the input is not an integer from 0 to 5, the String "error" should be returned, otherwise, the String corresponding to the color associated with the input should be returned. Thus, if 0 is the input, "red" is the output, and if 3 is the input, "green" is the output. Add a method named colorWord, that performs this conversion (int to String). Use a switch block in your method. You can handle the problem of input being out of range (not from 0 to 5) in the default case. You need NOT display an error message here, just return the String "error". Once you have written your method, replace the body of the buttonClicked method with the code below.
results.setText("Testing colorWord method:\n" +
      Format.justify('c', "input", 8) +
      Format.justify('c', "output", 8) + "\n");
for (int k = 6; k >= -1; k--) {
   results.append(Format.justify('c', k, 8) +
         Format.justify('c', colorWord(k),8) + "\n");
}
Run the project and record the output displayed below:
 
 
 
 
 
 
 
  1. The java statement Math.random() will produce a double value x with 0 < x < 1. Thus, 6*Math.random() will create a double between 0 and 6 (not including the endpoints). If such a value is cast to an integer type, you'll get a random integer from 0 to 5. Use this information to define the makeSecretCode() method. This method should select four colors (they need NOT be different colors) for the four pegs that make up the secret code. These pegs are global or class variables named code1, code2, code3, and code4. Your method should have no input parameters and should produce no output either. It simply sets the values of code1, code2, code3, and code4. Copy the body of your makeSecretCode() method below.

 
 
 
 
 
 
 
 
 
 
 
 
 
  1. Here is an interesting feature of the switch command: If you do NOT use a break statement in the block corresponding to some case, then java continues to execute the statements for the next case (and the next case, and so on, until it finds a break statement). For example, consider this switch block:
    1. switch(n) {
         case 3:
            results.append("Three French hens, ");
         case 2:
            results.append("Two turtle doves, and ");
         case 1:
            results.append("a partridge in a pear tree!");
      }
    If n is equal to 3, the TextArea (named results) will print all three phrases. If n is equal to 2, two phrases will get printed (the case 2 and case 1 phrases), and if n is 1, only the last phrase will get printed. In addition to this situation (where you want to do more and more, or less and less, with each successive value of n), you can also "do the same thing" for several cases. Keep in mind that your cases need NOT be defined in any special order. It is perfectly legal to go case 5, case 3, case 9, case 8, case 1, or any other order. Suppose you wanted to execute two statements for n = 1, 2 or 6, and a different statement for n = 3,4,5.
     
    Your switch block could look like this: 
    switch(n) {
       case 1:
       case 2:
       case 6:
          statement1;
          statement2;
          break;
       case 4:
       case 5:
       case 3:
          other statement;
          break;
    Or even better, like this: 
      switch(n) {
         case 1: case 2: case 6:
            statement1;
            statement2;
            break;
         case 4: case 5: case 3:
            other statement;
            break;
      }
       
       

    Write a buttonClicked method that tests your makeSecretCode() method 6 times. On the first and fourth test, simply append the number codes to the TextArea named results (as in "0, 4, 0, 2." if your code is red, blue, red yellow). On the second and sixth tests, print a nicely formatted message using words for the colors, like "the code is red, blue, red, yellow." (periods, commas and all). On the third and fifth tests, append just the words corresponding to the colors in the secret code (as in "red, blue, red, yellow."). Use a for loop and a switch block for this. You can take advantage of both features of the switch block mentioned above (doing more and more as well as lumping cases together). Copy your buttonClicked method body below:
     
     
     
     
     
     
     
     
     
     
     
     

  2. Once a user has entered four color-numbers in the GUI area, it should be quite simple to get these values and store them in global or class variables (the variables peg1, peg2, peg3 and peg4). During a play of the game, we will need to get these guesses from the GUI repeatedly. For this reason, we should have a getGuess() method (that performs this task for us). This way, we need not repeat several lines of code that do the same thing over and over again, we can simply call the getGuess() method (with a single line of code). Write the getGuess() method (it has no input and returns nothing). Write a buttonClicked method to test your getGuess method. After you type in color-numbers for each peg and press the button, the TextArea should print the numbers entered and their corresponding colors. Use the setText method rather than the append method (so the TextArea deletes the old message each time you press the button). Enter the guess 0, 5, 2, 2 and record the output of your buttonClicked method below:

  3.  

     
     
     
     
     
     
     
     

    Calculating the value of hint 1 is relatively easy. That is, given the 4 pegs of a guess and the four pegs of a secret code, it is straightforward to calculate the number of pegs in the guess that are in the right location and the correct color (or completely correct). Call the guessed pegs guess1, guess2, guess3 and guess4, and assume these are inputs to a method named hint1. The body of hint1 can check if guess1 == code1, and if so increment some variable. Then do the same for the second, third and fourth pegs. Finally, the method should return the value of this variable (namely the number of pegs in the guess that are completely correct). Write the hint1 method. Copy your hint1 method below (all of it, not just the body).