1*47854Sbostic /*- 2*47854Sbostic * Copyright (c) 1982 The Regents of the University of California. 3*47854Sbostic * All rights reserved. 4*47854Sbostic * 5*47854Sbostic * %sccs.include.proprietary.c% 621499Smckusick */ 721499Smckusick 89895Ssam #ifndef lint 921499Smckusick char copyright[] = 10*47854Sbostic "@(#) Copyright (c) 1982 The Regents of the University of California.\n\ 1121499Smckusick All rights reserved.\n"; 12*47854Sbostic #endif /* not lint */ 139895Ssam 1421499Smckusick #ifndef lint 15*47854Sbostic static char sccsid[] = "@(#)boggle.c 5.6 (Berkeley) 04/08/91"; 16*47854Sbostic #endif /* not lint */ 1721499Smckusick 189895Ssam #include <ctype.h> 199895Ssam #include <errno.h> 209895Ssam #include <setjmp.h> 219895Ssam #include <sgtty.h> 229895Ssam #include <signal.h> 239895Ssam #include <stdio.h> 2441169Sbostic #include "pathnames.h" 259895Ssam 269895Ssam /* basic parameters */ 279895Ssam #define N 4 289895Ssam #define SSIZE 200 299895Ssam #define MAXWORDS 1000 309895Ssam #define CWIDTH 10 319895Ssam #define LWIDTH 80 329895Ssam 339895Ssam /* parameters defined in terms of above */ 349895Ssam #define BSIZE (N*N) 359895Ssam #define row(x) (x/N) 369895Ssam #define col(x) (x%N) 379895Ssam 389895Ssam /* word being searched for */ 399895Ssam int wlength; 409895Ssam int numsame; 419895Ssam char wbuff [BSIZE+1]; 429895Ssam 439895Ssam /* tty and process control */ 449895Ssam extern int errno; 459895Ssam int status; 469895Ssam int pipefd[2]; 479895Ssam int super = 0; 489895Ssam int delct = 1; 499895Ssam int zero = 0; 509895Ssam int master = 1; 519895Ssam int column; 529895Ssam int *timept; 539895Ssam int timeint[] = {60,60,50,7,1,1,1,0}; 549895Ssam long timein; 559895Ssam extern long int time(); 569895Ssam struct sgttyb origttyb, tempttyb; 579895Ssam int ctlecho = 0; 589895Ssam int lctlech = LCTLECH; 599895Ssam jmp_buf env; 609895Ssam 619895Ssam /* monitoring variables */ 629895Ssam int games; 639895Ssam int logfile = -1; 649895Ssam long logloc; 659895Ssam char logbuff[100] = {"inst\t"}; 669895Ssam extern char *ctime(), *getlogin(); 679895Ssam extern long lseek(); 689895Ssam 699895Ssam /* dictionary interface */ 709895Ssam FILE *dict; 719895Ssam 729895Ssam /* structures for doing matching */ 739895Ssam struct frame { 749895Ssam struct frame *parent; 759895Ssam int place; 769895Ssam }; 779895Ssam struct frame stack [SSIZE]; 789895Ssam struct frame *level [BSIZE+1]; 799895Ssam 809895Ssam /* the board and subsidiary structures */ 819895Ssam char present [BSIZE+1]; 829895Ssam char board [BSIZE]; 839895Ssam char olink [BSIZE]; 849895Ssam char adj [BSIZE+1][BSIZE]; 859895Ssam char occurs [26]; 869895Ssam 879895Ssam /* the boggle cubes */ 889895Ssam char *cube [BSIZE] = { 899895Ssam "forixb", "moqabj", "gurilw", "setupl", 909895Ssam "cmpdae", "acitao", "slcrae", "romash", 919895Ssam "nodesw", "hefiye", "onudtk", "tevign", 929895Ssam "anedvz", "pinesh", "abilyt", "gkyleu" 939895Ssam }; 949895Ssam 959895Ssam 969895Ssam /* storage for words found */ 979895Ssam int ubotch, ustart, wcount; 989895Ssam char *word [MAXWORDS]; 999895Ssam char *freesp; 1009895Ssam char space[10000]; 1019895Ssam 1029895Ssam endline () 1039895Ssam { 1049895Ssam if (column != 0) { 1059895Ssam putchar('\n'); 1069895Ssam column = 0; 1079895Ssam } 1089895Ssam } 1099895Ssam 11046734Sbostic void 1119895Ssam timeout () 1129895Ssam { 1139895Ssam if (*timept > 0) { 1149895Ssam signal (SIGALRM, timeout); 1159895Ssam alarm(*timept++); 1169895Ssam } 1179895Ssam putchar('\007'); 1189895Ssam } 1199895Ssam 12046734Sbostic void 1219895Ssam interrupt () 1229895Ssam { 1239895Ssam signal(SIGINT, interrupt); 1249895Ssam if (delct++ >= 1) 1259895Ssam longjmp(env, 1); 1269895Ssam timept = &zero; 1279895Ssam } 1289895Ssam 1299895Ssam goodbye (stat) 1309895Ssam int stat; 1319895Ssam { 1329895Ssam if (master != 0) { 1339895Ssam wait(&status); 1349895Ssam if ( ctlecho & LCTLECH ) { 1359895Ssam ioctl( fileno(stdin), TIOCLBIS, &lctlech ); 1369895Ssam } 1379895Ssam stty(fileno(stdin), &origttyb); 1389895Ssam } 1399895Ssam exit(stat); 1409895Ssam } 1419895Ssam 1429895Ssam clearscreen () 1439895Ssam { 1449895Ssam stty (fileno(stdin), &tempttyb); 1459895Ssam printf("\n\033\f\r"); 1469895Ssam } 1479895Ssam 1489895Ssam compare (a, b) 1499895Ssam char **a, **b; 1509895Ssam { 1519895Ssam return(wordcomp(*a, *b)); 1529895Ssam } 1539895Ssam 1549895Ssam wordcomp (p, q) 1559895Ssam register char *p, *q; 1569895Ssam { 1579895Ssam if (*p=='0' && *q!='0') 1589895Ssam return(-1); 1599895Ssam if (*p!='0' && *q=='0') 1609895Ssam return(1); 1619895Ssam while (*++p == *++q && isalpha(*p)) ; 1629895Ssam if (!isalpha(*p)) 1639895Ssam return(-isalpha(*q)); 1649895Ssam if (!isalpha(*q)) 1659895Ssam return(1); 1669895Ssam return(*p-*q); 1679895Ssam } 1689895Ssam 1699895Ssam printinst () 1709895Ssam { 1719895Ssam stty (fileno(stdin), &tempttyb); 1729895Ssam printf("instructions?"); 1739895Ssam if (getchar() == 'y') { 1749895Ssam clearscreen(); 1759895Ssam printf(" The object of Boggle (TM Parker Bros.) is to find, within 3\n"); 1769895Ssam printf("minutes, as many words as possible in a 4 by 4 grid of letters. Words\n"); 1779895Ssam printf("may be formed from any sequence of 3 or more adjacent letters in the\n"); 1789895Ssam printf("grid. The letters may join horizontally, vertically, or diagonally.\n"); 1799895Ssam printf("However, no position in the grid may be used more than once within any\n"); 1809895Ssam printf("one word. In competitive play amongst humans, each player is given\n"); 1819895Ssam printf("credit for those of his words which no other player has found.\n"); 1829895Ssam printf(" This program is intended for people wishing to sharpen their\n"); 1839895Ssam printf("skills at Boggle. If you invoke the program with 4 arguments of 4\n"); 1849895Ssam printf("letters each, (e.g. \"boggle appl epie moth erhd\") the program forms the\n"); 1859895Ssam printf("obvious Boggle grid and lists all the words from /usr/dict/words found\n"); 1869895Ssam printf("therein. If you invoke the program without arguments, it will generate\n"); 1879895Ssam printf("a board for you, let you enter words for 3 minutes, and then tell you\n"); 1889895Ssam printf("how well you did relative to /usr/dict/words.\n"); 1899895Ssam printf(" In interactive play, enter your words separated by spaces, tabs,\n"); 1909895Ssam printf("or newlines. A bell will ring when there is 2:00, 1:00, 0:10, 0:02,\n"); 1919895Ssam printf("0:01, and 0:00 time left. You may complete any word started before the\n"); 1929895Ssam printf("expiration of time. You can surrender before time is up by hitting\n"); 1939895Ssam printf("'break'. While entering words, your erase character is only effective\n"); 1949895Ssam printf("within the current word and your line kill character is ignored.\n"); 1959895Ssam printf(" Advanced players may wish to invoke the program with 1 or 2 +'s as\n"); 19620195Smckusick printf("the first argument. The first + removes the restriction that positions\n"); 1979895Ssam printf("can only be used once in each word. The second + causes a position to\n"); 1989895Ssam printf("be considered adjacent to itself as well as its (up to) 8 neighbors.\n"); 1999895Ssam printf("Hit any key to begin.\n"); 2009895Ssam stty (fileno(stdin), &tempttyb); 2019895Ssam getchar(); 2029895Ssam } 2039895Ssam stty (fileno(stdin), &tempttyb); 2049895Ssam } 2059895Ssam 2069895Ssam setup () 2079895Ssam { 2089895Ssam register int i, j; 2099895Ssam int rd, cd, k; 2109895Ssam for (i=0; i<BSIZE; i++) { 2119895Ssam adj[i][i] = super>=2 ? 1 : 0; 2129895Ssam adj[BSIZE][i] = 1; 2139895Ssam for (j=0; j<i; j++) { 2149895Ssam rd = row(i)-row(j); 2159895Ssam cd = col(i)-col(j); 2169895Ssam k = 0; 2179895Ssam switch (rd) { 2189895Ssam case -1: 2199895Ssam case 1: 2209895Ssam if (-1<=cd && cd<=1) 2219895Ssam k = 1; 2229895Ssam break; 2239895Ssam case 0: 2249895Ssam if (cd==-1 || cd==1) 2259895Ssam k = 1; 2269895Ssam break; 2279895Ssam } 2289895Ssam adj[i][j] = adj[j][i] = k; 2299895Ssam } 2309895Ssam } 2319895Ssam stack[0].parent = &stack[0]; 2329895Ssam stack[0].place = BSIZE; 2339895Ssam level[0] = &stack[0]; 2349895Ssam level[1] = &stack[1]; 2359895Ssam } 2369895Ssam 2379895Ssam makelists () 2389895Ssam { 2399895Ssam register int i, c; 2409895Ssam for (i=0; i<26; i++) 2419895Ssam occurs[i] = BSIZE; 2429895Ssam for (i=0; i<BSIZE; i++) { 2439895Ssam c = board[i]; 2449895Ssam olink[i] = occurs[c-'a']; 2459895Ssam occurs[c-'a'] = i; 2469895Ssam } 2479895Ssam } 2489895Ssam 2499895Ssam genboard () 2509895Ssam { 2519895Ssam register int i, j; 2529895Ssam for (i=0; i<BSIZE; i++) 2539895Ssam board[i] = 0; 2549895Ssam for (i=0; i<BSIZE; i++) { 2559895Ssam j = rand()%BSIZE; 2569895Ssam while (board[j] != 0) 2579895Ssam j = (j+1)%BSIZE; 2589895Ssam board[j] = cube[i][rand()%6]; 2599895Ssam } 2609895Ssam } 2619895Ssam 2629895Ssam printboard () 2639895Ssam { 2649895Ssam register int i, j; 2659895Ssam for (i=0; i<N; i++) { 2669895Ssam printf("\t\t\t\t\b\b"); 2679895Ssam for (j=0; j<N; j++) { 2689895Ssam putchar ((putchar(board[i*N+j]) == 'q') ? 'u' : ' '); 2699895Ssam putchar(' '); 2709895Ssam } 2719895Ssam putchar('\n'); 2729895Ssam } 2739895Ssam putchar('\n'); 2749895Ssam } 2759895Ssam 2769895Ssam getdword () 2779895Ssam { 2789895Ssam /* input: numsame = # chars same as last word */ 2799895Ssam /* output: numsame = # same chars for next word */ 2809895Ssam /* word in wbuff[0]...wbuff[wlength-1] */ 2819895Ssam register int c; 2829895Ssam register char *p; 2839895Ssam if (numsame == EOF) 2849895Ssam return (0); 2859895Ssam p = &wbuff[numsame]+1; 2869895Ssam while ((*p++ = c = getc(dict)) != EOF && isalpha(c)) ; 2879895Ssam numsame = c; 2889895Ssam wlength = p - &wbuff[2]; 2899895Ssam return (1); 2909895Ssam } 2919895Ssam 2929895Ssam getuword () 2939895Ssam { 2949895Ssam int c; 2959895Ssam register char *p, *q, *r; 2969895Ssam numsame = 0; 2979895Ssam while (*timept>0 && (isspace(c=getchar()) || c==EOF)); 2989895Ssam if (*timept == 0) 2999895Ssam return(0); 3009895Ssam word[wcount++] = freesp; 3019895Ssam *freesp++ = '0'; 3029895Ssam r = &wbuff[1]; 3039895Ssam q = p = freesp; 3049895Ssam *p++ = c; 3059895Ssam while (!isspace(c = getchar())) { 3069895Ssam if (c == EOF) 3079895Ssam continue; 3089895Ssam if (c == origttyb.sg_erase) { 3099895Ssam if (p > q) 3109895Ssam p--; 3119895Ssam continue; 3129895Ssam } 3139895Ssam *p++ = c; 3149895Ssam } 3159895Ssam freesp = p; 3169895Ssam for (p=q; p<freesp && r<&wbuff[BSIZE]; ) 3179895Ssam if (islower(c = *p++) && (*r++ = *q++ = c) == 'q' && *p == 'u') 3189895Ssam p++; 3199895Ssam *(freesp = q) = '0'; 3209895Ssam wlength = r-&wbuff[1]; 3219895Ssam return(1); 3229895Ssam } 3239895Ssam 3249895Ssam aputuword (ways) 3259895Ssam int ways; 3269895Ssam { 3279895Ssam *word[wcount-1] = ways>=10 ? '*' : '0'+ways; 3289895Ssam } 3299895Ssam 3309895Ssam aputword (ways) 3319895Ssam int ways; 3329895Ssam { 3339895Ssam /* store (wbuff, ways) in next slot in space */ 3349895Ssam register int i; 3359895Ssam *freesp++ = ways>=10 ? '*' : '0'+ways; 3369895Ssam for (i=1; i<= wlength; i++) 3379895Ssam *freesp++ = wbuff[i]; 3389895Ssam word[++wcount] = freesp; 3399895Ssam } 3409895Ssam 3419895Ssam tputword (ways) 3429895Ssam int ways; 3439895Ssam { 3449895Ssam /* print (wbuff, ways) on terminal */ 3459895Ssam wbuff[wlength+1] = '0'; 3469895Ssam wbuff[0] = ways>=10 ? '*' : '0'+ways; 3479895Ssam outword(&wbuff[0]); 3489895Ssam } 3499895Ssam 3509895Ssam outword (p) 3519895Ssam register char *p; 3529895Ssam { 3539895Ssam register int newcol; 3549895Ssam register char *q; 3559895Ssam for (q=p+1; isalpha(*q); ) { 3569895Ssam putchar(*q); 3579895Ssam if (*q++ == 'q') { 3589895Ssam putchar('u'); 3599895Ssam column++; 3609895Ssam } 3619895Ssam } 3629895Ssam column += q-p-1; 3639895Ssam if (column > LWIDTH-CWIDTH) { 3649895Ssam putchar('\n'); 3659895Ssam column = 0; 3669895Ssam return; 3679895Ssam } 3689895Ssam newcol = ((column+CWIDTH)/CWIDTH)*CWIDTH; 3699895Ssam while (((column+8)/8)*8 <= newcol) { 3709895Ssam putchar('\t'); 3719895Ssam column = ((column+8)/8)*8; 3729895Ssam } 3739895Ssam while (column < newcol) { 3749895Ssam putchar(' '); 3759895Ssam column++; 3769895Ssam } 3779895Ssam } 3789895Ssam 3799895Ssam printdiff () 3809895Ssam { 3819895Ssam register int c, d, u; 3829895Ssam char both, donly, uonly; 3839895Ssam word[wcount] = freesp; 3849895Ssam *freesp = '0'; 3859895Ssam both = donly = uonly = column = d = 0; 3869895Ssam u = ustart; 3879895Ssam while (d < ubotch) { 3889895Ssam c = u<wcount ? wordcomp (word[d], word[u]) : -1; 3899895Ssam if (c == 0) { 3909895Ssam /* dict and user found same word */ 3919895Ssam if (both == 0) { 3929895Ssam both = 1; 3939895Ssam printf("\t\t\t we both found:\n"); 3949895Ssam } 3959895Ssam outword(word[d]); 3969895Ssam word[d++] = NULL; 3979895Ssam word[u++] = NULL; 3989895Ssam } else if (c < 0) { 3999895Ssam /* dict found it, user didn't */ 4009895Ssam donly = 1; 4019895Ssam d++; 4029895Ssam } else { 4039895Ssam /* user found it, dict didn't */ 4049895Ssam uonly = 1; 4059895Ssam u++; 4069895Ssam } 4079895Ssam } 4089895Ssam endline(); 4099895Ssam if (donly) { 4109895Ssam printf("\n\t\t\tI alone found these:\n"); 4119895Ssam for (d=0; d<ubotch; d++) 4129895Ssam if (word[d] != NULL) 4139895Ssam outword(word[d]); 4149895Ssam endline(); 4159895Ssam } 4169895Ssam if (uonly) { 4179895Ssam printf("\n\t\t\tyou alone found these:\n"); 4189895Ssam for (u=ustart; u<wcount; u++) 4199895Ssam if (word[u] != NULL) 4209895Ssam outword(word[u]); 4219895Ssam endline(); 4229895Ssam } 4239895Ssam if (ubotch < ustart) { 4249895Ssam printf("\n\t\t\t you botched these:\n"); 4259895Ssam for (u=ubotch; u<ustart; u++) 4269895Ssam outword(word[u]); 4279895Ssam endline(); 4289895Ssam } 4299895Ssam } 4309895Ssam 4319895Ssam numways (leaf, last) 4329895Ssam register struct frame *leaf; 4339895Ssam struct frame *last; 4349895Ssam { 4359895Ssam int count; 4369895Ssam register char *p; 4379895Ssam register struct frame *node; 4389895Ssam if (super > 0) 4399895Ssam return(last-leaf); 4409895Ssam count = 0; 4419895Ssam present[BSIZE] = 1; 4429895Ssam while (leaf < last) { 4439895Ssam for (p = &present[0]; p < &present[BSIZE]; *p++ = 0); 4449895Ssam for (node = leaf; present[node->place]++ == 0; node = node->parent); 4459895Ssam if (node == &stack[0]) 4469895Ssam count++; 4479895Ssam leaf++; 4489895Ssam } 4499895Ssam return(count); 4509895Ssam } 4519895Ssam 4529895Ssam evalboard (getword, putword) 4539895Ssam int (*getword)(), (*putword)(); 4549895Ssam { 4559895Ssam register struct frame *top; 4569895Ssam register int l, q; 4579895Ssam int fo, found; 4589895Ssam struct frame *parent, *lastparent; 4599895Ssam char *padj; 4609895Ssam 4619895Ssam numsame = found = 0; 4629895Ssam makelists (); 4639895Ssam 4649895Ssam while (1) { 4659895Ssam l = numsame; 4669895Ssam if (!(*getword) ()) 4679895Ssam break; 4689895Ssam top = level[l+1]; 4699895Ssam 4709895Ssam while (1) { 4719895Ssam level[l+1] = lastparent = top; 4729895Ssam /* wbuff[1]...wbuff[l] have been matched */ 4739895Ssam /* level[0],...,level[l] of tree built */ 4749895Ssam if (l == wlength) { 4759895Ssam if (wlength >= 3 && (q = numways(level[l], top)) != 0) { 4769895Ssam (*putword) (q); 4779895Ssam found++; 4789895Ssam } 4799895Ssam l = BSIZE+1; 4809895Ssam break; 4819895Ssam } 4829895Ssam if ((fo = occurs[wbuff[++l]-'a']) == BSIZE) 4839895Ssam break; 4849895Ssam /* wbuff[1]...wbuff[l-1] have been matched */ 4859895Ssam /* level[0],...,level[l-1] of tree built */ 4869895Ssam for (parent=level[l-1]; parent<lastparent; parent++) { 4879895Ssam padj = &adj[parent->place][0]; 4889895Ssam for (q=fo; q!=BSIZE; q=olink[q]) 4899895Ssam if (padj[q]) { 4909895Ssam top->parent = parent; 4919895Ssam top->place = q; 4929895Ssam if (++top >= &stack[SSIZE]) { 4939895Ssam printf("stack overflow\n"); 4949895Ssam goodbye(1); 4959895Ssam } 4969895Ssam } 4979895Ssam } 4989895Ssam /* were any nodes added? */ 4999895Ssam if (top == lastparent) 5009895Ssam break; 5019895Ssam } 5029895Ssam 5039895Ssam /* advance until first l characters of next word are different */ 5049895Ssam while (numsame >= l && (*getword)()) ; 5059895Ssam } 5069895Ssam return(found); 5079895Ssam } 5089895Ssam 5099895Ssam main (argc, argv) 5109895Ssam int argc; 5119895Ssam char **argv; 5129895Ssam { 5139895Ssam char *q; 5149895Ssam register char *p; 5159895Ssam register int i, c; 5169895Ssam 5179895Ssam gtty (fileno(stdin), &origttyb); 5189895Ssam setbuf(stdin, NULL); 5199895Ssam tempttyb = origttyb; 5209895Ssam if (setjmp(env) != 0) 5219895Ssam goodbye(0); 5229895Ssam signal (SIGINT, interrupt); 52346734Sbostic timein = time((time_t *)NULL); 52446734Sbostic if (argv[0][0] != 'a' && (logfile = open(_PATH_BOGLOG, 1)) >= 0) { 5259895Ssam p = &logbuff[5]; 5269895Ssam q = getlogin(); 5279895Ssam while (*p++ = *q++); 5289895Ssam p[-1] = '\t'; 5299895Ssam q = ctime(&timein); 5309895Ssam while (*p++ = *q++); 5319895Ssam logloc = lseek(logfile, 0L, 2); 5329895Ssam write(logfile, &logbuff[0], p-&logbuff[1]); 5339895Ssam } 53441169Sbostic if ((dict = fopen(_PATH_DICTIONARY, "r")) == NULL) { 53541169Sbostic printf("can't open %s\n", _PATH_DICTIONARY); 5369895Ssam goodbye (2); 5379895Ssam } 5389895Ssam while ( argc > 1 && ( argv[1][0] == '+' || argv[1][0] == '-' ) ) { 5399895Ssam if (argv[1][0]=='+') { 5409895Ssam while(*(argv[1]++) == '+') 5419895Ssam super++; 5429895Ssam argc--; 5439895Ssam argv++; 5449895Ssam } 5459895Ssam if ( argv[1][0] == '-' ) { 5469895Ssam timeint[0] = 60 * ( atol( &argv[1][1] ) - 2 ); 5479895Ssam if ( timeint[0] <= 0 ) { 5489895Ssam timeint[0] = 60; 5499895Ssam } 5509895Ssam argc--; 5519895Ssam argv++; 5529895Ssam } 5539895Ssam } 5549895Ssam setup (); 5559895Ssam switch (argc) { 5569895Ssam default: punt: 5579895Ssam printf("usage: boggle [+[+]] [row1 row2 row3 row4]\n"); 5589895Ssam goodbye (3); 5599895Ssam case 5: 5609895Ssam for (i=0; i<BSIZE; i++) { 5619895Ssam board[i] = c = argv[row(i)+1][col(i)]; 5629895Ssam if (!islower(c)) { 5639895Ssam printf("bad board\n"); 5649895Ssam goto punt; 5659895Ssam } 5669895Ssam } 5679895Ssam printboard(); 5689895Ssam column = 0; 5699895Ssam evalboard(getdword, tputword); 5709895Ssam endline(); 5719895Ssam if (logfile >= 0) { 5729895Ssam strncpy(&logbuff[0], "eval", 4); 5739895Ssam lseek(logfile, logloc, 0); 5749895Ssam write(logfile, &logbuff[0], 4); 5759895Ssam } 5769895Ssam goodbye(0); 5779895Ssam case 1: 5789895Ssam tempttyb.sg_flags |= CBREAK; 5799895Ssam if ( ioctl( fileno(stdin), TIOCLGET, &ctlecho ) == 0 ) { 5809895Ssam if ( ctlecho & LCTLECH ) { 5819895Ssam ioctl( fileno(stdin), TIOCLBIC, &lctlech ); 5829895Ssam } 5839895Ssam } 5849895Ssam printinst(); 5859895Ssam srand((int) timein); 5869895Ssam while (setjmp(env) == 0) { 5879895Ssam errno = 0; 5889895Ssam if (pipe(&pipefd[0]) != 0) { 5899895Ssam printf("can't create pipe\n"); 5909895Ssam goodbye(4); 5919895Ssam } 5929895Ssam genboard(); 5939895Ssam delct = wcount = 0; 5949895Ssam word[0] = freesp = &space[0]; 5959895Ssam if ((master = fork()) == 0) { 5969895Ssam close(pipefd[0]); 5979895Ssam clearscreen(); 5989895Ssam printboard(); 5999895Ssam signal(SIGALRM, timeout); 6009895Ssam timept = &timeint[0]; 6019895Ssam alarm(*timept++); 6029895Ssam evalboard(getuword, aputuword); 6039895Ssam clearscreen(); 6049895Ssam qsort(&word[0], wcount, sizeof (int), compare); 6059895Ssam for (i=0; i<wcount; i++) 6069895Ssam if (i==0 || wordcomp(word[i], word[i-1])!=0) { 6079895Ssam p = word[i]; 6089895Ssam while (isalpha(*++p)) ; 6099895Ssam write (pipefd[1], word[i], p-word[i]); 6109895Ssam } 6119895Ssam close(pipefd[1]); 6129895Ssam goodbye(0); 6139895Ssam } 6149895Ssam close(pipefd[1]); 6159895Ssam rewind(dict); 6169895Ssam getc(dict); 6179895Ssam evalboard(getdword, aputword); 6189895Ssam p = freesp; 6199895Ssam while ((i = read(pipefd[0], freesp, 512)) != 0) { 6209895Ssam if (i < 0) 6219895Ssam if (errno != EINTR) 6229895Ssam break; 6239895Ssam else 6249895Ssam i = 0; 6259895Ssam freesp += i; 6269895Ssam } 6279895Ssam close(pipefd[0]); 6289895Ssam ustart = ubotch = wcount; 6299895Ssam while (p < freesp) { 6309895Ssam word[wcount++] = p; 6319895Ssam if (*p == '0') 6329895Ssam ustart = wcount; 6339895Ssam while (isalpha(*++p)); 6349895Ssam } 6359895Ssam wait(&status); 6369895Ssam if (status != 0) 6379895Ssam goodbye (5); 6389895Ssam delct = 1; 6399895Ssam printdiff(); 6409895Ssam printboard(); 6419895Ssam games++; 6429895Ssam if (logfile >= 0) { 64332490Sbostic (void)sprintf(&logbuff[0], "%4d", games); 6449895Ssam lseek(logfile, logloc, 0); 6459895Ssam write(logfile, &logbuff[0], 4); 6469895Ssam } 6479895Ssam stty (fileno(stdin), &tempttyb); 6489895Ssam printf("\nanother game?"); 6499895Ssam if (getchar() != 'y') { 6509895Ssam putchar('\n'); 6519895Ssam break; 6529895Ssam } 6539895Ssam stty (fileno(stdin), &tempttyb); 6549895Ssam } 6559895Ssam goodbye(0); 6569895Ssam } 6579895Ssam } 658