|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.