X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=grid.c;h=cce4ab768da43dcd7f8105a7cf0f38ac9328f206;hb=fa2eccd25e634f0d2c4de088dc4a881de9cbbb50;hp=78c6c56d1370564c5165541a37f5be2192346174;hpb=17755d5a91f1470057bf2308984a25e7432bcd8a;p=wordgame diff --git a/grid.c b/grid.c index 78c6c56..cce4ab7 100644 --- a/grid.c +++ b/grid.c @@ -28,6 +28,9 @@ #include "dict.h" +/* Remember that dict reserves the 0th bit for IS_WORD */ +#define GRID_WORD_SEEN (1<<1) + char *cube_faces[16] = { "aaeeng", "abbjoo", "achops", "affkps", "aoottw", "cimotu", "deilrx", "delrvy", @@ -39,7 +42,7 @@ typedef struct _board { char letters[4][4]; /* Private, transient state used by enumerate */ - trie_t *result_trie; + dict_t *results; } board_t; int @@ -100,12 +103,15 @@ board_enumerate (board_t *board, int x, int y, int16_t seen, - string_t *word, - trie_t *dict_trie) + char *word, + dict_cursor_t dict_cursor) { char c; int dx, dy; + if (dict_cursor == DICT_CURSOR_NIL) + return; + if (x < 0 || x >= 4 || y < 0 || y >= 4 || seen & SEEN_BIT (x, y)) @@ -116,62 +122,64 @@ board_enumerate (board_t *board, seen |= SEEN_BIT (x, y); c = board->letters[y][x]; - string_append_char (word, c); - dict_trie = dict_trie->next[TRIE_CHAR_TO_INDEX (c)]; - if (dict_trie == NULL) - goto BAIL0; + word[strlen (word)] = c; + dict_cursor = dict_cursor_next (dict_cursor, c); if (c == 'q') { - string_append_char (word, 'u'); - dict_trie = dict_trie->next[TRIE_CHAR_TO_INDEX ('u')]; - if (dict_trie == NULL) - goto BAIL1; + word[strlen (word)] = 'u'; + dict_cursor = dict_cursor_next (dict_cursor, 'u'); } - if (dict_trie->flags & TRIE_FLAGS_IS_WORD) - trie_add (board->result_trie, word->s); + if (DICT_ENTRY_IS_WORD (dict_cursor_resolve (dict_cursor))) + dict_add_word (board->results, word); for (dy = -1; dy <= 1; dy++) for (dx = -1; dx <= 1; dx++) - board_enumerate (board, x + dx, y + dy, seen, word, dict_trie); + board_enumerate (board, x + dx, y + dy, seen, word, dict_cursor); - BAIL1: if (c == 'q') - string_chop (word); - BAIL0: - string_chop (word); + word [strlen (word) - 1] = '\0'; + word [strlen (word) - 1] = '\0'; } -void -board_solve (board_t *board, dict_t *dict, trie_t *solution) +static void +board_solve (board_t *board, dict_t *dict, dict_t *solution) { int x, y; int16_t seen = 0; - string_t word; + char word[17]; - board->result_trie = solution; + board->results = solution; - string_init (&word); + memset (word, '\0', 17); for (y = 0; y < 4; y++) for (x = 0; x < 4; x++) - board_enumerate (board, x, y, seen, &word, dict->trie); + board_enumerate (board, x, y, seen, word, dict_root (dict)); +} - string_fini (&word); +static bool_t +seen_predicate (dict_entry_t entry) +{ + return entry & GRID_WORD_SEEN; +} + +static bool_t +unseen_predicate (dict_entry_t entry) +{ + return ! seen_predicate (entry); } #define GAME_LENGTH (3 * 60) int main (void) { - dict_t dict; + dict_t dict, solution; board_t board; - trie_t *solution; struct timeval tv, tv_stop; int remaining, minutes, seconds; int found, missed; char prompt[7], *response; - string_t word; gettimeofday (&tv, NULL); srand (tv.tv_sec ^ tv.tv_usec); @@ -180,8 +188,8 @@ main (void) dict_add_words_from_file (&dict, "words.txt"); board_init (&board); - solution = trie_create (); - board_solve (&board, &dict, solution); + dict_init (&solution); + board_solve (&board, &dict, &solution); board_print (&board); @@ -199,16 +207,16 @@ main (void) if (strlen (response) == 0) { board_print (&board); } else { - trie_t *t; - t = trie_find (solution, response); - if (t && (t->flags & TRIE_FLAGS_IS_WORD)) { - if (t->flags & TRIE_FLAGS_SEEN) + dict_entry_t *entry; + entry = dict_lookup (&solution, response); + if (DICT_ENTRY_IS_WORD (entry)) { + if (*entry & GRID_WORD_SEEN) printf ("(repeat)\n"); else - t->flags |= TRIE_FLAGS_SEEN; + *entry |= GRID_WORD_SEEN; } else { - t = trie_find (dict.trie, response); - if (t && (t->flags & TRIE_FLAGS_IS_WORD)) + entry = dict_lookup (&dict, response); + if (DICT_ENTRY_IS_WORD (entry)) printf ("(a good word, but it's not in the puzzle)\n"); else printf ("*** %s is not a word\n", response); @@ -221,18 +229,13 @@ main (void) } while (remaining > 0); printf ("\nWords you found:\n"); - string_init (&word); - found = trie_print_seen (solution, &word); - string_fini (&word); - printf ("\n"); + found = dict_print_by_length_if (&solution, seen_predicate); printf ("\nWords you missed:\n"); - string_init (&word); - missed = trie_print_unseen (solution, &word); - string_fini (&word); + missed = dict_print_by_length_if (&solution, unseen_predicate); printf ("\n"); - printf ("\nYou found %d of %d words (%.2f%%)\n", + printf ("You found %d of %d words (%.2f%%)\n", found, found + missed, 100 * (double) found / (found + missed));