1

I am trying to make a wordle clone in C, but I cannot deal with duplicate yellow letters. For example, if the master word is "apple" and the user guess is "aplle" (not an actual word, just an example), my code returns "APlLE" instead of "AP*LE". Note that an uppercase character denotes a green character, lowercase denotes a yellow one, and a * denotes a gray one.

This is the logic for handling the user guess. I'm really unsure as to how I can get a solution for this, if it's even possible with this logic. Any help is much appreciated. I've tried looking at other similar questions, but the code looks fairly different and this is my first time coding in C. Thanks in advance!

do {
    scanf("%5s", userGuess);
    correctGuess = strcmp(userGuess,chosenWord);
    if (strlen(userGuess) != 5) { // checks if the user input is not a 5 letter word
        printf("Please enter a five letter word.\n");
    }
    else if (correctGuess == 0) { // 0 means that the two strings are the same
        printf("You are correct!\n");
        guessNumber++;
        printf("%i", guessNumber);
    }
    else {
        guessNumber++;
        for (int i = 0; i <= 4; i++) { // green letter implementation
            if (userGuess[i] == chosenWord[i]) {
                userGuess2[i] = toupper(userGuess[i]);
            }
            else {
                int yellowChar = 0; // handles yellow letters - doesn't know how to deal with duplicates
                for (int j = 0; j < 5; j++) {
                    if (i != j && userGuess[i] == chosenWord[j]) {
                        userGuess2[i] = tolower(userGuess[i]);
                        yellowChar = 1;
                        break;
                    }
                }
                if (!yellowChar) { // handles gray letters
                    userGuess2[i] = '*';
                }
            }
        }
        printf("%s\n", userGuess2);
    }
}
while(guessNumber <= 5 && correctGuess != 0);
Ken White
  • 123,280
  • 14
  • 225
  • 444
  • 1
    Logic should be first check for exact match, then only consider unmatched positions for yellow letters. You can't do it in one pass because you may not have hit the green position yet. – stark Feb 25 '23 at 19:19

2 Answers2

0

The answer you are looking for is to add to your yellow if statement another && condition:

if (i != j && userGuess[i] == chosenWord[j] && userGuess[i] != userGuess[j]) {
  logic
}

That'll take care of that, if the word is apple then the guess aaaaa would result in A****.

There is still another problem which is if the guess is xaaaa then it would still yellow all of the other 4 A's not just the first one of them.

Saar
  • 96
  • 5
  • Ah, thank you! Is there any way to solve the issue you've brought up as well? – Daniel Joseph Feb 25 '23 at 19:47
  • What's the desired behavior for this case - one yellow and four stars? – mzimmers Feb 25 '23 at 19:55
  • Yes @mzimmers, the desired behavior would be `*a***`. I honestly am not sure how to fix it myself, I tried for a bit and couldn't really figure it out (this is why I didn't add it in my answer in the first place). My general direction is if the number of instances of a letter in the guess is higher than the number of instances of that letter in the secret word, then stop "yellowing" letters after the amount of instances in the secret word is met. – Saar Feb 25 '23 at 20:13
  • 1
    @Saar right, that's what I do in my solution. This line of code indicates how I did just that. – mzimmers Feb 25 '23 at 23:15
0

You could use a flag or two:

const int STR_LEN = 5;
const char *answer = "apple";
void adjustCase(char *s) {
    for (int i = 0; i < STR_LEN; i++) {
        s[i] = tolower(s[i]);
    }
}
int main(int argc, char *argv[])
{
    char guess[STR_LEN + 1]; // for null terminator
    char evalResult[STR_LEN + 1]; // for null terminator
    int guessNumber = 0;
    bool correct = false;
    bool charFound;

    do {
        charFound = false;
        strcpy(evalResult, "*****");
        scanf("%5s", guess);
        adjustCase(guess);
        if (strcmp(guess, answer) == 0) {
            correct = true;
            printf("You are correct!\n");
        }
        else {
            guessNumber++;
            for (int i = 0; i < STR_LEN; i++) {
                if (guess[i] == answer[i]) {
                    evalResult[i] = toupper(guess[i]);
                } else if (!charFound){
                    for (int j = 0; j < STR_LEN; j++) {
                        if (guess[i] == answer[j]) {
                            evalResult[i] = guess[i];
                            charFound = true;
                            break;
                        }
                    }
                }
            }
            printf("%s\n", evalResult);
        }
    }
    while(guessNumber <= 5 && !correct);
}

Not the only answer, and probably not even the best, but seems straightforward and reasonable efficent.

mzimmers
  • 857
  • 7
  • 17