From 0cb3ed6bc1a5fc1c4e88b0785fd6eb11aa7ca7d5 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Sat, 23 Sep 2006 03:47:48 -0700 Subject: [PATCH] Add new rack game as well --- .gitignore | 1 + Makefile | 2 +- rack.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++ word-game.c | 6 +-- 4 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 rack.c diff --git a/.gitignore b/.gitignore index 0d0835b..f3b3bf4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ Makefile.dep drill2 grid +rack *.o *~ diff --git a/Makefile b/Makefile index dd05ade..b8f940d 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ WGCFLAGS=-Wall -Wextra -Wmissing-prototypes -Wno-unused-parameter -PROGRAMS=grid drill2 +PROGRAMS=grid drill2 rack all: $(PROGRAMS) LIBRARY=dict.o word-game.o diff --git a/rack.c b/rack.c new file mode 100644 index 0000000..fa0cdc1 --- /dev/null +++ b/rack.c @@ -0,0 +1,141 @@ +/* + * Copyright © 2006 Carl Worth + * + * This program is free software; you can redistribute it and\/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA." + */ + +#include "word-game.h" + +#include +#include +#include +#include + +char bag_orig[101] = +"AAAAAAAAABBCCDDDDEEEEEEEEEEEEFFGGGHHIIIIIIIIIJKLLLL" +"MMNNNNNNOOOOOOOOPPQRRRRRRSSSSTTTTTTUUUUVVWWXYYZ??"; + +static int +rand_within (int num_values) +{ + return (int) ((double) num_values * (rand() / (RAND_MAX + 1.0))); +} + +static void +shuffle (char *array, int length) +{ + int i, r, tmp; + + for (i = 0; i < length; i++) + { + r = i + rand_within (length - i); + tmp = array[i]; + array[i] = array[r]; + array[r] = tmp; + } +} + +static const char *subanagram_anagram; +static char subanagram_enumerate_word[WORD_GAME_MAX_WORD_LENGTH]; +static dict_t *subanagram_enumerate_answers; + +static void +subanagram_enumerate (dict_cursor_t cursor, + uint8_t seen) +{ + char c; + unsigned int i, last; + uint8_t next_seen; + + if (cursor == DICT_CURSOR_NIL) + return; + + if (DICT_ENTRY_IS_WORD (dict_cursor_resolve (cursor))) + dict_add_word (subanagram_enumerate_answers, subanagram_enumerate_word); + + last = strlen (subanagram_enumerate_word); + + for (i = 0; i < strlen (subanagram_anagram); i++) { + if (seen & (1 << i)) + continue; + next_seen = seen | (1 << i); + c = subanagram_anagram[i]; + if (c == '?' || c == '_') { + for (c = 'a'; c <= 'z'; c++) { + subanagram_enumerate_word[last] = c; + subanagram_enumerate (dict_cursor_next (cursor, c), next_seen); + } + } else { + subanagram_enumerate_word[last] = c; + subanagram_enumerate (dict_cursor_next (cursor, c), next_seen); + } + subanagram_enumerate_word[last] = '\0'; + } +} + +static void +subanagram_expand (const char *anagram, dict_t *dict, dict_t *answers) +{ + subanagram_anagram = anagram; + memset (subanagram_enumerate_word, '\0', WORD_GAME_MAX_WORD_LENGTH); + subanagram_enumerate_answers = answers; + + subanagram_enumerate (dict_root (dict), 0); +} + +static int +character_compare (const void *_a, + const void *_b) +{ + const char *a = _a; + const char *b = _b; + + if (*a == '?') + return 1; + if (*b == '?') + return -1; + return *a - *b; +} + +int +main (void) +{ + dict_t dict, solution; + struct timeval tv; + char bag[100], rack[8]; + + gettimeofday (&tv, NULL); + srand (tv.tv_sec ^ tv.tv_usec); + + memcpy (bag, bag_orig, 100); + shuffle (bag, 100); + + memcpy (rack, bag, 7); + rack[7] = '\0'; + qsort (rack, 7, 1, character_compare); + + dict_init (&dict); + dict_add_words_from_file (&dict, "words.txt"); + + dict_init (&solution); + subanagram_expand (rack, &dict, &solution); + + word_game_play (rack, &dict, &solution, 0); + + dict_fini (&solution); + dict_fini (&dict); + + return 0; +} diff --git a/word-game.c b/word-game.c index 8c9af9a..e12787d 100644 --- a/word-game.c +++ b/word-game.c @@ -82,7 +82,7 @@ word_game_play (const char *puzzle, for (i=0; i < 17; i++) possible_total += possible[i]; - printf ("%s\n\n", puzzle); + printf ("%s\n", puzzle); just_saw_puzzle = TRUE; remaining = time_limit_seconds; @@ -105,7 +105,7 @@ word_game_play (const char *puzzle, break; if (strlen (response) == 0) { if (! just_saw_puzzle) { - printf ("%s\n\n", puzzle); + printf ("%s\n", puzzle); just_saw_puzzle = TRUE; } else { for (i = 2; i <= 17; i++) @@ -146,7 +146,7 @@ word_game_play (const char *puzzle, } } while (remaining > 0); - printf ("%s\n\n", puzzle); + printf ("%s\n", puzzle); printf ("Words you found:\n"); dict_print_by_length_if (answers, seen_predicate); -- 2.43.0