cordle/src/game.c

115 lines
3.2 KiB
C
Raw Normal View History

2025-10-06 13:58:25 +00:00
//
// Created by Gregory Gauthier on 06/10/2025.
//
/* game.c - Game logic implementation */
#include "../include/game.h"
#include "../include/ui.h"
#include <string.h>
#include <ctype.h>
/* Initialize game state */
void init_game(GameState* game) {
int i, j;
game->word_count = 0;
game->target_word[0] = '\0';
game->guess_count = 0;
game->current_guess[0] = '\0';
game->current_guess_length = 0;
game->game_over = 0;
game->won = 0;
/* Initialize letter status to unused */
for (i = 0; i < 26; i++) {
game->letter_status[i] = STATUS_UNUSED;
}
/* Clear guesses */
for (i = 0; i < MAX_GUESSES; i++) {
game->guesses[i][0] = '\0';
for (j = 0; j < WORD_LENGTH; j++) {
game->guess_colors[i][j] = COLOR_DEFAULT;
}
}
}
/* Check guess against target word */
void check_guess(GameState* game, const char* guess, int* colors) {
char target_copy[WORD_LENGTH + 1];
char guess_copy[WORD_LENGTH + 1];
int i, j;
int target_used[WORD_LENGTH] = {0};
strcpy(target_copy, game->target_word);
strcpy(guess_copy, guess);
/* Ensure uppercase */
for (i = 0; i < WORD_LENGTH; i++) {
guess_copy[i] = toupper(guess_copy[i]);
}
/* Initialize all as absent */
for (i = 0; i < WORD_LENGTH; i++) {
colors[i] = COLOR_ABSENT;
}
/* First pass: mark correct positions */
for (i = 0; i < WORD_LENGTH; i++) {
if (guess_copy[i] == target_copy[i]) {
colors[i] = COLOR_CORRECT;
target_used[i] = 1;
game->letter_status[guess_copy[i] - 'A'] = STATUS_CORRECT;
}
}
/* Second pass: mark present but wrong position */
for (i = 0; i < WORD_LENGTH; i++) {
if (colors[i] == COLOR_ABSENT) {
for (j = 0; j < WORD_LENGTH; j++) {
if (!target_used[j] && guess_copy[i] == target_copy[j]) {
colors[i] = COLOR_PRESENT;
target_used[j] = 1;
if (game->letter_status[guess_copy[i] - 'A'] != STATUS_CORRECT) {
game->letter_status[guess_copy[i] - 'A'] = STATUS_PRESENT;
}
break;
}
}
/* If still absent, mark letter as not in word */
if (colors[i] == COLOR_ABSENT) {
if (game->letter_status[guess_copy[i] - 'A'] == STATUS_UNUSED) {
game->letter_status[guess_copy[i] - 'A'] = STATUS_ABSENT;
}
}
}
}
}
/* Process a guess */
int make_guess(GameState* game, const char* guess) {
char upper_guess[WORD_LENGTH + 1];
int i;
if (strlen(guess) != WORD_LENGTH) {
return 0;
}
strcpy(upper_guess, guess);
for (i = 0; i < WORD_LENGTH; i++) {
upper_guess[i] = toupper(upper_guess[i]);
}
strcpy(game->guesses[game->guess_count], upper_guess);
check_guess(game, guess, game->guess_colors[game->guess_count]);
game->guess_count++;
if (strcmp(upper_guess, game->target_word) == 0) {
game->game_over = 1;
game->won = 1;
} else if (game->guess_count >= MAX_GUESSES) {
game->game_over = 1;
game->won = 0;
}
return 1;
}