-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathckboggle.c
154 lines (141 loc) · 4.06 KB
/
ckboggle.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*--------------------------------------------------------------*
* Find words in a two-dimensional array of letters moving *
* up, down, left, right or diagonally. *
*--------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define XMAX 4
#define YMAX 4
#define MAXPOS (XMAX*YMAX)
#define NONE (-1)
typedef int bits; /* must be at least MAXPOS bits */
#define isset(m,b) ((m)&(1<<(b)))
#define adbit(m,b) ((m)|(1<<(b)))
#define stbit(m,b) (m)|=(1<<(b))
int first[26]; /* first pos containing letter */
int next[MAXPOS]; /* next pos containing same letter */
bits move[MAXPOS]; /* isset(move[x],y) if can move x->y */
#define FAIL 0
#define REDO 1
#define EXIT 2
/*--------------------------------------------------------------*
* recursively look for a word *
*--------------------------------------------------------------*/
int boggle(char *word, /* word to look for */
int pos, /* current position in array */
bits used) /* positions visited already */
{
int c, p;
while (c = *word++, ! isalpha(c)) { /* ignore punctuation */
if (c == '\0') return EXIT; /* end of string, ok! */
}
p = first[toupper(c) - 'A']; /* first square containing letter */
if (p == NONE) return FAIL; /* letter not in square */
for (; p != NONE; p=next[p]) {
if (pos == NONE || isset(move[pos],p)) { /* can move to square */
if (! isset(used,p)) { /* not already used */
switch (boggle(word, p, adbit(used,p))) { /* recurse on remainder */
case FAIL: return FAIL; /* later letter impossible */
case EXIT: return EXIT; /* succeeded */
}
}
}
}
return REDO; /* no luck here */
}
void makemap(char *letters)
{
int i,j,p,c;
char *s = letters;
for (i=0; i<26; i++) {
first[i] = NONE;
}
for (i=0; i<MAXPOS; i++) {
next[i] = NONE;
move[i] = 0;
}
p = 0;
for (j=0; j<YMAX; j++) {
for (i=0; i<XMAX; i++,p++) {
if (j>0) {
if (i>0) stbit(move[p],p-XMAX-1);
stbit(move[p],p-XMAX);
if (i<XMAX-1) stbit(move[p],p-XMAX+1);
}
if (i>0) stbit(move[p],p-1);
if (i<XMAX-1) stbit(move[p],p+1);
if (j<YMAX-1) {
if (i>0) stbit(move[p],p+XMAX-1);
stbit(move[p],p+XMAX);
if (i<XMAX-1) stbit(move[p],p+XMAX+1);
}
}
}
p = 0;
for (j=0; j<YMAX; j++) {
for (i=0; i<XMAX; i++,p++) {
c = *s++;
if (c == '\0') {
fprintf(stderr, "Too few letters\n");
exit(1);
}else if (! isalpha(c)) {
fprintf(stderr, "Non-alphabetic character %c\n", c);
exit(1);
}
c = toupper(c) - 'A';
next[p] = first[c];
first[c] = p;
}
}
if (*s != '\0') {
fprintf(stderr, "Too many letter\n");
exit(1);
}
}
#define MAXTEST 6
char *test[6] = {
"the","cat","sat","on","a","mat"};
/*--------------------------------------------------------------*
* Main program *
*--------------------------------------------------------------*/
int main(void)
{
char line[256];
char letters[256];
char name[40];
FILE *file;
int i;
printf("Boggle square size is %d lines of %d characters\n", YMAX, XMAX);
strcpy(letters, "");
for (i=0; i<YMAX; i++) {
printf("Enter line %d :", i+1);
gets(line);
if (strlen(line) != XMAX) {
fprintf(stderr, "Wrong length of line\n");
exit(1);
}
strcat(letters, line);
}
makemap(letters);
file = fopen("apet", "r");
if (file == NULL) {
fprintf(stderr, "Could not open %s\n", name);
exit(1);
}
for (; fgets(line, 256, file); ) {
if (boggle(line, NONE, 0) != EXIT) {
printf("-- %s", line);
}
}
fclose(file);
/*
for (i=0; i<MAXTEST; i++) {
if (boggle(test[i], NONE, 0) == EXIT) {
printf("-- %s\n", test[i]);
}
}
*/
return 0;
}