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