]> git.cworth.org Git - wordgame/commitdiff
Add new rack game as well
authorCarl Worth <cworth@raht.cworth.org>
Sat, 23 Sep 2006 10:47:48 +0000 (03:47 -0700)
committerCarl Worth <cworth@raht.cworth.org>
Sat, 23 Sep 2006 10:47:48 +0000 (03:47 -0700)
.gitignore
Makefile
rack.c [new file with mode: 0644]
word-game.c

index 0d0835b6f584b1fcdf7712c6050d5b295e2ab11e..f3b3bf4c5de10544ed80ebb39cef8b40ef91163f 100644 (file)
@@ -1,5 +1,6 @@
 Makefile.dep
 drill2
 grid
+rack
 *.o
 *~
index dd05adedfd0b820886ecdbadf3be1551b1e2a48a..b8f940da2367b9a16fc3549dbdb33d5a2a579a93 100644 (file)
--- 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 (file)
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 <string.h>
+#include <ctype.h>
+#include <sys/time.h>
+#include <time.h>
+
+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;
+}
index 8c9af9a59071feda5567f90cfecea9f014f32083..e12787d4e8abc33a62f1b99a6174eddd69f7b894 100644 (file)
@@ -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);