diff --git a/terdle.c b/terdle.c index bf4c3a0..30eaa39 100644 --- a/terdle.c +++ b/terdle.c @@ -121,46 +121,41 @@ result_set_t guess_match(word_t answer_word, word_t guess_word) { /* returns whether or not the game was won */ typedef struct wordle_game { word_t target; - uint32_t turn_limit; + uint32_t turn_number, turn_limit; int (*guess_fn)(word_t *, void *); void *guess_fn_data; void (*display_fn)(result_set_t, void *); void *display_fn_data; } wordle_game_t; -bool play_game(wordle_game_t *game) { - for (uint32_t turn = 1; turn <= game->turn_limit; ++turn) { - word_t guess = 0; - if (game->guess_fn(&guess, game->guess_fn_data) != 0) { - printf("guesser failure\n"); - } - result_set_t result_set = guess_match(game->target, guess); - game->display_fn(result_set, game->display_fn_data); - if (guess == game->target) { - return true; - } - } - return false; -} - struct linebuf { char *buffer; size_t capacity; }; +/* the guess function returns 0 on success and something else on failure */ int term_guess(word_t *word, void *data) { struct linebuf *linebuf = data; while (true) { + fputs("guess> ", stdout); ssize_t bytes_read = getline(&(linebuf->buffer), &(linebuf->capacity), stdin); + /* if the input is closed, there's no way to recover. fail out */ if (bytes_read == -1) { return -1; } char *buf_end = linebuf->buffer; strsep(&buf_end, "\n"); - if (strchr(linebuf->buffer, '\0') - linebuf->buffer == WORD_LENGTH) { + size_t length = strchr(linebuf->buffer, '\0') - linebuf->buffer; + /* some basic error checking around length */ + if (length == WORD_LENGTH) { *word = strtoword(linebuf->buffer); return 0; } else { + if (length > WORD_LENGTH) { + fprintf(stderr, "error: too long\n"); + } else { + fprintf(stderr, "error: too short\n"); + } continue; } } @@ -168,6 +163,7 @@ int term_guess(word_t *word, void *data) { void term_display(result_set_t result_set, void *ignored) { (void) ignored; + fputs("result ", stdout); for (size_t i = 0; i < WORD_LENGTH; ++i) { switch (rs_get(result_set, i)) { case RES_BLACK: @@ -184,10 +180,25 @@ void term_display(result_set_t result_set, void *ignored) { break; } } - fputs(" result", stdout); fputc('\n', stdout); } +bool play_game(wordle_game_t *game) { + for (game->turn_number = 1; game->turn_number <= game->turn_limit; ++game->turn_number) { + word_t guess = 0; + if (game->guess_fn(&guess, game->guess_fn_data) != 0) { + printf("guesser failure\n"); + break; + } + result_set_t result_set = guess_match(game->target, guess); + game->display_fn(result_set, game->display_fn_data); + if (guess == game->target) { + return true; + } + } + return false; +} + int main(int argc, char *argv[]) { struct linebuf lb = { .capacity = 6, @@ -195,13 +206,18 @@ int main(int argc, char *argv[]) { }; wordle_game_t game = { .target = strtoword("total"), + .turn_number = 0, .turn_limit = 6, .guess_fn = term_guess, .guess_fn_data = &lb, .display_fn = term_display, .display_fn_data = NULL, }; - int x = play_game(&game); - printf("endgame %d\n", x); + bool won = play_game(&game); + if (won) { + fprintf(stdout, "YOU WIN %d/%d\n", game.turn_number, game.turn_limit); + } else { + fprintf(stdout, "YOU LOSE\n"); + } return 0; }