0

This is a project I have for a class. I am still a beginner, so this topic is only supposed to cover things up to strings, loops and arrays. If you are not familiar with the game, the advanced version is this. However I am tasked with a simpler version. Here are the rules for this version.

The program starts by asking the first player, the code maker, to enter a pattern to be used for the game. The pattern is 4 letters long and each letter represents a color (R is red, G is green).
To simplify the game, there are only two colors that can be used, red and green. So for example, the user may enter RRGR to represent Red Red Green Red, or they could enter GGGG to represent Green Green Green Green. To simplify, you can assume that the pattern will only consist of R’s and/or G’s, the code maker will not enter incorrect characters or symbols.However, you must check that the code maker entered exactly 4 character (that it is 4 characters long, not 5 and not 3). If they do not, you need to prompt until they do. The code maker might enter upper or lowercase letters and you should be able to handle it.

The program also asks for a maximum number of guesses that is allowed. Now the game can begin.The code breaker now guesses the pattern to try to win the game. If they cannot do so by the maximum number of guesses, they lose. To help the code breaker, your program will give feedback after each guess. Specifically,for each color that is in the exact correct location, it will show a black peg. For each color that is not in the correct location, but is in the pattern, it will show a white peg. See the sample interactions for examples of this. Detailed requirements and hints:

Here is a sample of how it should work:

Code maker, please enter a pattern of 4 colors (the possible colors are R=red and G=green):

GGGR

What is the maximum number of guesses allowed for this game?

4

Okay, now it's the code breaker's turn. You have 4 chances to guess the pattern. Enter a guess:

RRRR

The code maker sets out 1 black pegs and 0 white pegs. 

Enter a guess:

GGRG

The code maker sets out 2 black pegs and 2 white pegs

Enter a guess:

GGGR

You got the pattern! The code breaker wins!

WHERE I AM SO FAR

First I want to calculate black pegs. The best way to do it is to transform string input into arrays by using FOR loops. There are two main arrays, the original pattern that needs to be solved, and the attempt array for all attempts done by the user. Then we use a FOR loop to compare the array contents and add a black peg every time they match in an attempt.

This is the code I am focusing on (calculating black pins). My issue so far is that I cant get the pins to match with every array content. Basically, it always results in 4 pins, even though there are times it should be 3 pins or 2. The entire unfinished code is below this part if needed.

String pattern = keys.nextLine().toUpperCase(); // this is used to enter the original pattern
String attempt = keys.nextLine().toUpperCase(); // this is to enter an attempt

String pattern_array [] = new String [5];
String attempt_array [] = new String [5];

int i;          
int black_pegs = 0;
for (i=0; i<pattern.length(); i++) {
    pattern_array[i] = pattern.substring(i,(i+1)); 
}
for ( i=0; i<attempt.length();i++) {
    attempt_array[i] = attempt.substring(i,i+1);
}
for (int x=0; x<4; x++) {
    if (pattern_array[i]==attempt_array[i]) {
        black_pegs++;
    }
}

This is my code of what I have so far (feel free to take a look and point out other things if you wish)

import java.util.Scanner;
public class CopyOfAssignment5 {
    public static void main(String[] args) {
        Scanner keys = new Scanner(System.in);
        System.out.println("Codemaker, please enter a pattern of 4 colors (the possible colors are R=red and G=green");
        String pattern = keys.nextLine().toUpperCase();
        System.out.println("What is the maximum number of guesses for this game?");
        int number_of_guesses = keys.nextInt();
        int turns = number_of_guesses + 1;
        System.out.println();
        System.out.println();
        System.out.println();
        System.out.println();
        System.out.println("Okay, now its the codebreaker's turn. You have " + number_of_guesses
                + " chances to guess the pattern");
        System.out.println("Enter a Guess:");

        int white_pegs = 0, black_pegs = 0;
        String pattern_array[] = new String[5];
        String attempt_array[] = new String[5];
        String attempt = null;

        while (turns > 0) { // while turns are not zero
            attempt = keys.nextLine().toUpperCase(); // then keep displaying the scanner input for an attempt.
            turns--;
        }
        if (attempt.equals(pattern)) { // if you get the correct patter, then you win. Loops stops.
            System.out.println("You got the pattern! The codebreaker wins!");
        }
        if (turns == 0 && !(attempt.equals(pattern))) {
            System.out
                    .println("The codemaker sets out " + black_pegs + " black pegs and " + white_pegs + " white pegs.");
            System.out.println("Sorry, that was your last chance. You lost.");
        } else if (turns < turns) {
            System.out
                    .println("The codemaker sets out " + black_pegs + " black pegs and " + white_pegs + " white pegs.");
            System.out.println("Enter a Guess:");
        }

        int i;
        for (i = 0; i < pattern.length(); i++) {
            pattern_array[i] = pattern.substring(i, (i + 1));
        }
        for (i = 0; i < attempt.length(); i++) {
            attempt_array[i] = attempt.substring(i, i + 1);
        }
        for (int x = 0; x < 4; x++) {
            if (pattern_array[i] == attempt_array[i]) {
                black_pegs++;
            }
        }
    }
}
John Kugelman
  • 307,513
  • 65
  • 473
  • 519
Emil
  • 13
  • 4

2 Answers2

2

Here is my implementation. I won't explain the code since you have already accepted an answer. Still maybe you would like to compare your code with mine. And maybe other people will land on this question and get some benefit from the below code.

public class MstrMind {
    private static final char  BLACK = 'B';
    private static final char  WHITE = 'W';
    private static final int  CODE_LENGTH = 4;

    private static String getCode(Scanner stdin) {
        System.out.println("Code maker, please enter a pattern of " + CODE_LENGTH + " colors (the possible colors are R=red and G=green):");
        String code = stdin.nextLine();
        while (!isCodeValid(code)) {
            System.out.println("Entered code does not contain " + CODE_LENGTH + " colors.");
            System.out.println("Code maker, please enter a pattern of " + CODE_LENGTH + " colors (the possible colors are R=red and G=green):");
            code = stdin.nextLine();
        }
        return code.toUpperCase();
    }

    private static int getGuesses(Scanner stdin) {
        System.out.print("What is the maximum number of guesses allowed for this game? ");
        int guesses = stdin.nextInt();
        stdin.nextLine();
        return guesses;
    }

    private static boolean guess(Scanner stdin, String code) {
        System.out.print("Enter a guess: ");
        String guess = stdin.nextLine();
        char[] flags = new char[CODE_LENGTH];
        int blackCount = 0;
        int whiteCount = 0;
        for (int i = 0; i < CODE_LENGTH; i++) {
            if (guess.charAt(i) == code.charAt(i)) {
                flags[i] = BLACK;
                blackCount++;
            }
            else {
                for (int j = 0; j < CODE_LENGTH; j++) {
                    if (guess.charAt(j) == code.charAt(i)  &&  flags[j] == 0  &&  i != j) {
                        flags[j] = WHITE;
                        whiteCount++;
                    }
                }
            }
        }
        boolean guessed = blackCount == CODE_LENGTH;
        if (!guessed) {
            System.out.printf("The code maker sets out %d black pegs and %d white pegs.%n",
                              blackCount,
                              whiteCount);
        }
        else {
            System.out.println("You got the pattern! The code breaker wins!");
        }
        return guessed;
    }

    private static boolean isCodeValid(String code) {
        return code != null && code.length() == CODE_LENGTH;
    }

    private static void playGame(Scanner stdin, String code, int guesses) {
        int guess = guesses;
        boolean guessed = false;
        while (guess > 0  &&  !guessed) {
            guessed = guess(stdin, code);
            guess--;
        }
        if (!guessed) {
            System.out.println("Code breaker failed to break the code. Code maker wins.");
        }
    }

    public static void main(String[] args) {
        Scanner stdin = new Scanner(System.in);
        String code = getCode(stdin);
        int guesses = getGuesses(stdin);
        System.out.printf("Okay, now it's the code breaker's turn. You have %d chances to guess " +
                                                                                  "the pattern.%n",
                          guesses);
        playGame(stdin, code, guesses);
    }
}
Abra
  • 11,631
  • 5
  • 25
  • 33
1

There are a lot of mistakes in your program.

You need to keep the while loop running as long as the turns are not over. I see the closing brace } for while loop is misplaced.

You need to break from the loop when you find the pattern.

turns < turns and turns == 0 inside the loop makes no sense. because, in that case, there's no way it enters the loop.

You don't need to create a new String array. You can use String's chatAt() method.(This is not a logical error though)

There's a bug in reading the input. After you use Scanner.nextInt() you should use scanner.nextLine() as stated here

Make int white_pegs = 0, black_pegs = 0; local variables with respect to loop. Following is the full working code.

public class CopyOfAssignment5 {

public static void main(String[] args) {
    Scanner keys = new Scanner(System.in);

    System.out.println("Codemaker, please enter a pattern of 4 colors (the possible colors are R=red and G=green");
    String pattern = keys.nextLine().toUpperCase();
    System.out.println("What is the maximum number of guesses for this game?");

    int number_of_guesses = keys.nextInt();
    keys.nextLine();
    int turns = number_of_guesses + 1;
    System.out.println();
    System.out.println();
    System.out.println();
    System.out.println();
    System.out.println("Okay, now its the codebreaker's turn. You have " + number_of_guesses
            + " chances to guess the pattern");
    System.out.println("Enter a Guess:");

    String attempt = null;

    while (turns > 0) { // while turns are not zero
        attempt = keys.nextLine();
        attempt = attempt.toUpperCase(); // then keep displaying the scanner input for an attempt.
        turns--;

        if (attempt.equals(pattern)) { // if you get the correct patter, then you win. Loops stops.
            System.out.println("You got the pattern! The codebreaker wins!");
            break;// Exit from while
        }

        // count black and white pegs to set.

        int rCountInPattern = 0;
        int gCountInPattern = 0;

        int rCountInAttempt = 0;
        int gCountInAttempt = 0;
        int white_pegs = 0, black_pegs = 0;

        for (int i = 0; i < 4; i++) {
            if (pattern.charAt(i) == attempt.charAt(i)) {
                black_pegs++;
            } else {
                if (pattern.charAt(i) == 'R') {
                    rCountInPattern++;
                } else {
                    gCountInPattern++;
                }

                if (attempt.charAt(i) == 'R') {
                    rCountInAttempt++;
                } else {
                    gCountInAttempt++;
                }
            }
        }

        white_pegs = Math.min(rCountInPattern, rCountInAttempt);
        white_pegs = white_pegs + (Math.min(gCountInPattern, gCountInAttempt));

        System.out
                .println("The codemaker sets out " + black_pegs + " black pegs and " + white_pegs + " white pegs.");
        System.out.println("Enter a Guess:");

    }

    if (turns <= 0) {
        System.out.println("Sorry, that was your last chance. You lost.");
    }

}

}

Although there are a lot of things that needs improvement, I have posted an answer that isn't too different from your solution so that you can understand it better.

EDIT: My answer is just a minimal working solution which gets you the output. @Abra has given a more modular, more readable code.

Arun Gowda
  • 1,715
  • 4
  • 17
  • 34