static char sccsid
[] = "@(#)boggle.c 4.1 12/24/82";
/* parameters defined in terms of above */
/* word being searched for */
/* tty and process control */
int timeint
[] = {60,60,50,7,1,1,1,0};
struct sgttyb origttyb
, tempttyb
;
/* monitoring variables */
char logbuff
[100] = {"inst\t"};
extern char *ctime(), *getlogin();
/* dictionary interface */
char defname
[] = "/usr/games/bogdict";
char *dictname
= &defname
[0];
/* structures for doing matching */
struct frame stack
[SSIZE
];
struct frame
*level
[BSIZE
+1];
/* the board and subsidiary structures */
char adj
[BSIZE
+1][BSIZE
];
"forixb", "moqabj", "gurilw", "setupl",
"cmpdae", "acitao", "slcrae", "romash",
"nodesw", "hefiye", "onudtk", "tevign",
"anedvz", "pinesh", "abilyt", "gkyleu"
/* storage for words found */
int ubotch
, ustart
, wcount
;
signal (SIGALRM
, timeout
);
signal(SIGINT
, interrupt
);
if ( ctlecho
& LCTLECH
) {
ioctl( fileno(stdin
), TIOCLBIS
, &lctlech
);
stty(fileno(stdin
), &origttyb
);
stty (fileno(stdin
), &tempttyb
);
return(wordcomp(*a
, *b
));
while (*++p
== *++q
&& isalpha(*p
)) ;
stty (fileno(stdin
), &tempttyb
);
printf(" The object of Boggle (TM Parker Bros.) is to find, within 3\n");
printf("minutes, as many words as possible in a 4 by 4 grid of letters. Words\n");
printf("may be formed from any sequence of 3 or more adjacent letters in the\n");
printf("grid. The letters may join horizontally, vertically, or diagonally.\n");
printf("However, no position in the grid may be used more than once within any\n");
printf("one word. In competitive play amongst humans, each player is given\n");
printf("credit for those of his words which no other player has found.\n");
printf(" This program is intended for people wishing to sharpen their\n");
printf("skills at Boggle. If you invoke the program with 4 arguments of 4\n");
printf("letters each, (e.g. \"boggle appl epie moth erhd\") the program forms the\n");
printf("obvious Boggle grid and lists all the words from /usr/dict/words found\n");
printf("therein. If you invoke the program without arguments, it will generate\n");
printf("a board for you, let you enter words for 3 minutes, and then tell you\n");
printf("how well you did relative to /usr/dict/words.\n");
printf(" In interactive play, enter your words separated by spaces, tabs,\n");
printf("or newlines. A bell will ring when there is 2:00, 1:00, 0:10, 0:02,\n");
printf("0:01, and 0:00 time left. You may complete any word started before the\n");
printf("expiration of time. You can surrender before time is up by hitting\n");
printf("'break'. While entering words, your erase character is only effective\n");
printf("within the current word and your line kill character is ignored.\n");
printf(" Advanced players may wish to invoke the program with 1 or 2 +'s as\n");
printf("the first argument. The first + removes the restriction that postions\n");
printf("can only be used once in each word. The second + causes a position to\n");
printf("be considered adjacent to itself as well as its (up to) 8 neighbors.\n");
printf("Hit any key to begin.\n");
stty (fileno(stdin
), &tempttyb
);
stty (fileno(stdin
), &tempttyb
);
for (i
=0; i
<BSIZE
; i
++) {
adj
[i
][i
] = super
>=2 ? 1 : 0;
adj
[i
][j
] = adj
[j
][i
] = k
;
stack
[0].parent
= &stack
[0];
for (i
=0; i
<BSIZE
; i
++) {
olink
[i
] = occurs
[c
-'a'];
for (i
=0; i
<BSIZE
; i
++) {
board
[j
] = cube
[i
][rand()%6];
putchar ((putchar(board
[i
*N
+j
]) == 'q') ? 'u' : ' ');
/* input: numsame = # chars same as last word */
/* output: numsame = # same chars for next word */
/* word in wbuff[0]...wbuff[wlength-1] */
while ((*p
++ = c
= getc(dict
)) != EOF
&& isalpha(c
)) ;
register char *p
, *q
, *r
;
while (*timept
>0 && (isspace(c
=getchar()) || c
==EOF
));
while (!isspace(c
= getchar())) {
if (c
== origttyb
.sg_erase
) {
for (p
=q
; p
<freesp
&& r
<&wbuff
[BSIZE
]; )
if (islower(c
= *p
++) && (*r
++ = *q
++ = c
) == 'q' && *p
== 'u')
*word
[wcount
-1] = ways
>=10 ? '*' : '0'+ways
;
/* store (wbuff, ways) in next slot in space */
*freesp
++ = ways
>=10 ? '*' : '0'+ways
;
for (i
=1; i
<= wlength
; i
++)
/* print (wbuff, ways) on terminal */
wbuff
[0] = ways
>=10 ? '*' : '0'+ways
;
for (q
=p
+1; isalpha(*q
); ) {
if (column
> LWIDTH
-CWIDTH
) {
newcol
= ((column
+CWIDTH
)/CWIDTH
)*CWIDTH
;
while (((column
+8)/8)*8 <= newcol
) {
column
= ((column
+8)/8)*8;
while (column
< newcol
) {
both
= donly
= uonly
= column
= d
= 0;
c
= u
<wcount
? wordcomp (word
[d
], word
[u
]) : -1;
/* dict and user found same word */
printf("\t\t\t we both found:\n");
/* dict found it, user didn't */
/* user found it, dict didn't */
printf("\n\t\t\tI alone found these:\n");
printf("\n\t\t\tyou alone found these:\n");
for (u
=ustart
; u
<wcount
; u
++)
printf("\n\t\t\t you botched these:\n");
for (u
=ubotch
; u
<ustart
; u
++)
register struct frame
*leaf
;
register struct frame
*node
;
for (p
= &present
[0]; p
< &present
[BSIZE
]; *p
++ = 0);
for (node
= leaf
; present
[node
->place
]++ == 0; node
= node
->parent
);
evalboard (getword
, putword
)
int (*getword
)(), (*putword
)();
register struct frame
*top
;
struct frame
*parent
, *lastparent
;
level
[l
+1] = lastparent
= top
;
/* wbuff[1]...wbuff[l] have been matched */
/* level[0],...,level[l] of tree built */
if (wlength
>= 3 && (q
= numways(level
[l
], top
)) != 0) {
if ((fo
= occurs
[wbuff
[++l
]-'a']) == BSIZE
)
/* wbuff[1]...wbuff[l-1] have been matched */
/* level[0],...,level[l-1] of tree built */
for (parent
=level
[l
-1]; parent
<lastparent
; parent
++) {
padj
= &adj
[parent
->place
][0];
for (q
=fo
; q
!=BSIZE
; q
=olink
[q
])
if (++top
>= &stack
[SSIZE
]) {
printf("stack overflow\n");
/* were any nodes added? */
/* advance until first l characters of next word are different */
while (numsame
>= l
&& (*getword
)()) ;
gtty (fileno(stdin
), &origttyb
);
signal (SIGINT
, interrupt
);
if (argv
[0][0] != 'a' && (logfile
= open("/usr/games/boglog", 1)) >= 0) {
logloc
= lseek(logfile
, 0L, 2);
write(logfile
, &logbuff
[0], p
-&logbuff
[1]);
if ((dict
= fopen(dictname
, "r")) == NULL
) {
printf("can't open %s\n", dictname
);
while ( argc
> 1 && ( argv
[1][0] == '+' || argv
[1][0] == '-' ) ) {
while(*(argv
[1]++) == '+')
if ( argv
[1][0] == '-' ) {
timeint
[0] = 60 * ( atol( &argv
[1][1] ) - 2 );
printf("usage: boggle [+[+]] [row1 row2 row3 row4]\n");
for (i
=0; i
<BSIZE
; i
++) {
board
[i
] = c
= argv
[row(i
)+1][col(i
)];
evalboard(getdword
, tputword
);
strncpy(&logbuff
[0], "eval", 4);
lseek(logfile
, logloc
, 0);
write(logfile
, &logbuff
[0], 4);
tempttyb
.sg_flags
|= CBREAK
;
if ( ioctl( fileno(stdin
), TIOCLGET
, &ctlecho
) == 0 ) {
if ( ctlecho
& LCTLECH
) {
ioctl( fileno(stdin
), TIOCLBIC
, &lctlech
);
while (setjmp(env
) == 0) {
if (pipe(&pipefd
[0]) != 0) {
printf("can't create pipe\n");
word
[0] = freesp
= &space
[0];
if ((master
= fork()) == 0) {
signal(SIGALRM
, timeout
);
evalboard(getuword
, aputuword
);
qsort(&word
[0], wcount
, sizeof (int), compare
);
if (i
==0 || wordcomp(word
[i
], word
[i
-1])!=0) {
write (pipefd
[1], word
[i
], p
-word
[i
]);
evalboard(getdword
, aputword
);
while ((i
= read(pipefd
[0], freesp
, 512)) != 0) {
ustart
= ubotch
= wcount
;
sprintf(&logbuff
[0], "%4d", games
);
lseek(logfile
, logloc
, 0);
write(logfile
, &logbuff
[0], 4);
stty (fileno(stdin
), &tempttyb
);
printf("\nanother game?");
stty (fileno(stdin
), &tempttyb
);