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

Defined functions

busy defined in line 474; used 1 times
chase defined in line 562; used 2 times
drawbox defined in line 421; used 1 times
flushi defined in line 550; used 2 times
length defined in line 897; used 4 times
logit defined in line 903; used 4 times
main defined in line 87; never used
mainloop defined in line 172; used 1 times
post defined in line 497; used 2 times
pushsnake defined in line 775; used 1 times
random defined in line 449; used 6 times
remove defined in line 825; used 8 times
setup defined in line 404; used 4 times
snap defined in line 644; used 1 times
spacewarp defined in line 616; used 2 times
stop defined in line 872; used 4 times
stretch defined in line 680; used 2 times
  • in line 661(2)
surround defined in line 720; used 1 times
suspend defined in line 879; used 1 times
win defined in line 744; used 1 times
winnings defined in line 860; used 5 times

Defined variables

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

Defined macros

BSIZE defined in line 65; used 3 times
BUSY defined in line 36; used 3 times
DEL defined in line 57; never used
EOT defined in line 55; never used
GOAL defined in line 63; used 2 times
LF defined in line 56; never used
LOGFILE defined in line 50; used 2 times
ME defined in line 59; used 7 times
PENALTY defined in line 53; used 1 times
SNAKEHEAD defined in line 60; used 3 times
SNAKERAWSCORES defined in line 43; used 2 times
SNAKETAIL defined in line 61; used 3 times
TREASURE defined in line 62; used 3 times
Last modified: 1997-07-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1104
Valid CSS Valid XHTML 1.0 Strict