diff --git a/ui/ui.c b/ui/ui.c index 233c24737acecd8af746b3402a13d8dc6b5fae30..44eef2d05db0cf39b8ced8d1e727e53ebbf36bab 100644 --- a/ui/ui.c +++ b/ui/ui.c @@ -186,7 +186,7 @@ void show_gameboard(int tries_count, int word_length, char **tries, int **valida // Draw remaning try letters placeholder for (size_t j = 0; j < word_length - strlen(tries[i]); j++) - mvaddstr(GAMEBOARD_Y_OFFSET + i, TERM_MID_COLS + word_length - 2 - (j * 2), "_ "); + mvaddstr(GAMEBOARD_Y_OFFSET + i, TERM_MID_COLS + (word_length / 2) - (j * 2), " _"); } refresh(); } \ No newline at end of file diff --git a/wordle/wordle.c b/wordle/wordle.c index 4a03714e31a8d75f7a4cb6a5b08f0366730b0926..41dd5f766d95aea86f12c33b98f31fd14febe2c8 100644 --- a/wordle/wordle.c +++ b/wordle/wordle.c @@ -11,35 +11,78 @@ int **validations; int current_try_id = 0; int current_try_letter_id = 0; +/** + * @brief Initialize the game + */ +void initialize_game() { + chosen_word = "SALUT"; // Must be randomly picked in a dictionary + + tries = calloc(TRIES_COUNT, sizeof(char *)); + validations = malloc(sizeof(int *) * TRIES_COUNT); + + for (int i = 0; i < TRIES_COUNT; i++) { + validations[i] = calloc(WORD_LENGHT + 1, sizeof(int)); + tries[i] = calloc(WORD_LENGHT + 1, sizeof(char)); // +1 because of \0 + } +} + /** * @brief Terminate a game */ -void terminate_game() { _game_finished = true; } +void terminate_game() { + _game_finished = true; + + for (int i = 0; i < TRIES_COUNT; i++) { + free(tries[i]); + free(validations[i]); + } + + free(tries); + free(validations); +} /** - * @brief Add a letter to the current try + * @brief Condition(s) to lose a game * - * @param letter + * @return true + * @return false */ -void add_letter_to_try(char letter) { - tries[current_try_id][current_try_letter_id] = letter; - current_try_letter_id += 1; +bool lose_condition() { return (current_try_id > TRIES_COUNT - 1); } + +/** + * @brief Render the game for the selected gamemode + */ +void render_game() { + switch (gamemode) { + case GAMEMODE_SOLO: + printw_center("Solo", 5); + break; + + case GAMEMODE_1_V_1: + printw_center("Player 1", 5); + break; + + case GAMEMODE_COMPUTER: + printw_center("Computer assisted", 5); + break; + } + + show_gameboard(TRIES_COUNT, WORD_LENGHT, tries, validations); } /** - * @brief Check if the given letter is a lowercase letter only + * @brief Check if the given letter is a lowercase letter only (ASCII code) * * @param key * @return true * @return false */ -bool validate_letter(int key) { return (key >= 97 && key <= 122); } +bool validate_letter(int key) { return (islower(key) || isupper(key)); } /** * @brief Validate the last guess - * */ -int *validate_last_guess(char answer[WORD_LENGHT], char try[WORD_LENGHT]) { +int *validate_guess(char answer[WORD_LENGHT], char try[WORD_LENGHT]) { int a[WORD_LENGHT] = {0, 2, 0, 1, 0}; int *validation = calloc(WORD_LENGHT, sizeof(int)); @@ -68,7 +111,7 @@ void handle_controls(int key) { if (strlen(tries[current_try_id]) < WORD_LENGHT) break; - int *tmp = validate_last_guess(chosen_word, tries[current_try_id]); + int *tmp = validate_guess(chosen_word, tries[current_try_id]); for (int i = 0; i < WORD_LENGHT; i++) validations[current_try_id][i] = tmp[i]; free(tmp); @@ -85,58 +128,33 @@ void handle_controls(int key) { void set_gamemode(int menu_gamemode) { gamemode = menu_gamemode; } void launch_game() { - chosen_word = "SALUT"; - - tries = calloc(TRIES_COUNT, sizeof(char *)); - validations = malloc(sizeof(int *) * TRIES_COUNT); - - for (int i = 0; i < TRIES_COUNT; i++) { - validations[i] = calloc(WORD_LENGHT + 1, sizeof(int)); - tries[i] = calloc(WORD_LENGHT + 1, sizeof(char)); // +1 because of \0 - } + initialize_game(); while (!game_finished()) { // Guard clause - if (current_try_id > TRIES_COUNT - 1) { + if (lose_condition()) { terminate_game(); continue; } // Render - switch (gamemode) { - case GAMEMODE_SOLO: - printw_center("Solo", 5); - break; - - case GAMEMODE_1_V_1: - printw_center("Player 1", 5); - break; - - case GAMEMODE_COMPUTER: - printw_center("Computer assisted", 5); - break; - } - - show_gameboard(TRIES_COUNT, WORD_LENGHT, tries, validations); + render_game(); - // Next letter + // Key handling + // || Need to check letter by letter every time to be able to continue using + // || shortcut keys like Ctrl+h during a guess. int key = getch(); if (validate_letter(key)) { - if (current_try_letter_id < WORD_LENGHT) - add_letter_to_try((char)key - 32); // Offset letter to only put upercase + if (current_try_letter_id < WORD_LENGHT) { + tries[current_try_id][current_try_letter_id] = toupper(key); + current_try_letter_id += 1; + } } handle_controls(key); refresh(); } - - for (int i = 0; i < TRIES_COUNT; i++) { - free(tries[i]); - free(validations[i]); - } - free(tries); - free(validations); } bool game_finished() { return _game_finished; } \ No newline at end of file diff --git a/wordle/wordle.h b/wordle/wordle.h index 01882a2c9052ed2de6dc84fe8e298b766b00e629..40167569623de27a47a60675688662f47da4dbd6 100644 --- a/wordle/wordle.h +++ b/wordle/wordle.h @@ -2,7 +2,9 @@ #define WORDLE_H_ #include "../ui/ui.h" +#include <ctype.h> #include <stdbool.h> +#include <string.h> // Gamemodes #define GAMEMODE_SOLO 0