#ifndef S4638520_WORDLE #define S4638520_WORDLE #include #include #include #include #include #define MIN_RANGE 3 #define MAX_RANGE 9 #define MAX_FLAGS 2 // According to spec max guess is 50, so giving some extra space for // newline, EOF, etc #define MAX_GUESS_LENGTH 55 #define ENVIRONMENT_WORD "WORD2310" #define WELCOME_MESSAGE "Welcome to Wordle!\n" #define USAGE_MESSAGE "Usage: wordle [-len word-length] [-max max-guesses] "\ "[dictionary]\n" #define FILE_ERROR "wordle: dictionary file \"%s\" cannot be opened\n" #define DEFAULT_WORD_LENGTH 5 #define DEFAULT_MAX_GUESSES 6 #define DEFAULT_DICTIONARY_PATH "/usr/share/dict/words" enum ErrorCodes { E_OK = 0, E_ARGS = 1, E_FILE = 2, E_LOST = 3 }; typedef struct Dictionary { char** contents; int size; } Dictionary; /* get_flag_from_argument() * ------------------------ * Gets the flag from the given argument * * argument: the argument * * Returns: the flag */ char* get_flag_from_argument(char* argument); /* add_to_used_flags() * --------------------- * Adds the given flag to an array of already used flags, also checks if * the flag has been used before within the array. * * flag: the given flag to add to the array * usedFlags: the array containing the already contained flags, assumes * each word is of length 5 including the null terminator. * usedFlagIndex: the current index of "usedFlags". * * Returns: 1 if the function completes successfully, 0 otherwise. */ int add_to_used_flags(char* flag, char usedFlags[MAX_FLAGS][5], int* usedFlagIndex); /* check_valid_value() * -------------------------- * Check if the entire value given is of an integer * * value: the value to check * * Returns: 0 if invalid, 1 if valid */ int check_valid_value(char* value); /* update_file_path_from_value() * ----------------------------- * Updates the filePath pointer to point at the new parsed filepath from the * argument. * * filePath: pointer to the string for the filePath * argument: what to update the filepath to */ void update_file_path_from_argument(char** filePath, char* argument); /* get_valid_command_arguments() * --------------------------- * Parses the given set of flags parsed on the command line and updates * variables "wordLength", "maxGuesses" and "filepath". * * argc: the amount of parsed arguments * argv: the array containing strings of all parsed arguments * wordLength: pointer to update for the wordLength flag '-len' * maxGuesses: pointer to update for the maxGuesses flag '-max' * filePath: pointer to update the filepath to the dictionary * * Returns: * 0: * - the flag parsed has been seen before in the command * - the flag does not have an associated value * - the flag value is NaN or not within 3 and 9 * - the flag is not a recognised flag * - an argument is parsed without a dash and is not at the end of the command * 1: * - the above is not true, and hence the function completed successfully * * Exits: if strcpy fails at any point during this function */ int get_valid_command_arguments(int argc, char** argv, int* wordLength, int* maxGuesses, char** filePath); /* check_invalid_word() * -------------------- * Checks if a word is invalid * * word: the word to check * wordLength: the length the word needs to be * * Returns: * 0: if the word is valid * 1: if the word is not the required length * 2: if the word has characters that are not alphas */ int check_invalid_word(char* word, int wordLength); /* free_dictionary() * ----------------- * Frees all allocated memory for the dictionary, including its contents * * dictionary: the dictionary to free from memory */ void free_dictionary(Dictionary* dictionary); /* insert_word_into_dictionary() * ----------------------------- * Reallocate space for the dictionary, allocate space for word and then * instert it into the dictionary * * dictionary: the dictionary to insert the word into * word: the word to insert into the dictionary */ void insert_word_into_dictionary(Dictionary* dictionary, char* word); /* get_new_dictionary() * -------------------- * Creates a new dictionary and allocates the needed space for it * * Returns: the new dictionary */ Dictionary get_new_dictionary(void); /* get_dictionary_from_buffer() * ---------------------------- * Creates a dictionary based on the parsed file buffer * * dictionaryFile: the buffer containing newline seperated words for the * dictionary * * Returns: the dictionary made from the buffer */ Dictionary get_dictionary_from_buffer(FILE* dictionaryFile); /* get_dictionary_words_of_length() * -------------------------------- * Makes a new dictionary from an old containing only words of the given * length * * dictionary: the dictionary containing all of the words * wordLength: the length of the words to be extracted * * Returns: the dictionary containing only words of given length */ Dictionary get_dictionary_words_of_length(Dictionary dictionary, int wordLength); /* check_word_in_dictionary() * -------------------------- * Checks if the supplied word is in the supplied dictionary * * dictionary: the dictionary to check * word: the word to check if in dictionary * * Returns: 0 if it is not, 1 if it is */ int check_word_in_dictionary(Dictionary dictionary, char* word); /* get_blank_wordle() * ------------------ * Gets a string that only contains '-' of given length * For example, with a length of 5, the string will be "-----" * * wordLength: the length of the blank word * * Returns: the blank word * * Reference: Inspired by https://stackoverflow.com/questions/12352682 */ char* get_blank_wordle(int wordLength); /* get_wordle_format() * ------------------- * Get the guess in the format of wordle * * guessedWord: the word the user guessed * answer: the correct word * * Returns: the word in the format of wordle */ char* get_wordle_format(char* guessedWord, char* answer); /* string_lowercase() * ------------------ * Converts a string to its lowercase varient * * string: the string to convert */ void string_lowercase(char* string); /* get_guessed_word_from_input() * ----------------------------- * Prompt for a guess word and return the guessed word if it is valid * * Returns: * NULL: if EOF * "a": if the word is blank * the input if not the above */ char* get_guessed_word_from_input(void); /* prompt_invalid_guess() * ---------------------- * Prompt if the guess was invalid and the correct message for the type of * invalidity * * invalidType: the type of invalid guess * wordLength: the length of the answer */ void prompt_invalid_guess(int invalidType, int wordLength); /* print_attempt_prompt() * ---------------------- * Print the attempt with the amount of guesses remaing and length of word * * guessesRemaining: the amount of guesses remaining * wordLength: the length of the answer */ void print_attempt_prompt(int guessesRemaining, int wordLength); /* game_loop() * ----------- * The gameplay loop for the game * * wordLength: the maximum length of a word to be given * maxGuesses: the maximum number of guesses the user has * * Returns: * 0: if the correct word was guessed * 3: if the user failed */ int game_loop(int wordLength, int maxGuesses, char* answer, Dictionary dictionary); /* get_answer() * ------------ * Gets and allocates a random word as the answer using get_random_word() * * answer: pointer to the answer * wordLength, the word length if getting a random word */ void get_answer(char** answer, int wordLength); #endif