Search code examples
arrayscfunctioncs50

Attempted to create a basic wordle clone and am running into roadblocks


New to coding, just a few weeks in now. Trying my hand at making a Wordle clone sounded like good practice, so I started earlier today. I have also really not learned a thing about pointers, by the way.

Running into problems on line 42:

string result = check(guess[i], key) 

where I try to use my check function, the CLI returns this to me:

incompatible pointer types initializing 'string' (aka 'char *') with an expression of type 'string *' (aka 'char **')

Problem two is I can get the checks for each letter of the guess, but they are stored in an array called letter, and I'd like to combine them in a string to say: 1st letter: right spot, 2nd letter: not in word... etc. Not sure if this is possible.

Also trying to pass the letter array back from my function and not sure how that works. But I can figure that one out, I think. I also considered passing back an int and from that I could extrapolate the results, but not to sure what way is best.

Sorry for the word vomit, but I do want to accomplish this and don't know where to go.

#include <cs50.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

string word_list[] = { "blind", "sheet", "crush", "relax", "drain",
    "label", "expel", "thump", "shade", "resin", "alert", "dream",
    "flood", "guard", "adult", "force", "wound", "drain", "cable"
};
string key;

string *check(string guess, string key);

int main(void)
{
    char ready;
    do {
        ready = get_char("Welcome to wordle! Are you ready to play? (y/n) ");
    } while (ready != 110 && ready != 121);

    if (ready == 121) {
        int ran;
        srand(time(NULL));
        ran = rand() % 18;
        key = word_list[ran];
    } else {
        return 1;
    }

    int guess_num = 1;
    string guess[5];

    for (int i = 0; i < 5; i++)
        do {
            guess[i] = get_string("Guess %i:\n", guess_num);
            string result = check(guess[i], key);
            printf("%s\n", result);

            if (strlen(guess[i]) == 5) {
                guess_num++;
            }
        } while (strlen(guess[i]) != 5);
}

string *check(string guess, string keys)
{
    string correct = "in correct spot." ;
    string almost = "in the word, wrong spot.";
    string not = "not in word.";
    string letter[5];

    for (int i = 0; i < 5; i++)
        if (guess[i] == key[])
        {
            letter[i] = correct;
        }
        else if (guess[i] == key[0] || guess[i] == key[1] || guess[i] == key[2] || guess[i] == key[3] || guess[i] == key[4])
        {
            letter[i] = almost;
        }
        else
        {
            letter[i] = not;
        }
    return letter;
}

I have tried multiple sites and tutorials but no really understanding, or solutions are for a similar problem but dont address my own.


Solution

  • There are multiple problems:

    • the test if (guess[i] == key[]) is a syntax error. You should write:

        if (guess[i] == key[i])
      
    • the function check returns a local array: this is invalid. The array becomes invalid as soon as the function returns so a pointer to its first element must not be returned to the caller. You should instead take the array as an argument (defined in the calling function) and update it in check(). note also that letter should be a char array of length 6, not a string (which is just a char *).

    • you should use character constants instead of cryptic ASCII codes ready != 110 && ready != 121:

       ready != 'n' && ready != 'y'
      
    • there are actually 19 words in the word_list array, do not use 18 but an expression that evaluates to the length of the array.

    Here is modified version:

    #include <cs50.h>
    #include <ctype.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    string word_list[] = {
        "blind", "sheet", "crush", "relax", "drain",
        "label", "expel", "thump", "shade", "resin",
        "alert", "dream", "flood", "guard", "adult",
        "force", "wound", "drain", "cable"
    };
    string key;
    
    void check(string guess, string key, char letter[]);
    
    int main(void)
    {
        char ready;
        do {
            ready = get_char("Welcome to wordle! Are you ready to play? (y/n) ");
        } while (ready != 'n' && ready != 'y');
    
        if (ready == 'y') {
            srand(time(NULL));
            int ran = rand() % (sizeof word_list / sizeof word_list[0]);
            key = word_list[ran];
        } else {
            return 1;
        }
    
        int guess_num = 1;
        string guess[5];
        char result[6];
    
        for (int i = 0; i < 5; i++) {
            do {
                guess[i] = get_string("Guess %i:\n", guess_num);
            } while (strlen(guess[i]) != 5);
    
            check(guess[i], key, result);
            printf("%s\n", result);
            guess_num++;
            if (!strcmp(guess[i], key)) {
                printf("found!\n");
                return 0;
            }
        }
        printf("not found! word was %s\n", key);
    }
    
    void check(string guess, string keys, char letter[6])
    {
        char correct = 'O';
        char almost = 'X';
        char not = '.';
    
        for (int i = 0; i < 5; i++) {
            if (guess[i] == key[i]) {
                letter[i] = correct;
            } else
            if (guess[i] == key[0] || guess[i] == key[1] || guess[i] == key[2]
            ||  guess[i] == key[3] || guess[i] == key[4]) {
                letter[i] = almost;
            } else {
                letter[i] = not;
            }
        }
        letter[5] = '\0';  // set the null terminator
    }