1*9895Ssam #ifndef lint 2*9895Ssam static char sccsid[] = "@(#)boggle.c 4.1 12/24/82"; 3*9895Ssam #endif 4*9895Ssam 5*9895Ssam #include <ctype.h> 6*9895Ssam #include <errno.h> 7*9895Ssam #include <setjmp.h> 8*9895Ssam #include <sgtty.h> 9*9895Ssam #include <signal.h> 10*9895Ssam #include <stdio.h> 11*9895Ssam 12*9895Ssam /* basic parameters */ 13*9895Ssam #define N 4 14*9895Ssam #define SSIZE 200 15*9895Ssam #define MAXWORDS 1000 16*9895Ssam #define CWIDTH 10 17*9895Ssam #define LWIDTH 80 18*9895Ssam 19*9895Ssam /* parameters defined in terms of above */ 20*9895Ssam #define BSIZE (N*N) 21*9895Ssam #define row(x) (x/N) 22*9895Ssam #define col(x) (x%N) 23*9895Ssam 24*9895Ssam /* word being searched for */ 25*9895Ssam int wlength; 26*9895Ssam int numsame; 27*9895Ssam char wbuff [BSIZE+1]; 28*9895Ssam 29*9895Ssam /* tty and process control */ 30*9895Ssam extern int errno; 31*9895Ssam int status; 32*9895Ssam int pipefd[2]; 33*9895Ssam int super = 0; 34*9895Ssam int delct = 1; 35*9895Ssam int zero = 0; 36*9895Ssam int master = 1; 37*9895Ssam int column; 38*9895Ssam int *timept; 39*9895Ssam int timeint[] = {60,60,50,7,1,1,1,0}; 40*9895Ssam long timein; 41*9895Ssam extern long int time(); 42*9895Ssam struct sgttyb origttyb, tempttyb; 43*9895Ssam int ctlecho = 0; 44*9895Ssam int lctlech = LCTLECH; 45*9895Ssam jmp_buf env; 46*9895Ssam 47*9895Ssam /* monitoring variables */ 48*9895Ssam int games; 49*9895Ssam int logfile = -1; 50*9895Ssam long logloc; 51*9895Ssam char logbuff[100] = {"inst\t"}; 52*9895Ssam extern char *ctime(), *getlogin(); 53*9895Ssam extern long lseek(); 54*9895Ssam 55*9895Ssam /* dictionary interface */ 56*9895Ssam char defname[] = "/usr/games/bogdict"; 57*9895Ssam char *dictname = &defname[0]; 58*9895Ssam FILE *dict; 59*9895Ssam 60*9895Ssam /* structures for doing matching */ 61*9895Ssam struct frame { 62*9895Ssam struct frame *parent; 63*9895Ssam int place; 64*9895Ssam }; 65*9895Ssam struct frame stack [SSIZE]; 66*9895Ssam struct frame *level [BSIZE+1]; 67*9895Ssam 68*9895Ssam /* the board and subsidiary structures */ 69*9895Ssam char present [BSIZE+1]; 70*9895Ssam char board [BSIZE]; 71*9895Ssam char olink [BSIZE]; 72*9895Ssam char adj [BSIZE+1][BSIZE]; 73*9895Ssam char occurs [26]; 74*9895Ssam 75*9895Ssam /* the boggle cubes */ 76*9895Ssam char *cube [BSIZE] = { 77*9895Ssam "forixb", "moqabj", "gurilw", "setupl", 78*9895Ssam "cmpdae", "acitao", "slcrae", "romash", 79*9895Ssam "nodesw", "hefiye", "onudtk", "tevign", 80*9895Ssam "anedvz", "pinesh", "abilyt", "gkyleu" 81*9895Ssam }; 82*9895Ssam 83*9895Ssam 84*9895Ssam /* storage for words found */ 85*9895Ssam int ubotch, ustart, wcount; 86*9895Ssam char *word [MAXWORDS]; 87*9895Ssam char *freesp; 88*9895Ssam char space[10000]; 89*9895Ssam 90*9895Ssam endline () 91*9895Ssam { 92*9895Ssam if (column != 0) { 93*9895Ssam putchar('\n'); 94*9895Ssam column = 0; 95*9895Ssam } 96*9895Ssam } 97*9895Ssam 98*9895Ssam timeout () 99*9895Ssam { 100*9895Ssam if (*timept > 0) { 101*9895Ssam signal (SIGALRM, timeout); 102*9895Ssam alarm(*timept++); 103*9895Ssam } 104*9895Ssam putchar('\007'); 105*9895Ssam } 106*9895Ssam 107*9895Ssam interrupt () 108*9895Ssam { 109*9895Ssam signal(SIGINT, interrupt); 110*9895Ssam if (delct++ >= 1) 111*9895Ssam longjmp(env, 1); 112*9895Ssam timept = &zero; 113*9895Ssam } 114*9895Ssam 115*9895Ssam goodbye (stat) 116*9895Ssam int stat; 117*9895Ssam { 118*9895Ssam if (master != 0) { 119*9895Ssam wait(&status); 120*9895Ssam if ( ctlecho & LCTLECH ) { 121*9895Ssam ioctl( fileno(stdin), TIOCLBIS, &lctlech ); 122*9895Ssam } 123*9895Ssam stty(fileno(stdin), &origttyb); 124*9895Ssam } 125*9895Ssam exit(stat); 126*9895Ssam } 127*9895Ssam 128*9895Ssam clearscreen () 129*9895Ssam { 130*9895Ssam stty (fileno(stdin), &tempttyb); 131*9895Ssam printf("\n\033\f\r"); 132*9895Ssam } 133*9895Ssam 134*9895Ssam compare (a, b) 135*9895Ssam char **a, **b; 136*9895Ssam { 137*9895Ssam return(wordcomp(*a, *b)); 138*9895Ssam } 139*9895Ssam 140*9895Ssam wordcomp (p, q) 141*9895Ssam register char *p, *q; 142*9895Ssam { 143*9895Ssam if (*p=='0' && *q!='0') 144*9895Ssam return(-1); 145*9895Ssam if (*p!='0' && *q=='0') 146*9895Ssam return(1); 147*9895Ssam while (*++p == *++q && isalpha(*p)) ; 148*9895Ssam if (!isalpha(*p)) 149*9895Ssam return(-isalpha(*q)); 150*9895Ssam if (!isalpha(*q)) 151*9895Ssam return(1); 152*9895Ssam return(*p-*q); 153*9895Ssam } 154*9895Ssam 155*9895Ssam printinst () 156*9895Ssam { 157*9895Ssam stty (fileno(stdin), &tempttyb); 158*9895Ssam printf("instructions?"); 159*9895Ssam if (getchar() == 'y') { 160*9895Ssam clearscreen(); 161*9895Ssam printf(" The object of Boggle (TM Parker Bros.) is to find, within 3\n"); 162*9895Ssam printf("minutes, as many words as possible in a 4 by 4 grid of letters. Words\n"); 163*9895Ssam printf("may be formed from any sequence of 3 or more adjacent letters in the\n"); 164*9895Ssam printf("grid. The letters may join horizontally, vertically, or diagonally.\n"); 165*9895Ssam printf("However, no position in the grid may be used more than once within any\n"); 166*9895Ssam printf("one word. In competitive play amongst humans, each player is given\n"); 167*9895Ssam printf("credit for those of his words which no other player has found.\n"); 168*9895Ssam printf(" This program is intended for people wishing to sharpen their\n"); 169*9895Ssam printf("skills at Boggle. If you invoke the program with 4 arguments of 4\n"); 170*9895Ssam printf("letters each, (e.g. \"boggle appl epie moth erhd\") the program forms the\n"); 171*9895Ssam printf("obvious Boggle grid and lists all the words from /usr/dict/words found\n"); 172*9895Ssam printf("therein. If you invoke the program without arguments, it will generate\n"); 173*9895Ssam printf("a board for you, let you enter words for 3 minutes, and then tell you\n"); 174*9895Ssam printf("how well you did relative to /usr/dict/words.\n"); 175*9895Ssam printf(" In interactive play, enter your words separated by spaces, tabs,\n"); 176*9895Ssam printf("or newlines. A bell will ring when there is 2:00, 1:00, 0:10, 0:02,\n"); 177*9895Ssam printf("0:01, and 0:00 time left. You may complete any word started before the\n"); 178*9895Ssam printf("expiration of time. You can surrender before time is up by hitting\n"); 179*9895Ssam printf("'break'. While entering words, your erase character is only effective\n"); 180*9895Ssam printf("within the current word and your line kill character is ignored.\n"); 181*9895Ssam printf(" Advanced players may wish to invoke the program with 1 or 2 +'s as\n"); 182*9895Ssam printf("the first argument. The first + removes the restriction that postions\n"); 183*9895Ssam printf("can only be used once in each word. The second + causes a position to\n"); 184*9895Ssam printf("be considered adjacent to itself as well as its (up to) 8 neighbors.\n"); 185*9895Ssam printf("Hit any key to begin.\n"); 186*9895Ssam stty (fileno(stdin), &tempttyb); 187*9895Ssam getchar(); 188*9895Ssam } 189*9895Ssam stty (fileno(stdin), &tempttyb); 190*9895Ssam } 191*9895Ssam 192*9895Ssam setup () 193*9895Ssam { 194*9895Ssam register int i, j; 195*9895Ssam int rd, cd, k; 196*9895Ssam for (i=0; i<BSIZE; i++) { 197*9895Ssam adj[i][i] = super>=2 ? 1 : 0; 198*9895Ssam adj[BSIZE][i] = 1; 199*9895Ssam for (j=0; j<i; j++) { 200*9895Ssam rd = row(i)-row(j); 201*9895Ssam cd = col(i)-col(j); 202*9895Ssam k = 0; 203*9895Ssam switch (rd) { 204*9895Ssam case -1: 205*9895Ssam case 1: 206*9895Ssam if (-1<=cd && cd<=1) 207*9895Ssam k = 1; 208*9895Ssam break; 209*9895Ssam case 0: 210*9895Ssam if (cd==-1 || cd==1) 211*9895Ssam k = 1; 212*9895Ssam break; 213*9895Ssam } 214*9895Ssam adj[i][j] = adj[j][i] = k; 215*9895Ssam } 216*9895Ssam } 217*9895Ssam stack[0].parent = &stack[0]; 218*9895Ssam stack[0].place = BSIZE; 219*9895Ssam level[0] = &stack[0]; 220*9895Ssam level[1] = &stack[1]; 221*9895Ssam } 222*9895Ssam 223*9895Ssam makelists () 224*9895Ssam { 225*9895Ssam register int i, c; 226*9895Ssam for (i=0; i<26; i++) 227*9895Ssam occurs[i] = BSIZE; 228*9895Ssam for (i=0; i<BSIZE; i++) { 229*9895Ssam c = board[i]; 230*9895Ssam olink[i] = occurs[c-'a']; 231*9895Ssam occurs[c-'a'] = i; 232*9895Ssam } 233*9895Ssam } 234*9895Ssam 235*9895Ssam genboard () 236*9895Ssam { 237*9895Ssam register int i, j; 238*9895Ssam for (i=0; i<BSIZE; i++) 239*9895Ssam board[i] = 0; 240*9895Ssam for (i=0; i<BSIZE; i++) { 241*9895Ssam j = rand()%BSIZE; 242*9895Ssam while (board[j] != 0) 243*9895Ssam j = (j+1)%BSIZE; 244*9895Ssam board[j] = cube[i][rand()%6]; 245*9895Ssam } 246*9895Ssam } 247*9895Ssam 248*9895Ssam printboard () 249*9895Ssam { 250*9895Ssam register int i, j; 251*9895Ssam for (i=0; i<N; i++) { 252*9895Ssam printf("\t\t\t\t\b\b"); 253*9895Ssam for (j=0; j<N; j++) { 254*9895Ssam putchar ((putchar(board[i*N+j]) == 'q') ? 'u' : ' '); 255*9895Ssam putchar(' '); 256*9895Ssam } 257*9895Ssam putchar('\n'); 258*9895Ssam } 259*9895Ssam putchar('\n'); 260*9895Ssam } 261*9895Ssam 262*9895Ssam getdword () 263*9895Ssam { 264*9895Ssam /* input: numsame = # chars same as last word */ 265*9895Ssam /* output: numsame = # same chars for next word */ 266*9895Ssam /* word in wbuff[0]...wbuff[wlength-1] */ 267*9895Ssam register int c; 268*9895Ssam register char *p; 269*9895Ssam if (numsame == EOF) 270*9895Ssam return (0); 271*9895Ssam p = &wbuff[numsame]+1; 272*9895Ssam while ((*p++ = c = getc(dict)) != EOF && isalpha(c)) ; 273*9895Ssam numsame = c; 274*9895Ssam wlength = p - &wbuff[2]; 275*9895Ssam return (1); 276*9895Ssam } 277*9895Ssam 278*9895Ssam getuword () 279*9895Ssam { 280*9895Ssam int c; 281*9895Ssam register char *p, *q, *r; 282*9895Ssam numsame = 0; 283*9895Ssam while (*timept>0 && (isspace(c=getchar()) || c==EOF)); 284*9895Ssam if (*timept == 0) 285*9895Ssam return(0); 286*9895Ssam word[wcount++] = freesp; 287*9895Ssam *freesp++ = '0'; 288*9895Ssam r = &wbuff[1]; 289*9895Ssam q = p = freesp; 290*9895Ssam *p++ = c; 291*9895Ssam while (!isspace(c = getchar())) { 292*9895Ssam if (c == EOF) 293*9895Ssam continue; 294*9895Ssam if (c == origttyb.sg_erase) { 295*9895Ssam if (p > q) 296*9895Ssam p--; 297*9895Ssam continue; 298*9895Ssam } 299*9895Ssam *p++ = c; 300*9895Ssam } 301*9895Ssam freesp = p; 302*9895Ssam for (p=q; p<freesp && r<&wbuff[BSIZE]; ) 303*9895Ssam if (islower(c = *p++) && (*r++ = *q++ = c) == 'q' && *p == 'u') 304*9895Ssam p++; 305*9895Ssam *(freesp = q) = '0'; 306*9895Ssam wlength = r-&wbuff[1]; 307*9895Ssam return(1); 308*9895Ssam } 309*9895Ssam 310*9895Ssam aputuword (ways) 311*9895Ssam int ways; 312*9895Ssam { 313*9895Ssam *word[wcount-1] = ways>=10 ? '*' : '0'+ways; 314*9895Ssam } 315*9895Ssam 316*9895Ssam aputword (ways) 317*9895Ssam int ways; 318*9895Ssam { 319*9895Ssam /* store (wbuff, ways) in next slot in space */ 320*9895Ssam register int i; 321*9895Ssam *freesp++ = ways>=10 ? '*' : '0'+ways; 322*9895Ssam for (i=1; i<= wlength; i++) 323*9895Ssam *freesp++ = wbuff[i]; 324*9895Ssam word[++wcount] = freesp; 325*9895Ssam } 326*9895Ssam 327*9895Ssam tputword (ways) 328*9895Ssam int ways; 329*9895Ssam { 330*9895Ssam /* print (wbuff, ways) on terminal */ 331*9895Ssam wbuff[wlength+1] = '0'; 332*9895Ssam wbuff[0] = ways>=10 ? '*' : '0'+ways; 333*9895Ssam outword(&wbuff[0]); 334*9895Ssam } 335*9895Ssam 336*9895Ssam outword (p) 337*9895Ssam register char *p; 338*9895Ssam { 339*9895Ssam register int newcol; 340*9895Ssam register char *q; 341*9895Ssam for (q=p+1; isalpha(*q); ) { 342*9895Ssam putchar(*q); 343*9895Ssam if (*q++ == 'q') { 344*9895Ssam putchar('u'); 345*9895Ssam column++; 346*9895Ssam } 347*9895Ssam } 348*9895Ssam column += q-p-1; 349*9895Ssam if (column > LWIDTH-CWIDTH) { 350*9895Ssam putchar('\n'); 351*9895Ssam column = 0; 352*9895Ssam return; 353*9895Ssam } 354*9895Ssam newcol = ((column+CWIDTH)/CWIDTH)*CWIDTH; 355*9895Ssam while (((column+8)/8)*8 <= newcol) { 356*9895Ssam putchar('\t'); 357*9895Ssam column = ((column+8)/8)*8; 358*9895Ssam } 359*9895Ssam while (column < newcol) { 360*9895Ssam putchar(' '); 361*9895Ssam column++; 362*9895Ssam } 363*9895Ssam } 364*9895Ssam 365*9895Ssam printdiff () 366*9895Ssam { 367*9895Ssam register int c, d, u; 368*9895Ssam char both, donly, uonly; 369*9895Ssam word[wcount] = freesp; 370*9895Ssam *freesp = '0'; 371*9895Ssam both = donly = uonly = column = d = 0; 372*9895Ssam u = ustart; 373*9895Ssam while (d < ubotch) { 374*9895Ssam c = u<wcount ? wordcomp (word[d], word[u]) : -1; 375*9895Ssam if (c == 0) { 376*9895Ssam /* dict and user found same word */ 377*9895Ssam if (both == 0) { 378*9895Ssam both = 1; 379*9895Ssam printf("\t\t\t we both found:\n"); 380*9895Ssam } 381*9895Ssam outword(word[d]); 382*9895Ssam word[d++] = NULL; 383*9895Ssam word[u++] = NULL; 384*9895Ssam } else if (c < 0) { 385*9895Ssam /* dict found it, user didn't */ 386*9895Ssam donly = 1; 387*9895Ssam d++; 388*9895Ssam } else { 389*9895Ssam /* user found it, dict didn't */ 390*9895Ssam uonly = 1; 391*9895Ssam u++; 392*9895Ssam } 393*9895Ssam } 394*9895Ssam endline(); 395*9895Ssam if (donly) { 396*9895Ssam printf("\n\t\t\tI alone found these:\n"); 397*9895Ssam for (d=0; d<ubotch; d++) 398*9895Ssam if (word[d] != NULL) 399*9895Ssam outword(word[d]); 400*9895Ssam endline(); 401*9895Ssam } 402*9895Ssam if (uonly) { 403*9895Ssam printf("\n\t\t\tyou alone found these:\n"); 404*9895Ssam for (u=ustart; u<wcount; u++) 405*9895Ssam if (word[u] != NULL) 406*9895Ssam outword(word[u]); 407*9895Ssam endline(); 408*9895Ssam } 409*9895Ssam if (ubotch < ustart) { 410*9895Ssam printf("\n\t\t\t you botched these:\n"); 411*9895Ssam for (u=ubotch; u<ustart; u++) 412*9895Ssam outword(word[u]); 413*9895Ssam endline(); 414*9895Ssam } 415*9895Ssam } 416*9895Ssam 417*9895Ssam numways (leaf, last) 418*9895Ssam register struct frame *leaf; 419*9895Ssam struct frame *last; 420*9895Ssam { 421*9895Ssam int count; 422*9895Ssam register char *p; 423*9895Ssam register struct frame *node; 424*9895Ssam if (super > 0) 425*9895Ssam return(last-leaf); 426*9895Ssam count = 0; 427*9895Ssam present[BSIZE] = 1; 428*9895Ssam while (leaf < last) { 429*9895Ssam for (p = &present[0]; p < &present[BSIZE]; *p++ = 0); 430*9895Ssam for (node = leaf; present[node->place]++ == 0; node = node->parent); 431*9895Ssam if (node == &stack[0]) 432*9895Ssam count++; 433*9895Ssam leaf++; 434*9895Ssam } 435*9895Ssam return(count); 436*9895Ssam } 437*9895Ssam 438*9895Ssam evalboard (getword, putword) 439*9895Ssam int (*getword)(), (*putword)(); 440*9895Ssam { 441*9895Ssam register struct frame *top; 442*9895Ssam register int l, q; 443*9895Ssam int fo, found; 444*9895Ssam struct frame *parent, *lastparent; 445*9895Ssam char *padj; 446*9895Ssam 447*9895Ssam numsame = found = 0; 448*9895Ssam makelists (); 449*9895Ssam 450*9895Ssam while (1) { 451*9895Ssam l = numsame; 452*9895Ssam if (!(*getword) ()) 453*9895Ssam break; 454*9895Ssam top = level[l+1]; 455*9895Ssam 456*9895Ssam while (1) { 457*9895Ssam level[l+1] = lastparent = top; 458*9895Ssam /* wbuff[1]...wbuff[l] have been matched */ 459*9895Ssam /* level[0],...,level[l] of tree built */ 460*9895Ssam if (l == wlength) { 461*9895Ssam if (wlength >= 3 && (q = numways(level[l], top)) != 0) { 462*9895Ssam (*putword) (q); 463*9895Ssam found++; 464*9895Ssam } 465*9895Ssam l = BSIZE+1; 466*9895Ssam break; 467*9895Ssam } 468*9895Ssam if ((fo = occurs[wbuff[++l]-'a']) == BSIZE) 469*9895Ssam break; 470*9895Ssam /* wbuff[1]...wbuff[l-1] have been matched */ 471*9895Ssam /* level[0],...,level[l-1] of tree built */ 472*9895Ssam for (parent=level[l-1]; parent<lastparent; parent++) { 473*9895Ssam padj = &adj[parent->place][0]; 474*9895Ssam for (q=fo; q!=BSIZE; q=olink[q]) 475*9895Ssam if (padj[q]) { 476*9895Ssam top->parent = parent; 477*9895Ssam top->place = q; 478*9895Ssam if (++top >= &stack[SSIZE]) { 479*9895Ssam printf("stack overflow\n"); 480*9895Ssam goodbye(1); 481*9895Ssam } 482*9895Ssam } 483*9895Ssam } 484*9895Ssam /* were any nodes added? */ 485*9895Ssam if (top == lastparent) 486*9895Ssam break; 487*9895Ssam } 488*9895Ssam 489*9895Ssam /* advance until first l characters of next word are different */ 490*9895Ssam while (numsame >= l && (*getword)()) ; 491*9895Ssam } 492*9895Ssam return(found); 493*9895Ssam } 494*9895Ssam 495*9895Ssam main (argc, argv) 496*9895Ssam int argc; 497*9895Ssam char **argv; 498*9895Ssam { 499*9895Ssam char *q; 500*9895Ssam register char *p; 501*9895Ssam register int i, c; 502*9895Ssam 503*9895Ssam gtty (fileno(stdin), &origttyb); 504*9895Ssam setbuf(stdin, NULL); 505*9895Ssam tempttyb = origttyb; 506*9895Ssam if (setjmp(env) != 0) 507*9895Ssam goodbye(0); 508*9895Ssam signal (SIGINT, interrupt); 509*9895Ssam timein = time(0L); 510*9895Ssam if (argv[0][0] != 'a' && (logfile = open("/usr/games/boglog", 1)) >= 0) { 511*9895Ssam p = &logbuff[5]; 512*9895Ssam q = getlogin(); 513*9895Ssam while (*p++ = *q++); 514*9895Ssam p[-1] = '\t'; 515*9895Ssam q = ctime(&timein); 516*9895Ssam while (*p++ = *q++); 517*9895Ssam logloc = lseek(logfile, 0L, 2); 518*9895Ssam write(logfile, &logbuff[0], p-&logbuff[1]); 519*9895Ssam } 520*9895Ssam if ((dict = fopen(dictname, "r")) == NULL) { 521*9895Ssam printf("can't open %s\n", dictname); 522*9895Ssam goodbye (2); 523*9895Ssam } 524*9895Ssam while ( argc > 1 && ( argv[1][0] == '+' || argv[1][0] == '-' ) ) { 525*9895Ssam if (argv[1][0]=='+') { 526*9895Ssam while(*(argv[1]++) == '+') 527*9895Ssam super++; 528*9895Ssam argc--; 529*9895Ssam argv++; 530*9895Ssam } 531*9895Ssam if ( argv[1][0] == '-' ) { 532*9895Ssam timeint[0] = 60 * ( atol( &argv[1][1] ) - 2 ); 533*9895Ssam if ( timeint[0] <= 0 ) { 534*9895Ssam timeint[0] = 60; 535*9895Ssam } 536*9895Ssam argc--; 537*9895Ssam argv++; 538*9895Ssam } 539*9895Ssam } 540*9895Ssam setup (); 541*9895Ssam switch (argc) { 542*9895Ssam default: punt: 543*9895Ssam printf("usage: boggle [+[+]] [row1 row2 row3 row4]\n"); 544*9895Ssam goodbye (3); 545*9895Ssam case 5: 546*9895Ssam for (i=0; i<BSIZE; i++) { 547*9895Ssam board[i] = c = argv[row(i)+1][col(i)]; 548*9895Ssam if (!islower(c)) { 549*9895Ssam printf("bad board\n"); 550*9895Ssam goto punt; 551*9895Ssam } 552*9895Ssam } 553*9895Ssam printboard(); 554*9895Ssam column = 0; 555*9895Ssam evalboard(getdword, tputword); 556*9895Ssam endline(); 557*9895Ssam if (logfile >= 0) { 558*9895Ssam strncpy(&logbuff[0], "eval", 4); 559*9895Ssam lseek(logfile, logloc, 0); 560*9895Ssam write(logfile, &logbuff[0], 4); 561*9895Ssam } 562*9895Ssam goodbye(0); 563*9895Ssam case 1: 564*9895Ssam tempttyb.sg_flags |= CBREAK; 565*9895Ssam if ( ioctl( fileno(stdin), TIOCLGET, &ctlecho ) == 0 ) { 566*9895Ssam if ( ctlecho & LCTLECH ) { 567*9895Ssam ioctl( fileno(stdin), TIOCLBIC, &lctlech ); 568*9895Ssam } 569*9895Ssam } 570*9895Ssam printinst(); 571*9895Ssam srand((int) timein); 572*9895Ssam while (setjmp(env) == 0) { 573*9895Ssam errno = 0; 574*9895Ssam if (pipe(&pipefd[0]) != 0) { 575*9895Ssam printf("can't create pipe\n"); 576*9895Ssam goodbye(4); 577*9895Ssam } 578*9895Ssam genboard(); 579*9895Ssam delct = wcount = 0; 580*9895Ssam word[0] = freesp = &space[0]; 581*9895Ssam if ((master = fork()) == 0) { 582*9895Ssam close(pipefd[0]); 583*9895Ssam clearscreen(); 584*9895Ssam printboard(); 585*9895Ssam signal(SIGALRM, timeout); 586*9895Ssam timept = &timeint[0]; 587*9895Ssam alarm(*timept++); 588*9895Ssam evalboard(getuword, aputuword); 589*9895Ssam clearscreen(); 590*9895Ssam qsort(&word[0], wcount, sizeof (int), compare); 591*9895Ssam for (i=0; i<wcount; i++) 592*9895Ssam if (i==0 || wordcomp(word[i], word[i-1])!=0) { 593*9895Ssam p = word[i]; 594*9895Ssam while (isalpha(*++p)) ; 595*9895Ssam write (pipefd[1], word[i], p-word[i]); 596*9895Ssam } 597*9895Ssam close(pipefd[1]); 598*9895Ssam goodbye(0); 599*9895Ssam } 600*9895Ssam close(pipefd[1]); 601*9895Ssam rewind(dict); 602*9895Ssam getc(dict); 603*9895Ssam evalboard(getdword, aputword); 604*9895Ssam p = freesp; 605*9895Ssam while ((i = read(pipefd[0], freesp, 512)) != 0) { 606*9895Ssam if (i < 0) 607*9895Ssam if (errno != EINTR) 608*9895Ssam break; 609*9895Ssam else 610*9895Ssam i = 0; 611*9895Ssam freesp += i; 612*9895Ssam } 613*9895Ssam close(pipefd[0]); 614*9895Ssam ustart = ubotch = wcount; 615*9895Ssam while (p < freesp) { 616*9895Ssam word[wcount++] = p; 617*9895Ssam if (*p == '0') 618*9895Ssam ustart = wcount; 619*9895Ssam while (isalpha(*++p)); 620*9895Ssam } 621*9895Ssam wait(&status); 622*9895Ssam if (status != 0) 623*9895Ssam goodbye (5); 624*9895Ssam delct = 1; 625*9895Ssam printdiff(); 626*9895Ssam printboard(); 627*9895Ssam games++; 628*9895Ssam if (logfile >= 0) { 629*9895Ssam sprintf(&logbuff[0], "%4d", games); 630*9895Ssam lseek(logfile, logloc, 0); 631*9895Ssam write(logfile, &logbuff[0], 4); 632*9895Ssam } 633*9895Ssam stty (fileno(stdin), &tempttyb); 634*9895Ssam printf("\nanother game?"); 635*9895Ssam if (getchar() != 'y') { 636*9895Ssam putchar('\n'); 637*9895Ssam break; 638*9895Ssam } 639*9895Ssam stty (fileno(stdin), &tempttyb); 640*9895Ssam } 641*9895Ssam goodbye(0); 642*9895Ssam } 643*9895Ssam } 644