]> git.cworth.org Git - wordgame/blob - rack.c
Abstract bag code from rack into new bag.c
[wordgame] / rack.c
1 /*
2  * Copyright © 2006 Carl Worth
3  *
4  * This program is free software; you can redistribute it and\/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2, or (at your option)
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA."
17  */
18
19 #include "word-game.h"
20
21 #include <string.h>
22 #include <ctype.h>
23 #include <sys/time.h>
24 #include <time.h>
25
26 static const char *subanagram_anagram;
27 static char subanagram_enumerate_word[WORD_GAME_MAX_WORD_LENGTH];
28 static dict_t *subanagram_enumerate_answers;
29
30 static void
31 subanagram_enumerate (dict_cursor_t      cursor,
32                       uint8_t            seen)
33 {
34     char c;
35     unsigned int i, last;
36     uint8_t next_seen;
37
38     if (cursor == DICT_CURSOR_NIL)
39         return;
40
41     if (DICT_ENTRY_IS_WORD (dict_cursor_resolve (cursor)))
42         dict_add_word (subanagram_enumerate_answers, subanagram_enumerate_word);
43
44     last = strlen (subanagram_enumerate_word);
45
46     for (i = 0; i < strlen (subanagram_anagram); i++) {
47         if (seen & (1 << i))
48             continue;
49         next_seen = seen | (1 << i);
50         c = subanagram_anagram[i];
51         if (c == '?' || c == '_') {
52             for (c = 'a'; c <= 'z'; c++) {
53                 subanagram_enumerate_word[last] = c;
54                 subanagram_enumerate (dict_cursor_next (cursor, c), next_seen);
55             }
56         } else {
57             subanagram_enumerate_word[last] = c;
58             subanagram_enumerate (dict_cursor_next (cursor, c), next_seen);
59         }
60         subanagram_enumerate_word[last] = '\0';
61     }
62 }
63
64 static void
65 subanagram_expand (const char *anagram, dict_t *dict, dict_t *answers)
66 {
67     subanagram_anagram = anagram;
68     memset (subanagram_enumerate_word, '\0', WORD_GAME_MAX_WORD_LENGTH);
69     subanagram_enumerate_answers = answers;
70
71     subanagram_enumerate (dict_root (dict), 0);
72 }
73
74 static int
75 character_compare (const void *_a,
76                    const void *_b)
77 {
78     const char *a = _a;
79     const char *b = _b;
80
81     if (*a == '?')
82         return 1;
83     if (*b == '?')
84         return -1;
85     return *a - *b;
86 }
87
88 int
89 main (void)
90 {
91     dict_t dict, solution;
92     struct timeval tv;
93     bag_t bag;
94     char rack[8];
95
96     gettimeofday (&tv, NULL);
97     srand (tv.tv_sec ^ tv.tv_usec);
98
99     bag_init (&bag);
100     bag_shuffle (&bag);
101
102     memcpy (rack, bag.tiles, 7);
103     rack[7] = '\0';
104     qsort (rack, 7, 1, character_compare);
105
106     dict_init (&dict);
107     dict_add_words_from_file (&dict, "words.txt");
108
109     dict_init (&solution);
110     subanagram_expand (rack, &dict, &solution);
111
112     word_game_play (rack, &dict, &solution, 0);
113
114     dict_fini (&solution);
115     dict_fini (&dict);
116
117     return 0;
118 }