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: }

Defined functions

busy defined in line 476; used 1 times
chase defined in line 564; used 2 times
drawbox defined in line 423; used 1 times
flushi defined in line 552; used 2 times
length defined in line 899; used 4 times
logit defined in line 905; used 4 times
main defined in line 89; never used
mainloop defined in line 174; used 1 times
post defined in line 499; used 2 times
pushsnake defined in line 777; used 1 times
random defined in line 451; used 6 times
remove defined in line 827; used 8 times
setup defined in line 406; used 4 times
snap defined in line 646; used 1 times
spacewarp defined in line 618; used 2 times
stop defined in line 874; used 4 times
stretch defined in line 682; used 2 times
  • in line 663(2)
surround defined in line 722; used 1 times
suspend defined in line 881; used 1 times
win defined in line 746; used 1 times
winnings defined in line 862; used 5 times

Defined variables

absv defined in line 560; used 1 times
argcount defined in line 76; used 1 times
  • in line 99
argval defined in line 77; used 2 times
ch defined in line 82; used 6 times
copyright defined in line 8; never used
fast defined in line 84; used 11 times
finish defined in line 71; used 10 times
kd defined in line 83; used 2 times
kl defined in line 83; used 2 times
kr defined in line 83; used 2 times
ku defined in line 83; used 2 times
loot defined in line 74; used 8 times
money defined in line 70; used 19 times
moves defined in line 78; used 5 times
mx defined in line 556; used 3 times
my defined in line 558; used 3 times
oldw defined in line 563; used 2 times
p defined in line 81; used 85 times
penalty defined in line 74; used 5 times
repeat defined in line 85; used 16 times
savec defined in line 82; used 3 times
sccsid defined in line 14; never used
snake defined in line 72; used 18 times
str defined in line 79; used 3 times
stri defined in line 80; used 3 times
tl defined in line 75; never used
tm defined in line 75; never used
tn defined in line 87; never used
tv defined in line 86; used 3 times
you defined in line 69; used 77 times

Defined macros

BSIZE defined in line 67; used 3 times
BUSY defined in line 38; used 3 times
DEL defined in line 59; never used
EOT defined in line 57; never used
GOAL defined in line 65; used 2 times
LF defined in line 58; never used
LOGFILE defined in line 52; used 2 times
ME defined in line 61; used 7 times
PENALTY defined in line 55; used 1 times
SNAKEHEAD defined in line 62; used 3 times
SNAKERAWSCORES defined in line 45; used 2 times
SNAKETAIL defined in line 63; used 3 times
TREASURE defined in line 64; used 3 times
Last modified: 1985-05-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3261
Valid CSS Valid XHTML 1.0 Strict