1: /* 2: * Copyright (c) 1980 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: */ 6: 7: #if !defined(lint) && defined(DOSCCS) 8: char copyright[] = 9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 10: All rights reserved.\n"; 11: 12: static char sccsid[] = "@(#)snake.c 5.1.1 (2.11BSD) 1997/7/29"; 13: #endif 14: 15: /* 16: * snake - crt hack game. 17: * 18: * You move around the screen with arrow keys trying to pick up money 19: * without getting eaten by the snake. hjkl work as in vi in place of 20: * arrow keys. You can leave at the exit any time. 21: * 22: * compile as follows: 23: * cc -O snake.c move.c -o snake -lm -ltermlib 24: */ 25: 26: #include "snake.h" 27: #include <pwd.h> 28: 29: /* 30: * If CHECKBUSY is defined, the file BUSY must be executable 31: * and must return a value which is used to determine the priority 32: * a which snake runs. A zero value means no nice. 33: * If BUSY does not exist, snake won't play. 34: */ 35: #ifndef BUSY 36: #define BUSY "/usr/games/lib/busy" 37: #endif 38: 39: /* 40: * This is the data file for scorekeeping. 41: */ 42: #ifndef SNAKERAWSCORES 43: #define SNAKERAWSCORES "/usr/games/lib/snakerawscores" 44: #endif 45: 46: /* 47: * If it exists, a log is kept here. Otherwise it isn't. 48: */ 49: #ifndef LOGFILE 50: #define LOGFILE "/usr/games/lib/snake.log" 51: #endif 52: 53: #define PENALTY 10 /* % penalty for invoking spacewarp */ 54: 55: #define EOT '\004' 56: #define LF '\n' 57: #define DEL '\177' 58: 59: #define ME 'I' 60: #define SNAKEHEAD 'S' 61: #define SNAKETAIL 's' 62: #define TREASURE '$' 63: #define GOAL '#' 64: 65: #define BSIZE 80 66: 67: struct point you; 68: struct point money; 69: struct point finish; 70: struct point snake[6]; 71: 72: int loot, penalty; 73: int long tl, tm=0L; 74: int argcount; 75: char **argval; 76: int moves; 77: static char str[BSIZE]; 78: char stri[BSIZE]; 79: char *p; 80: char ch, savec; 81: char *kl, *kr, *ku, *kd; 82: int fast=1; 83: int repeat=1; 84: long tv; 85: char *tn; 86: 87: main(argc,argv) 88: int argc; 89: char **argv; 90: { 91: int i,k; 92: int j; 93: long time(); 94: int stop(); 95: char stdbuf[BUFSIZ]; 96: 97: argcount = argc; 98: argval = argv; 99: penalty = loot = 0; 100: getcap(); 101: ccnt -= 2; lcnt -= 2; /* compensate for border */ 102: busy(); 103: time(&tv); 104: 105: for (i=1; i<argc; i++) { 106: switch(argv[i][1]) { 107: case 'd': 108: sscanf(argv[1], "-d%ld", &tv); 109: break; 110: case 'w': /* width */ 111: case 'c': /* columns */ 112: ccnt = atoi(argv[i]+2); 113: break; 114: case 'l': /* length */ 115: case 'h': /* height */ 116: case 'r': /* rows */ 117: lcnt = atoi(argv[i]+2); 118: break; 119: default: 120: printf("bad option %s\n", argv[1]); 121: } 122: } 123: 124: srand((int)tv); 125: setbuf(stdout, stdbuf); 126: i = ((lcnt < ccnt) ? lcnt : ccnt); /* min screen edge */ 127: if (i < 4) { 128: printf("Screen too small for a fair game\n"); 129: done(); 130: } 131: /* 132: * chunk is the amount of money the user gets for each $. 133: * The formula below tries to be fair for various screen sizes. 134: * We only pay attention to the smaller of the 2 edges, since 135: * that seems to be the bottleneck. 136: * This formula is a hyperbola which includes the following points: 137: * (24, $25) (original scoring algorithm) 138: * (12, $40) (experimentally derived by the "feel") 139: * (48, $15) (a guess) 140: * This will give a 4x4 screen $99/shot. We don't allow anything 141: * smaller than 4x4 because there is a 3x3 game where you can win 142: * an infinite amount of money. 143: */ 144: if (i < 12) i = 12; /* otherwise it isn't fair */ 145: /* 146: * Compensate for border. This really changes the game since 147: * the screen is two squares smaller but we want the default 148: * to be $25, and the high scores on small screens were a bit 149: * much anyway. 150: */ 151: i += 2; 152: chunk = (675.0 / (i+6)) + 2.5; /* min screen edge */ 153: 154: signal (SIGINT, stop); 155: putpad(TI); /* String to begin programs that use cm */ 156: putpad(KS); /* Put terminal in keypad transmit mode */ 157: 158: random(&finish); 159: random(&you); 160: random(&money); 161: random(&snake[0]); 162: 163: if ((orig.sg_ospeed < B9600) || 164: ((! CM) && (! TA))) fast=0; 165: for(i=1;i<6;i++) 166: chase (&snake[i], &snake[i-1]); 167: setup(); 168: mainloop(); 169: } 170: 171: /* Main command loop */ 172: mainloop() 173: { 174: int j, k; 175: 176: for (;;) { 177: int c,lastc,match; 178: 179: move(&you); 180: fflush(stdout); 181: if (((c = getchar() & 0177) <= '9') && (c >= '0')) { 182: ungetc(c,stdin); 183: j = scanf("%d",&repeat); 184: c = getchar() & 0177; 185: } else { 186: if (c != '.') repeat = 1; 187: } 188: if (c == '.') { 189: c = lastc; 190: } 191: if ((Klength > 0) && 192: (c == *KL || c == *KR || c == *KU || c == *KD)) { 193: savec = c; 194: match = 0; 195: kl = KL; 196: kr = KR; 197: ku = KU; 198: kd = KD; 199: for (j=Klength;j>0;j--){ 200: if (match != 1) { 201: match = 0; 202: if (*kl++ == c) { 203: ch = 'h'; 204: match++; 205: } 206: if (*kr++ == c) { 207: ch = 'l'; 208: match++; 209: } 210: if (*ku++ == c) { 211: ch = 'k'; 212: match++; 213: } 214: if (*kd++ == c) { 215: ch = 'j'; 216: match++; 217: } 218: if (match == 0) { 219: ungetc(c,stdin); 220: ch = savec; 221: /* Oops! 222: * This works if we figure it out on second character. 223: */ 224: break; 225: } 226: } 227: savec = c; 228: if(j != 1) c = getchar() & 0177; 229: } 230: c = ch; 231: } 232: if (!fast) flushi(); 233: lastc = c; 234: switch (c){ 235: case CTRL(z): 236: case CTRL(c): 237: suspend(); 238: continue; 239: case EOT: 240: case 'x': 241: case 0177: /* del or end of file */ 242: ll(); 243: length(moves); 244: logit("quit"); 245: done(); 246: case '!': 247: cook(); 248: putchar('\n'); 249: putchar(c); 250: fflush(stdout); 251: j = read(0,stri,BSIZE); 252: stri[j] = 0; 253: if (fork() == 0) { 254: setuid(getuid()); 255: system(stri); 256: } else 257: wait(0); 258: printf("READY?\n"); 259: fflush(stdout); 260: raw(); 261: c = getchar(); 262: ungetc(c,stdin); 263: putpad(KS); 264: putpad(TI); 265: point(&cursor,0,lcnt-1); 266: case CTRL(l): 267: setup(); 268: winnings(cashvalue); 269: continue; 270: case 'p': 271: case 'd': 272: snap(); 273: continue; 274: case 'w': 275: spacewarp(0); 276: continue; 277: case 'A': 278: repeat = you.col; 279: c = 'h'; 280: break; 281: case 'H': 282: case 'S': 283: repeat = you.col - money.col; 284: c = 'h'; 285: break; 286: case 'T': 287: repeat = you.line; 288: c = 'k'; 289: break; 290: case 'K': 291: case 'E': 292: repeat = you.line - money.line; 293: c = 'k'; 294: break; 295: case 'P': 296: repeat = ccnt - 1 - you.col; 297: c = 'l'; 298: break; 299: case 'L': 300: case 'F': 301: repeat = money.col - you.col; 302: c = 'l'; 303: break; 304: case 'B': 305: repeat = lcnt - 1 - you.line; 306: c = 'j'; 307: break; 308: case 'J': 309: case 'C': 310: repeat = money.line - you.line; 311: c = 'j'; 312: break; 313: } 314: for(k=1;k<=repeat;k++){ 315: moves++; 316: switch(c) { 317: case 's': 318: case 'h': 319: case '\b': 320: if (you.col >0) { 321: if((fast)||(k == 1)) 322: pchar(&you,' '); 323: you.col--; 324: if((fast) || (k == repeat) || 325: (you.col == 0)) 326: pchar(&you,ME); 327: } 328: break; 329: case 'f': 330: case 'l': 331: case ' ': 332: if (you.col < ccnt-1) { 333: if((fast)||(k == 1)) 334: pchar(&you,' '); 335: you.col++; 336: if((fast) || (k == repeat) || 337: (you.col == ccnt-1)) 338: pchar(&you,ME); 339: } 340: break; 341: case CTRL(p): 342: case 'e': 343: case 'k': 344: case 'i': 345: if (you.line > 0) { 346: if((fast)||(k == 1)) 347: pchar(&you,' '); 348: you.line--; 349: if((fast) || (k == repeat) || 350: (you.line == 0)) 351: pchar(&you,ME); 352: } 353: break; 354: case CTRL(n): 355: case 'c': 356: case 'j': 357: case LF: 358: case 'm': 359: if (you.line+1 < lcnt) { 360: if((fast)||(k == 1)) 361: pchar(&you,' '); 362: you.line++; 363: if((fast) || (k == repeat) || 364: (you.line == lcnt-1)) 365: pchar(&you,ME); 366: } 367: break; 368: } 369: 370: if (same(&you,&money)) 371: { 372: char xp[20]; 373: struct point z; 374: loot += 25; 375: if(k < repeat) 376: pchar(&you,' '); 377: do { 378: random(&money); 379: } while (money.col == finish.col && money.line == finish.line || 380: money.col < 5 && money.line == 0 || 381: money.col == you.col && money.line == you.line); 382: pchar(&money,TREASURE); 383: winnings(cashvalue); 384: continue; 385: } 386: if (same(&you,&finish)) 387: { 388: win(&finish); 389: ll(); 390: cook(); 391: printf("You have won with $%d.\n",cashvalue); 392: fflush(stdout); 393: logit("won"); 394: post(cashvalue,0); 395: length(moves); 396: done(0); 397: } 398: if (pushsnake())break; 399: } 400: fflush(stdout); 401: } 402: } 403: 404: setup(){ /* 405: * setup the board 406: */ 407: int i; 408: 409: clear(); 410: pchar(&you,ME); 411: pchar(&finish,GOAL); 412: pchar(&money,TREASURE); 413: for(i=1; i<6; i++) { 414: pchar(&snake[i],SNAKETAIL); 415: } 416: pchar(&snake[0], SNAKEHEAD); 417: drawbox(); 418: fflush(stdout); 419: } 420: 421: drawbox() 422: { 423: register int i; 424: struct point p; 425: 426: p.line = -1; 427: for (i= 0; i<ccnt; i++) { 428: p.col = i; 429: pchar(&p, '-'); 430: } 431: p.col = ccnt; 432: for (i= -1; i<=lcnt; i++) { 433: p.line = i; 434: pchar(&p, '|'); 435: } 436: p.col = -1; 437: for (i= -1; i<=lcnt; i++) { 438: p.line = i; 439: pchar(&p, '|'); 440: } 441: p.line = lcnt; 442: for (i= 0; i<ccnt; i++) { 443: p.col = i; 444: pchar(&p, '-'); 445: } 446: } 447: 448: 449: random(sp) 450: struct point *sp; 451: { 452: register int issame; 453: struct point p; 454: register int i; 455: 456: sp->col = sp->line = -1; /* impossible */ 457: do { 458: issame = 0; 459: p.col = ((rand()>>8) & 0377)% ccnt; 460: p.line = ((rand()>>8) & 0377)% lcnt; 461: 462: /* make sure it's not on top of something else */ 463: if (p.line == 0 && p.col <5) issame++; 464: if(same(&p, &you)) issame++; 465: if(same(&p, &money)) issame++; 466: if(same(&p, &finish)) issame++; 467: for (i=0; i<5; i++) 468: if(same(&p, &snake[i])) issame++; 469: 470: } while (issame); 471: *sp = p; 472: } 473: 474: busy() 475: { 476: FILE *pip, *popen(); 477: char c; 478: int b,r; 479: float a; 480: 481: #ifdef CHECKBUSY 482: if (! strcmp (argval[0], "test")) return; 483: if ((access(BUSY,1) != 0) || (pip = popen(BUSY,"r")) == NULL){ 484: printf("Sorry, no snake just now.\n"); 485: done(); 486: } 487: fscanf(pip,"%d",&b); 488: pclose(pip); 489: if (b > 20) { 490: printf("Sorry, the system is too heavily loaded right now.\n"); 491: done(); 492: } 493: nice(b); 494: #endif 495: } 496: 497: post(iscore, flag) 498: int iscore, flag; 499: { 500: short score = iscore; 501: int rawscores; 502: short uid; 503: short oldbest=0; 504: short allbwho=0, allbscore=0; 505: struct passwd *p, *getpwuid(); 506: 507: /* 508: * Neg uid, 0, and 1 cannot have scores recorded. 509: */ 510: if ((uid=getuid()) > 1 && (rawscores=open(SNAKERAWSCORES,2))>=0) { 511: /* Figure out what happened in the past */ 512: read(rawscores, &allbscore, sizeof(short)); 513: read(rawscores, &allbwho, sizeof(short)); 514: lseek(rawscores, ((long)uid)*sizeof(short), 0); 515: read(rawscores, &oldbest, sizeof(short)); 516: if (flag) return (score > oldbest ? 1 : 0); 517: 518: /* Update this jokers best */ 519: if (score > oldbest) { 520: lseek(rawscores, ((long)uid)*sizeof(short), 0); 521: write(rawscores, &score, sizeof(short)); 522: printf("You bettered your previous best of $%d\n", oldbest); 523: } else 524: printf("Your best to date is $%d\n", oldbest); 525: 526: /* See if we have a new champ */ 527: p = getpwuid(allbwho); 528: if (p == NULL || score > allbscore) { 529: lseek(rawscores, (long)0, 0); 530: write(rawscores, &score, sizeof(short)); 531: write(rawscores, &uid, sizeof(short)); 532: if (p != NULL) 533: printf("You beat %s's old record of $%d!\n", p->pw_name, allbscore); 534: else 535: printf("You set a new record!\n"); 536: } else 537: printf("The highest is %s with $%d\n", p->pw_name, allbscore); 538: close(rawscores); 539: } else 540: if (!flag) 541: printf("Unable to post score.\n"); 542: return (1); 543: } 544: 545: /* 546: * Flush typeahead to keep from buffering a bunch of chars and then 547: * overshooting. This loses horribly at 9600 baud, but works nicely 548: * if the terminal gets behind. 549: */ 550: flushi() 551: { 552: stty(0, &new); 553: } 554: int mx [8] = { 555: 0, 1, 1, 1, 0,-1,-1,-1}; 556: int my [8] = { 557: -1,-1, 0, 1, 1, 1, 0,-1}; 558: float absv[8]= { 559: 1, 1.4, 1, 1.4, 1, 1.4, 1, 1.4 560: }; 561: int oldw=0; 562: chase (np, sp) 563: struct point *sp, *np; 564: { 565: /* this algorithm has bugs; otherwise the 566: snake would get too good */ 567: struct point d; 568: int w, i, wt[8]; 569: double sqrt(), v1, v2, vp, max; 570: point(&d,you.col-sp->col,you.line-sp->line); 571: v1 = sqrt( (double) (d.col*d.col + d.line*d.line) ); 572: w=0; 573: max=0; 574: for(i=0; i<8; i++) 575: { 576: vp = d.col*mx[i] + d.line*my[i]; 577: v2 = absv[i]; 578: if (v1>0) 579: vp = ((double)vp)/(v1*v2); 580: else vp=1.0; 581: if (vp>max) 582: { 583: max=vp; 584: w=i; 585: } 586: } 587: for(i=0; i<8; i++) 588: { 589: point(&d,sp->col+mx[i],sp->line+my[i]); 590: wt[i]=0; 591: if (d.col<0 || d.col>=ccnt || d.line<0 || d.line>=lcnt) 592: continue; 593: if (d.line == 0 && d.col < 5) continue; 594: if (same(&d,&money)) continue; 595: if (same(&d,&finish)) continue; 596: wt[i]= i==w ? loot/10 : 1; 597: if (i==oldw) wt [i] += loot/20; 598: } 599: for(w=i=0; i<8; i++) 600: w+= wt[i]; 601: vp = (( rand() >> 6 ) & 01777) %w; 602: for(i=0; i<8; i++) 603: if (vp <wt[i]) 604: break; 605: else 606: vp -= wt[i]; 607: if (i==8) { 608: printf("failure\n"); 609: i=0; 610: while (wt[i]==0) i++; 611: } 612: oldw=w=i; 613: point(np,sp->col+mx[w],sp->line+my[w]); 614: } 615: 616: spacewarp(w) 617: int w;{ 618: struct point p; 619: int j; 620: 621: random(&you); 622: point(&p,COLUMNS/2 - 8,LINES/2 - 1); 623: if (p.col < 0) 624: p.col = 0; 625: if (p.line < 0) 626: p.line = 0; 627: if (w) { 628: sprintf(str,"BONUS!!!"); 629: loot = loot - penalty; 630: penalty = 0; 631: } else { 632: sprintf(str,"SPACE WARP!!!"); 633: penalty += loot/PENALTY; 634: } 635: for(j=0;j<3;j++){ 636: clear(); 637: delay(5); 638: aprintf(&p,str); 639: delay(10); 640: } 641: setup(); 642: winnings(cashvalue); 643: } 644: snap() 645: { 646: struct point p; 647: int i; 648: 649: if(you.line < 3){ 650: pchar(point(&p,you.col,0),'-'); 651: } 652: if(you.line > lcnt-4){ 653: pchar(point(&p,you.col,lcnt-1),'_'); 654: } 655: if(you.col < 10){ 656: pchar(point(&p,0,you.line),'('); 657: } 658: if(you.col > ccnt-10){ 659: pchar(point(&p,ccnt-1,you.line),')'); 660: } 661: if (! stretch(&money)) if (! stretch(&finish)) delay(10); 662: if(you.line < 3){ 663: point(&p,you.col,0); 664: remove(&p); 665: } 666: if(you.line > lcnt-4){ 667: point(&p,you.col,lcnt-1); 668: remove(&p); 669: } 670: if(you.col < 10){ 671: point(&p,0,you.line); 672: remove(&p); 673: } 674: if(you.col > ccnt-10){ 675: point(&p,ccnt-1,you.line); 676: remove(&p); 677: } 678: fflush(stdout); 679: } 680: stretch(ps) 681: struct point *ps;{ 682: struct point p; 683: 684: point(&p,you.col,you.line); 685: if(abs(ps->col-you.col) < 6){ 686: if(you.line < ps->line){ 687: for (p.line = you.line+1;p.line <= ps->line;p.line++) 688: pchar(&p,'v'); 689: delay(10); 690: for (;p.line > you.line;p.line--) 691: remove(&p); 692: } else { 693: for (p.line = you.line-1;p.line >= ps->line;p.line--) 694: pchar(&p,'^'); 695: delay(10); 696: for (;p.line < you.line;p.line++) 697: remove(&p); 698: } 699: return(1); 700: } else if(abs(ps->line-you.line) < 3){ 701: p.line = you.line; 702: if(you.col < ps->col){ 703: for (p.col = you.col+1;p.col <= ps->col;p.col++) 704: pchar(&p,'>'); 705: delay(10); 706: for (;p.col > you.col;p.col--) 707: remove(&p); 708: } else { 709: for (p.col = you.col-1;p.col >= ps->col;p.col--) 710: pchar(&p,'<'); 711: delay(10); 712: for (;p.col < you.col;p.col++) 713: remove(&p); 714: } 715: return(1); 716: } 717: return(0); 718: } 719: 720: surround(ps) 721: struct point *ps;{ 722: struct point x; 723: int i,j; 724: 725: if(ps->col == 0)ps->col++; 726: if(ps->line == 0)ps->line++; 727: if(ps->line == LINES -1)ps->line--; 728: if(ps->col == COLUMNS -1)ps->col--; 729: aprintf(point(&x,ps->col-1,ps->line-1),"/*\\\r* *\r\\*/"); 730: for (j=0;j<20;j++){ 731: pchar(ps,'@'); 732: delay(1); 733: pchar(ps,' '); 734: delay(1); 735: } 736: if (post(cashvalue,1)) { 737: aprintf(point(&x,ps->col-1,ps->line-1)," \ro.o\r\\_/"); 738: delay(6); 739: aprintf(point(&x,ps->col-1,ps->line-1)," \ro.-\r\\_/"); 740: delay(6); 741: } 742: aprintf(point(&x,ps->col-1,ps->line-1)," \ro.o\r\\_/"); 743: } 744: win(ps) 745: struct point *ps; 746: { 747: struct point x; 748: int j,k; 749: int boxsize; /* actually diameter of box, not radius */ 750: 751: boxsize = fast ? 10 : 4; 752: point(&x,ps->col,ps->line); 753: for(j=1;j<boxsize;j++){ 754: for(k=0;k<j;k++){ 755: pchar(&x,'#'); 756: x.line--; 757: } 758: for(k=0;k<j;k++){ 759: pchar(&x,'#'); 760: x.col++; 761: } 762: j++; 763: for(k=0;k<j;k++){ 764: pchar(&x,'#'); 765: x.line++; 766: } 767: for(k=0;k<j;k++){ 768: pchar(&x,'#'); 769: x.col--; 770: } 771: } 772: fflush(stdout); 773: } 774: 775: pushsnake() 776: { 777: int i, bonus; 778: int issame = 0; 779: 780: /* 781: * My manual says times doesn't return a value. Furthermore, the 782: * snake should get his turn every time no matter if the user is 783: * on a fast terminal with typematic keys or not. 784: * So I have taken the call to times out. 785: */ 786: for(i=4; i>=0; i--) 787: if (same(&snake[i], &snake[5])) 788: issame++; 789: if (!issame) 790: pchar(&snake[5],' '); 791: for(i=4; i>=0; i--) 792: snake[i+1]= snake[i]; 793: chase(&snake[0], &snake[1]); 794: pchar(&snake[1],SNAKETAIL); 795: pchar(&snake[0],SNAKEHEAD); 796: for(i=0; i<6; i++) 797: { 798: if (same(&snake[i],&you)) 799: { 800: surround(&you); 801: i = (cashvalue) % 10; 802: bonus = ((rand()>>8) & 0377)% 10; 803: ll(); 804: printf("%d\n", bonus); 805: delay(30); 806: if (bonus == i) { 807: spacewarp(1); 808: logit("bonus"); 809: flushi(); 810: return(1); 811: } 812: if ( loot >= penalty ){ 813: printf("You and your $%d have been eaten\n",cashvalue); 814: } else { 815: printf("The snake ate you. You owe $%d.\n",-cashvalue); 816: } 817: logit("eaten"); 818: length(moves); 819: done(); 820: } 821: } 822: return(0); 823: } 824: 825: remove(sp) 826: struct point *sp; 827: { 828: int j; 829: 830: if (same(sp,&money)) { 831: pchar(sp,TREASURE); 832: return(2); 833: } 834: if (same(sp,&finish)) { 835: pchar(sp,GOAL); 836: return(3); 837: } 838: if (same(sp,&snake[0])) { 839: pchar(sp,SNAKEHEAD); 840: return(4); 841: } 842: for(j=1;j<6;j++){ 843: if(same(sp,&snake[j])){ 844: pchar(sp,SNAKETAIL); 845: return(4); 846: } 847: } 848: if ((sp->col < 4) && (sp->line == 0)){ 849: winnings(cashvalue); 850: if((you.line == 0) && (you.col < 4)) pchar(&you,ME); 851: return(5); 852: } 853: if (same(sp,&you)) { 854: pchar(sp,ME); 855: return(1); 856: } 857: pchar(sp,' '); 858: return(0); 859: } 860: winnings(won) 861: int won; 862: { 863: struct point p; 864: 865: p.line = p.col = 1; 866: if(won>0){ 867: move(&p); 868: printf("$%d",won); 869: } 870: } 871: 872: stop(){ 873: signal(SIGINT,1); 874: ll(); 875: length(moves); 876: done(); 877: } 878: 879: suspend() 880: { 881: char *sh; 882: 883: cook(); 884: #ifdef SIGTSTP 885: kill(getpid(), SIGTSTP); 886: #else 887: sh = getenv("SHELL"); 888: if (sh == NULL) 889: sh = "/bin/sh"; 890: system(sh); 891: #endif 892: raw(); 893: setup(); 894: winnings(cashvalue); 895: } 896: 897: length(num) 898: int num; 899: { 900: printf("You made %d moves.\n",num); 901: } 902: 903: logit(msg) 904: char *msg; 905: { 906: FILE *logfile; 907: long t; 908: 909: if ((logfile=fopen(LOGFILE, "a")) != NULL) { 910: time(&t); 911: fprintf(logfile, "%s $%d %dx%d %s %s", getlogin(), cashvalue, lcnt, ccnt, msg, ctime(&t)); 912: fclose(logfile); 913: } 914: }