mpfr: always include stdint.h to allow build from DragonFly-2.2
[dragonfly.git] / games / snake / snake / snake.c
blob693df16a5b141a886b148e1f60cb67c210228ece
1 /*
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
33 * @(#) Copyright (c) 1980, 1993 The Regents of the University of California. All rights reserved.
34 * @(#)snake.c 8.2 (Berkeley) 1/7/94
35 * $FreeBSD: src/games/snake/snake/snake.c,v 1.11.2.1 2000/08/17 06:21:44 jhb Exp $
36 * $DragonFly: src/games/snake/snake/snake.c,v 1.4 2006/09/03 23:47:56 pavalos Exp $
40 * snake - crt hack game.
42 * You move around the screen with arrow keys trying to pick up money
43 * without getting eaten by the snake. hjkl work as in vi in place of
44 * arrow keys. You can leave at the exit any time.
46 * compile as follows:
47 * cc -O snake.c move.c -o snake -lm -ltermlib
50 #include <sys/param.h>
52 #include <curses.h>
53 #include <fcntl.h>
54 #include <pwd.h>
55 #include <time.h>
56 #include <stdlib.h>
57 #include <unistd.h>
58 #include <sys/types.h>
59 #include <err.h>
60 #include <math.h>
61 #include <signal.h>
62 #include <stdio.h>
63 #include <stdlib.h>
64 #include <string.h>
65 #include <termios.h>
67 #include "pathnames.h"
69 #define cashvalue chunk*(loot-penalty)/25
71 struct point {
72 int col, line;
75 #define same(s1, s2) ((s1)->line == (s2)->line && (s1)->col == (s2)->col)
77 #define PENALTY 10 /* % penalty for invoking spacewarp */
79 #define EOT '\004'
80 #define LF '\n'
81 #define DEL '\177'
83 #define ME 'I'
84 #define SNAKEHEAD 'S'
85 #define SNAKETAIL 's'
86 #define TREASURE '$'
87 #define GOAL '#'
89 #ifndef MIN
90 #define MIN(a, b) ((a) < (b) ? (a) : (b))
91 #endif
93 #define pchar(point, c) mvaddch((point)->line + 1, (point)->col + 1, (c))
94 #define delay(t) usleep(t * 50000);
96 struct point you;
97 struct point money;
98 struct point finish;
99 struct point snake[6];
101 int loot, penalty;
102 int moves;
103 int fast = 1;
105 int rawscores;
106 FILE *logfile;
108 int lcnt, ccnt; /* user's idea of screen size */
109 int chunk; /* amount of money given at a time */
111 void chase(struct point *, struct point *);
112 int chk(const struct point *);
113 void drawbox(void);
114 void flushi(void);
115 void home(void);
116 void length(int);
117 void logit(const char *);
118 int main(int, char **);
119 void mainloop(void) __attribute__((__noreturn__));
120 struct point *point(struct point *, int, int);
121 int post(int, int);
122 int pushsnake(void);
123 void right(const struct point *);
124 void setup(void);
125 void snap(void);
126 void snrand(struct point *);
127 void spacewarp(int);
128 void stop(int) __attribute__((__noreturn__));
129 int stretch(const struct point *);
130 void surround(struct point *);
131 void suspend(void);
132 void win(const struct point *);
133 void winnings(int);
136 main(int argc, char **argv)
138 int ch, i;
139 time_t tv;
141 /* Open score files then revoke setgid privileges */
142 rawscores = open(_PATH_RAWSCORES, O_RDWR|O_CREAT, 0664);
143 if (rawscores < 0) {
144 warn("open %s", _PATH_RAWSCORES);
145 sleep(2);
146 } else if (rawscores < 3)
147 exit(1);
148 logfile = fopen(_PATH_LOGFILE, "a");
149 if (logfile == NULL) {
150 warn("fopen %s", _PATH_LOGFILE);
151 sleep(2);
153 setgid(getgid());
155 time(&tv);
157 while ((ch = getopt(argc, argv, "l:w:t")) != -1)
158 switch ((char) ch) {
159 #ifdef DEBUG
160 case 'd':
161 tv = atol(optarg);
162 break;
163 #endif
164 case 'w': /* width */
165 ccnt = atoi(optarg);
166 break;
167 case 'l': /* length */
168 lcnt = atoi(optarg);
169 break;
170 case 't':
171 fast = 0;
172 break;
173 case '?':
174 default:
175 #ifdef DEBUG
176 fputs("usage: snake [-d seed] [-w width] [-l length] [-t]\n", stderr);
177 #else
178 fputs("usage: snake [-w width] [-l length] [-t]\n", stderr);
179 #endif
180 exit(1);
183 srandom((int) tv);
185 penalty = loot = 0;
186 initscr();
187 cbreak();
188 noecho();
189 #ifdef KEY_LEFT
190 keypad(stdscr, TRUE);
191 #endif
192 if (!lcnt || lcnt > LINES - 2)
193 lcnt = LINES - 2;
194 if (!ccnt || ccnt > COLS - 2)
195 ccnt = COLS - 2;
197 i = MIN(lcnt, ccnt);
198 if (i < 4) {
199 endwin();
200 errx(1, "screen too small for a fair game.");
204 * chunk is the amount of money the user gets for each $.
205 * The formula below tries to be fair for various screen sizes.
206 * We only pay attention to the smaller of the 2 edges, since
207 * that seems to be the bottleneck.
208 * This formula is a hyperbola which includes the following points:
209 * (24, $25) (original scoring algorithm)
210 * (12, $40) (experimentally derived by the "feel")
211 * (48, $15) (a guess)
212 * This will give a 4x4 screen $99/shot. We don't allow anything
213 * smaller than 4x4 because there is a 3x3 game where you can win
214 * an infinite amount of money.
216 if (i < 12) i = 12; /* otherwise it isn't fair */
218 * Compensate for border. This really changes the game since
219 * the screen is two squares smaller but we want the default
220 * to be $25, and the high scores on small screens were a bit
221 * much anyway.
223 i += 2;
224 chunk = (675.0 / (i+6)) + 2.5; /* min screen edge */
226 signal (SIGINT, stop);
228 snrand(&finish);
229 snrand(&you);
230 snrand(&money);
231 snrand(&snake[0]);
233 for(i=1;i<6;i++)
234 chase (&snake[i], &snake[i-1]);
235 setup();
236 mainloop();
237 /* NOTREACHED */
238 return (0);
241 struct point *
242 point(struct point *ps, int x, int y)
244 ps->col = x;
245 ps->line = y;
246 return (ps);
249 /* Main command loop */
250 void
251 mainloop(void)
253 int k;
254 int repeat = 1;
255 int lastc = 0;
257 for (;;) {
258 int c;
260 /* Highlight you, not left & above */
261 move(you.line + 1, you.col + 1);
262 refresh();
263 if (((c = getch()) <= '9') && (c >= '0')) {
264 repeat = c - '0';
265 while (((c = getch()) <= '9') && (c >= '0'))
266 repeat = 10 * repeat + (c - '0');
267 } else {
268 if (c != '.') repeat = 1;
270 if (c == '.') {
271 c = lastc;
273 if (!fast) flushi();
274 lastc = c;
275 switch (c){
276 case CTRL('z'):
277 suspend();
278 continue;
279 case EOT:
280 case 'x':
281 case 0177: /* del or end of file */
282 endwin();
283 length(moves);
284 logit("quit");
285 exit(0);
286 case CTRL('l'):
287 setup();
288 winnings(cashvalue);
289 continue;
290 case 'p':
291 case 'd':
292 snap();
293 continue;
294 case 'w':
295 spacewarp(0);
296 continue;
297 case 'A':
298 repeat = you.col;
299 c = 'h';
300 break;
301 case 'H':
302 case 'S':
303 repeat = you.col - money.col;
304 c = 'h';
305 break;
306 case 'T':
307 repeat = you.line;
308 c = 'k';
309 break;
310 case 'K':
311 case 'E':
312 repeat = you.line - money.line;
313 c = 'k';
314 break;
315 case 'P':
316 repeat = ccnt - 1 - you.col;
317 c = 'l';
318 break;
319 case 'L':
320 case 'F':
321 repeat = money.col - you.col;
322 c = 'l';
323 break;
324 case 'B':
325 repeat = lcnt - 1 - you.line;
326 c = 'j';
327 break;
328 case 'J':
329 case 'C':
330 repeat = money.line - you.line;
331 c = 'j';
332 break;
334 for(k=1;k<=repeat;k++){
335 moves++;
336 switch(c) {
337 case 's':
338 case 'h':
339 #ifdef KEY_LEFT
340 case KEY_LEFT:
341 #endif
342 case '\b':
343 if (you.col >0) {
344 if((fast)||(k == 1))
345 pchar(&you,' ');
346 you.col--;
347 if((fast) || (k == repeat) ||
348 (you.col == 0))
349 pchar(&you,ME);
351 break;
352 case 'f':
353 case 'l':
354 #ifdef KEY_RIGHT
355 case KEY_RIGHT:
356 #endif
357 case ' ':
358 if (you.col < ccnt-1) {
359 if((fast)||(k == 1))
360 pchar(&you,' ');
361 you.col++;
362 if((fast) || (k == repeat) ||
363 (you.col == ccnt-1))
364 pchar(&you,ME);
366 break;
367 case CTRL('p'):
368 case 'e':
369 case 'k':
370 #ifdef KEY_UP
371 case KEY_UP:
372 #endif
373 case 'i':
374 if (you.line > 0) {
375 if((fast)||(k == 1))
376 pchar(&you,' ');
377 you.line--;
378 if((fast) || (k == repeat) ||
379 (you.line == 0))
380 pchar(&you,ME);
382 break;
383 case CTRL('n'):
384 case 'c':
385 case 'j':
386 #ifdef KEY_DOWN
387 case KEY_DOWN:
388 #endif
389 case LF:
390 case 'm':
391 if (you.line+1 < lcnt) {
392 if((fast)||(k == 1))
393 pchar(&you,' ');
394 you.line++;
395 if((fast) || (k == repeat) ||
396 (you.line == lcnt-1))
397 pchar(&you,ME);
399 break;
402 if (same(&you,&money))
404 loot += 25;
405 if(k < repeat)
406 pchar(&you,' ');
407 do {
408 snrand(&money);
409 } while ((money.col == finish.col && money.line == finish.line) ||
410 (money.col < 5 && money.line == 0) ||
411 (money.col == you.col && money.line == you.line));
412 pchar(&money,TREASURE);
413 winnings(cashvalue);
414 continue;
416 if (same(&you,&finish))
418 win(&finish);
419 flushi();
420 endwin();
421 printf("You have won with $%d.\n", cashvalue);
422 fflush(stdout);
423 logit("won");
424 post(cashvalue,1);
425 length(moves);
426 exit(0);
428 if (pushsnake())break;
433 void
434 setup(void)
435 { /*
436 * setup the board
438 int i;
440 erase();
441 pchar(&you,ME);
442 pchar(&finish,GOAL);
443 pchar(&money,TREASURE);
444 for(i=1; i<6; i++) {
445 pchar(&snake[i],SNAKETAIL);
447 pchar(&snake[0], SNAKEHEAD);
448 drawbox();
449 refresh();
452 void
453 drawbox(void)
455 int i;
457 for (i = 1; i <= ccnt; i++) {
458 mvaddch(0, i, '-');
459 mvaddch(lcnt + 1, i, '-');
461 for (i = 0; i <= lcnt + 1; i++) {
462 mvaddch(i, 0, '|');
463 mvaddch(i, ccnt + 1, '|');
467 void
468 snrand(struct point *sp)
470 struct point p;
471 int i;
473 for (;;) {
474 p.col = random() % ccnt;
475 p.line = random() % lcnt;
477 /* make sure it's not on top of something else */
478 if (p.line == 0 && p.col < 5)
479 continue;
480 if (same(&p, &you))
481 continue;
482 if (same(&p, &money))
483 continue;
484 if (same(&p, &finish))
485 continue;
486 for (i = 0; i < 6; i++)
487 if (same(&p, &snake[i]))
488 break;
489 if (i < 6)
490 continue;
491 break;
493 *sp = p;
497 post(int iscore, int flag)
499 short score = iscore;
500 short uid;
501 short oldbest=0;
502 short allbwho=0, allbscore=0;
503 struct passwd *p;
505 /* I want to printf() the scores for terms that clear on cook(),
506 * but this routine also gets called with flag == 0 to see if
507 * the snake should wink. If (flag) then we're at game end and
508 * can printf.
511 * Neg uid, 0, and 1 cannot have scores recorded.
513 if ((uid = getuid()) <= 1) {
514 if (flag)
515 printf("No saved scores for uid %d.\n", uid);
516 return(1);
518 if (rawscores < 0) {
519 /* Error reported earlier */
520 return(1);
522 /* Figure out what happened in the past */
523 read(rawscores, &allbscore, sizeof(short));
524 read(rawscores, &allbwho, sizeof(short));
525 lseek(rawscores, ((off_t)uid)*sizeof(short), 0);
526 read(rawscores, &oldbest, sizeof(short));
527 if (!flag) {
528 lseek(rawscores, 0, SEEK_SET);
529 return (score > oldbest ? 1 : 0);
532 /* Update this jokers best */
533 if (score > oldbest) {
534 lseek(rawscores, ((off_t)uid)*sizeof(short), 0);
535 write(rawscores, &score, sizeof(short));
536 printf("You bettered your previous best of $%d\n", oldbest);
537 } else
538 printf("Your best to date is $%d\n", oldbest);
540 /* See if we have a new champ */
541 p = getpwuid(allbwho);
542 if (score > allbscore) {
543 lseek(rawscores, 0, SEEK_SET);
544 write(rawscores, &score, sizeof(short));
545 write(rawscores, &uid, sizeof(short));
546 if (allbwho) {
547 if (p)
548 printf("You beat %s's old record of $%d!\n",
549 p->pw_name, allbscore);
550 else
551 printf("You beat (%d)'s old record of $%d!\n",
552 (int)allbwho, allbscore);
554 else
555 printf("You set a new record!\n");
556 } else if (p)
557 printf("The highest is %s with $%d\n", p->pw_name, allbscore);
558 else
559 printf("The highest is (%d) with $%d\n", (int)allbwho,
560 allbscore);
561 lseek(rawscores, 0, SEEK_SET);
562 return (1);
566 * Flush typeahead to keep from buffering a bunch of chars and then
567 * overshooting. This loses horribly at 9600 baud, but works nicely
568 * if the terminal gets behind.
570 void
571 flushi(void)
573 tcflush(0, TCIFLUSH);
575 int mx [8] = {
576 0, 1, 1, 1, 0,-1,-1,-1};
577 int my [8] = {
578 -1,-1, 0, 1, 1, 1, 0,-1};
579 float absv[8]= {
580 1, 1.4, 1, 1.4, 1, 1.4, 1, 1.4
582 int oldw=0;
584 void
585 chase(struct point *np, struct point *sp)
587 /* this algorithm has bugs; otherwise the
588 snake would get too good */
589 struct point d;
590 int w, i, wt[8];
591 double v1, v2, vp, max;
592 point(&d,you.col-sp->col,you.line-sp->line);
593 v1 = sqrt( (double) (d.col*d.col + d.line*d.line) );
594 w=0;
595 max=0;
596 for(i=0; i<8; i++)
598 vp = d.col*mx[i] + d.line*my[i];
599 v2 = absv[i];
600 if (v1>0)
601 vp = ((double)vp)/(v1*v2);
602 else vp=1.0;
603 if (vp>max)
605 max=vp;
606 w=i;
609 for(i=0; i<8; i++)
611 point(&d,sp->col+mx[i],sp->line+my[i]);
612 wt[i]=0;
613 if (d.col<0 || d.col>=ccnt || d.line<0 || d.line>=lcnt)
614 continue;
616 * Change to allow snake to eat you if you're on the money,
617 * otherwise, you can just crouch there until the snake goes
618 * away. Not positive it's right.
620 * if (d.line == 0 && d.col < 5) continue;
622 if (same(&d,&money)) continue;
623 if (same(&d,&finish)) continue;
624 wt[i]= i==w ? loot/10 : 1;
625 if (i==oldw) wt [i] += loot/20;
627 for(w=i=0; i<8; i++)
628 w+= wt[i];
629 vp = ((random() >> 6) & 01777) % w;
630 for(i=0; i<8; i++)
631 if (vp <wt[i])
632 break;
633 else
634 vp -= wt[i];
635 if (i==8) {
636 printw("failure\n");
637 i=0;
638 while (wt[i]==0) i++;
640 oldw=w=i;
641 point(np,sp->col+mx[w],sp->line+my[w]);
644 void
645 spacewarp(int w)
647 struct point p;
648 int j;
649 const char *str;
651 snrand(&you);
652 point(&p, COLS / 2 - 8, LINES / 2 - 1);
653 if (p.col < 0)
654 p.col = 0;
655 if (p.line < 0)
656 p.line = 0;
657 if (w) {
658 str = "BONUS!!!";
659 loot = loot - penalty;
660 penalty = 0;
661 } else {
662 str = "SPACE WARP!!!";
663 penalty += loot/PENALTY;
665 for(j=0;j<3;j++){
666 erase();
667 refresh();
668 delay(5);
669 mvaddstr(p.line + 1, p.col + 1, str);
670 refresh();
671 delay(10);
673 setup();
674 winnings(cashvalue);
677 void
678 snap(void)
680 if (!stretch(&money))
681 if (!stretch(&finish)) {
682 pchar(&you, '?');
683 refresh();
684 delay(10);
685 pchar(&you, ME);
687 refresh();
691 stretch(const struct point *ps)
693 struct point p;
695 point(&p,you.col,you.line);
696 if ((abs(ps->col - you.col) < (ccnt / 12)) && (you.line != ps->line)) {
697 if(you.line < ps->line){
698 for (p.line = you.line+1;p.line <= ps->line;p.line++)
699 pchar(&p,'v');
700 refresh();
701 delay(10);
702 for (;p.line > you.line;p.line--)
703 chk(&p);
704 } else {
705 for (p.line = you.line-1;p.line >= ps->line;p.line--)
706 pchar(&p,'^');
707 refresh();
708 delay(10);
709 for (;p.line < you.line;p.line++)
710 chk(&p);
712 return(1);
713 } else
714 if ((abs(ps->line - you.line) < (lcnt/7))
715 && (you.col != ps->col)) {
716 p.line = you.line;
717 if(you.col < ps->col){
718 for (p.col = you.col+1;p.col <= ps->col;p.col++)
719 pchar(&p,'>');
720 refresh();
721 delay(10);
722 for (;p.col > you.col;p.col--)
723 chk(&p);
724 } else {
725 for (p.col = you.col-1;p.col >= ps->col;p.col--)
726 pchar(&p,'<');
727 refresh();
728 delay(10);
729 for (;p.col < you.col;p.col++)
730 chk(&p);
732 return(1);
734 return(0);
737 void
738 surround(struct point *ps)
740 int j;
742 if(ps->col == 0)ps->col++;
743 if(ps->line == 0)ps->line++;
744 if(ps->line == LINES -1)ps->line--;
745 if(ps->col == COLS -1)ps->col--;
746 mvaddstr(ps->line, ps->col, "/*\\");
747 mvaddstr(ps->line + 1, ps->col, "* *");
748 mvaddstr(ps->line + 2, ps->col, "\\*/");
749 for (j=0;j<20;j++){
750 pchar(ps,'@');
751 refresh();
752 delay(1);
753 pchar(ps,' ');
754 refresh();
755 delay(1);
757 if (post(cashvalue,0)) {
758 mvaddstr(ps->line, ps->col, " ");
759 mvaddstr(ps->line + 1, ps->col, "o.o");
760 mvaddstr(ps->line + 2, ps->col, "\\_/");
761 refresh();
762 delay(6);
763 mvaddstr(ps->line, ps->col, " ");
764 mvaddstr(ps->line + 1, ps->col, "o.-");
765 mvaddstr(ps->line + 2, ps->col, "\\_/");
766 refresh();
767 delay(6);
769 mvaddstr(ps->line, ps->col, " ");
770 mvaddstr(ps->line + 1, ps->col, "o.o");
771 mvaddstr(ps->line + 2, ps->col, "\\_/");
772 refresh();
773 delay(6);
776 void
777 win(const struct point *ps)
779 struct point x;
780 int j,k;
781 int boxsize; /* actually diameter of box, not radius */
783 boxsize = fast ? 10 : 4;
784 point(&x,ps->col,ps->line);
785 for(j=1;j<boxsize;j++){
786 for(k=0;k<j;k++){
787 pchar(&x,'#');
788 x.line--;
790 for(k=0;k<j;k++){
791 pchar(&x,'#');
792 x.col++;
794 j++;
795 for(k=0;k<j;k++){
796 pchar(&x,'#');
797 x.line++;
799 for(k=0;k<j;k++){
800 pchar(&x,'#');
801 x.col--;
803 refresh();
804 delay(1);
809 pushsnake(void)
811 int i, bonus;
812 int issame = 0;
813 struct point tmp;
816 * My manual says times doesn't return a value. Furthermore, the
817 * snake should get his turn every time no matter if the user is
818 * on a fast terminal with typematic keys or not.
819 * So I have taken the call to times out.
821 for(i=4; i>=0; i--)
822 if (same(&snake[i], &snake[5]))
823 issame++;
824 if (!issame)
825 pchar(&snake[5],' ');
826 /* Need the following to catch you if you step on the snake's tail */
827 tmp.col = snake[5].col;
828 tmp.line = snake[5].line;
829 for(i=4; i>=0; i--)
830 snake[i+1]= snake[i];
831 chase(&snake[0], &snake[1]);
832 pchar(&snake[1],SNAKETAIL);
833 pchar(&snake[0],SNAKEHEAD);
834 for(i=0; i<6; i++)
836 if (same(&snake[i],&you) || same(&tmp, &you))
838 surround(&you);
839 i = (cashvalue) % 10;
840 bonus = ((random() >> 8) & 0377) % 10;
841 mvprintw(lcnt + 1, 0, "%d\n", bonus);
842 refresh();
843 delay(30);
844 if (bonus == i) {
845 spacewarp(1);
846 logit("bonus");
847 flushi();
848 return(1);
850 flushi();
851 endwin();
852 if ( loot >= penalty ){
853 printf("\nYou and your $%d have been eaten\n",
854 cashvalue);
855 } else {
856 printf("\nThe snake ate you. You owe $%d.\n",
857 -cashvalue);
859 logit("eaten");
860 length(moves);
861 exit(0);
864 return(0);
868 chk(const struct point *sp)
870 int j;
872 if (same(sp,&money)) {
873 pchar(sp,TREASURE);
874 return(2);
876 if (same(sp,&finish)) {
877 pchar(sp,GOAL);
878 return(3);
880 if (same(sp,&snake[0])) {
881 pchar(sp,SNAKEHEAD);
882 return(4);
884 for(j=1;j<6;j++){
885 if(same(sp,&snake[j])){
886 pchar(sp,SNAKETAIL);
887 return(4);
890 if ((sp->col < 4) && (sp->line == 0)){
891 winnings(cashvalue);
892 if((you.line == 0) && (you.col < 4)) pchar(&you,ME);
893 return(5);
895 if (same(sp,&you)) {
896 pchar(sp,ME);
897 return(1);
899 pchar(sp,' ');
900 return(0);
903 void
904 winnings(int won)
906 if (won > 0) {
907 mvprintw(1, 1, "$%d", won);
911 void
912 stop(__unused int dummy)
914 signal(SIGINT,SIG_IGN);
915 endwin();
916 length(moves);
917 exit(0);
920 void
921 suspend(void)
923 endwin();
924 kill(getpid(), SIGTSTP);
925 refresh();
926 winnings(cashvalue);
929 void
930 length(int num)
932 printf("You made %d moves.\n", num);
935 void
936 logit(const char *msg)
938 time_t t;
940 if (logfile != NULL) {
941 time(&t);
942 fprintf(logfile, "%s $%d %dx%d %s %s",
943 getlogin(), cashvalue, lcnt, ccnt, msg, ctime(&t));
944 fflush(logfile);