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