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

Defined functions

busy defined in line 456; used 1 times
  • in line 88
chase defined in line 543; used 2 times
drawbox defined in line 403; used 1 times
flushi defined in line 531; used 2 times
length defined in line 878; used 4 times
logit defined in line 884; used 4 times
main defined in line 73; never used
mainloop defined in line 158; used 1 times
post defined in line 479; used 2 times
pushsnake defined in line 756; used 1 times
random defined in line 431; used 6 times
remove defined in line 806; used 8 times
setup defined in line 386; used 4 times
snap defined in line 625; used 1 times
spacewarp defined in line 597; used 2 times
stop defined in line 853; used 4 times
stretch defined in line 661; used 2 times
  • in line 642(2)
surround defined in line 701; used 1 times
suspend defined in line 860; used 1 times
win defined in line 725; used 1 times
winnings defined in line 841; used 5 times

Defined variables

absv defined in line 539; used 1 times
argcount defined in line 60; used 1 times
  • in line 83
argval defined in line 61; used 2 times
ch defined in line 66; used 6 times
fast defined in line 68; used 11 times
finish defined in line 55; used 10 times
kd defined in line 67; used 2 times
kl defined in line 67; used 2 times
kr defined in line 67; used 2 times
ku defined in line 67; used 2 times
loot defined in line 58; used 8 times
money defined in line 54; used 19 times
moves defined in line 62; used 5 times
mx defined in line 535; used 3 times
my defined in line 537; used 3 times
oldw defined in line 542; used 2 times
p defined in line 65; used 85 times
penalty defined in line 58; used 5 times
repeat defined in line 69; used 16 times
savec defined in line 66; used 3 times
snake defined in line 56; used 18 times
str defined in line 63; used 3 times
stri defined in line 64; used 3 times
tl defined in line 59; never used
tm defined in line 59; never used
tn defined in line 71; never used
tv defined in line 70; used 3 times
you defined in line 53; used 77 times

Defined macros

BSIZE defined in line 51; used 3 times
BUSY defined in line 22; used 3 times
DEL defined in line 43; never used
EOT defined in line 41; never used
GOAL defined in line 49; used 2 times
LF defined in line 42; never used
LOGFILE defined in line 36; used 2 times
ME defined in line 45; used 7 times
PENALTY defined in line 39; used 1 times
SNAKEHEAD defined in line 46; used 3 times
SNAKERAWSCORES defined in line 29; used 2 times
SNAKETAIL defined in line 47; used 3 times
TREASURE defined in line 48; used 3 times
Last modified: 1981-01-19
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2629
Valid CSS Valid XHTML 1.0 Strict