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