John Heck
John Heck

Reputation: 1

I'm trying to make a wordle clone in java but duplicate letters wont display in the right color (display in yellow when they should display in red)

do {
    userInput = input.nextLine().toUpperCase(); // Convert input to uppercase to match secretWord's case

    if (userInput.length() > 5) {
        System.out.println("Invalid Guess, word is too long");
    } else if (userInput.length() < 5) {
        System.out.println("Invalid Guess, word is too short");
    } else {
        for (int i = 0; i < 5; i++) {
            String userChar = userInput.substring(i, i + 1);
            String secretChar = secretWord.substring(i, i + 1); 

            if (userChar.equals(secretChar)) {
                System.out.print(GREEN + userChar + RESET);
            } else if (secretWord.contains(userChar)) {
                System.out.print(YELLOW + userChar + RESET);
            } else {
                System.out.print(RED + userChar + RESET);
            }
        }

        System.out.println();

        if (userInput.equals(secretWord)) {
            correct = true;
        }

        guessCounter++;
    }
} while (guessCounter < maxGuess && !correct);

The program starts by choosing a word from an array of words. say the word selected from the array is Brain, if the user were to type in iiiii it would display the first 3 in yellow the 4th in green and the 5th in yellow. I need it to display all but the 4th in red to show that those letters are not in the word.

I've tried taking the index of userChar and comparing it to the index of secretChar which results in the same thing happening. is there a way I could use something like secretWord.contains(userChar) to determine that it should be red? any help would be appreciated!

Upvotes: -2

Views: 234

Answers (2)

shmosel
shmosel

Reputation: 50746

When marking yellow letters, you need to keep track of which letters were already "claimed" as yellow or green. One approach is to keep a list (or multiset) of available chars and empty it as letters are claimed. You'll also have to double-check that you're not stealing a green in advance. I think the easiest way to do that is to run through the word twice, first claiming the green letters, then again to print:

List<Character> available = IntStream.range(0, 5)
        .filter(i -> secretWord.charAt(i) != userInput.charAt(i))
        .mapToObj(secretWord::charAt)
        .collect(Collectors.toCollection(ArrayList::new));

for (int i = 0; i < 5; i++) {
    char userChar = userInput.charAt(i);
    char secretChar = secretWord.charAt(i);

    if (userChar == secretChar) {
        System.out.print(GREEN + userChar + RESET);
    } else if (available.remove((Character)userChar)) {
        System.out.print(YELLOW + userChar + RESET);        
    } else {
        System.out.print(RED + userChar + RESET);
    }

    ...

Upvotes: 0

Reilas
Reilas

Reputation: 6266

I am not familiar with Wordle, so this might be somewhat incorrect.

"... if the user were to type in iiiii it would display the first 3 in yellow the 4th in green and the 5th in yellow. I need it to display all but the 4th in red to show that those letters are not in the word. ..."

Utilize a class to colorize the word.

Here is Wikipedia article on SGR control sequences.
Wikipedia – SGR (Select Graphic Rendition) parameters

class Word {
    String s;
    Set<Character> set = new LinkedHashSet<>();
    static String red = "\033[31m", yellow = "\033[33m", reset = "\033[0m";

    Word(String s) {
        this.s = s;
    }

    void guess(char c) {
        set.add(c);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (char c : s.toCharArray()) {
            sb.append(set.contains(c) ? yellow : red);
            sb.append(c).append(reset);
        }
        return sb.toString();
    }
}

And, here is an example usage.

Word w = new Word("Brain");
System.out.println(w);
w.guess('i');
System.out.println(w);

Upvotes: 0

Related Questions