cleanup, add manual page
[unix-history] / usr / src / games / snake / snake / snake.c
CommitLineData
b6f0a7e4
DF
1/*
2 * Copyright (c) 1980 Regents of the University of California.
a825d20f
KB
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
65c7d3b6
KB
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
b6f0a7e4
DF
16 */
17
18#ifndef lint
19char copyright[] =
20"@(#) Copyright (c) 1980 Regents of the University of California.\n\
21 All rights reserved.\n";
a825d20f 22#endif /* not lint */
b6f0a7e4 23
384a101e 24#ifndef lint
65c7d3b6 25static char sccsid[] = "@(#)snake.c 5.6 (Berkeley) %G%";
a825d20f 26#endif /* not lint */
384a101e
SL
27
28/*
29 * snake - crt hack game.
30 *
31 * You move around the screen with arrow keys trying to pick up money
32 * without getting eaten by the snake. hjkl work as in vi in place of
33 * arrow keys. You can leave at the exit any time.
34 *
35 * compile as follows:
36 * cc -O snake.c move.c -o snake -lm -ltermlib
37 */
38
3f63e290 39#include <sys/param.h>
384a101e 40#include <pwd.h>
3f63e290 41#include "snake.h"
384a101e
SL
42
43 /*
44 * This is the data file for scorekeeping.
45 */
46#ifndef SNAKERAWSCORES
47#define SNAKERAWSCORES "/usr/games/lib/snakerawscores"
48#endif
49
50 /*
51 * If it exists, a log is kept here. Otherwise it isn't.
52 */
53#ifndef LOGFILE
54#define LOGFILE "/usr/games/lib/snake.log"
55#endif
56
57#define PENALTY 10 /* % penalty for invoking spacewarp */
58
59#define EOT '\004'
60#define LF '\n'
61#define DEL '\177'
62
63#define ME 'I'
64#define SNAKEHEAD 'S'
65#define SNAKETAIL 's'
66#define TREASURE '$'
67#define GOAL '#'
68
69#define BSIZE 80
70
71struct point you;
72struct point money;
73struct point finish;
74struct point snake[6];
75
76int loot, penalty;
77int long tl, tm=0L;
384a101e 78int moves;
384a101e
SL
79char stri[BSIZE];
80char *p;
81char ch, savec;
82char *kl, *kr, *ku, *kd;
83int fast=1;
84int repeat=1;
85long tv;
86char *tn;
87
88main(argc,argv)
89int argc;
90char **argv;
91{
3f63e290
KB
92 extern char *optarg;
93 extern int optind;
94 int ch, i, j, k;
95 time_t time();
96 long atol();
384a101e 97 int stop();
384a101e 98
3f63e290
KB
99 (void)time(&tv);
100 srandom((int)tv);
384a101e 101
3f63e290
KB
102 while ((ch = getopt(argc, argv, "l:w:")) != EOF)
103 switch((char)ch) {
104#ifdef notdef
384a101e 105 case 'd':
3f63e290 106 tv = atol(optarg);
384a101e 107 break;
3f63e290 108#endif
384a101e 109 case 'w': /* width */
3f63e290 110 ccnt = atoi(optarg);
384a101e
SL
111 break;
112 case 'l': /* length */
3f63e290 113 lcnt = atoi(optarg);
384a101e 114 break;
3f63e290 115 case '?':
384a101e 116 default:
3f63e290
KB
117 fputs("usage: snake [-d seed] [-w width] [-l length]\n", stderr);
118 exit(1);
384a101e 119 }
384a101e 120
3f63e290
KB
121 penalty = loot = 0;
122 getcap();
123
124 i = MIN(lcnt, ccnt);
384a101e 125 if (i < 4) {
3f63e290
KB
126 cook();
127 printf("snake: screen too small for a fair game.\n");
128 exit(1);
384a101e 129 }
3f63e290 130
384a101e
SL
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
3f63e290
KB
158 snrand(&finish);
159 snrand(&you);
160 snrand(&money);
161 snrand(&snake[0]);
384a101e
SL
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 */
172mainloop()
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){
36c966f5 235 case CTRL('z'):
384a101e
SL
236 suspend();
237 continue;
238 case EOT:
239 case 'x':
240 case 0177: /* del or end of file */
241 ll();
242 length(moves);
243 logit("quit");
244 done();
36c966f5 245 case CTRL('l'):
384a101e
SL
246 setup();
247 winnings(cashvalue);
248 continue;
249 case 'p':
250 case 'd':
251 snap();
252 continue;
253 case 'w':
254 spacewarp(0);
255 continue;
256 case 'A':
257 repeat = you.col;
258 c = 'h';
259 break;
260 case 'H':
261 case 'S':
262 repeat = you.col - money.col;
263 c = 'h';
264 break;
265 case 'T':
266 repeat = you.line;
267 c = 'k';
268 break;
269 case 'K':
270 case 'E':
271 repeat = you.line - money.line;
272 c = 'k';
273 break;
274 case 'P':
275 repeat = ccnt - 1 - you.col;
276 c = 'l';
277 break;
278 case 'L':
279 case 'F':
280 repeat = money.col - you.col;
281 c = 'l';
282 break;
283 case 'B':
284 repeat = lcnt - 1 - you.line;
285 c = 'j';
286 break;
287 case 'J':
288 case 'C':
289 repeat = money.line - you.line;
290 c = 'j';
291 break;
292 }
293 for(k=1;k<=repeat;k++){
294 moves++;
295 switch(c) {
296 case 's':
297 case 'h':
298 case '\b':
299 if (you.col >0) {
300 if((fast)||(k == 1))
301 pchar(&you,' ');
302 you.col--;
303 if((fast) || (k == repeat) ||
304 (you.col == 0))
305 pchar(&you,ME);
306 }
307 break;
308 case 'f':
309 case 'l':
310 case ' ':
311 if (you.col < ccnt-1) {
312 if((fast)||(k == 1))
313 pchar(&you,' ');
314 you.col++;
315 if((fast) || (k == repeat) ||
316 (you.col == ccnt-1))
317 pchar(&you,ME);
318 }
319 break;
36c966f5 320 case CTRL('p'):
384a101e
SL
321 case 'e':
322 case 'k':
323 case 'i':
324 if (you.line > 0) {
325 if((fast)||(k == 1))
326 pchar(&you,' ');
327 you.line--;
328 if((fast) || (k == repeat) ||
329 (you.line == 0))
330 pchar(&you,ME);
331 }
332 break;
36c966f5 333 case CTRL('n'):
384a101e
SL
334 case 'c':
335 case 'j':
336 case LF:
337 case 'm':
338 if (you.line+1 < lcnt) {
339 if((fast)||(k == 1))
340 pchar(&you,' ');
341 you.line++;
342 if((fast) || (k == repeat) ||
343 (you.line == lcnt-1))
344 pchar(&you,ME);
345 }
346 break;
347 }
348
349 if (same(&you,&money))
350 {
351 char xp[20];
352 struct point z;
353 loot += 25;
354 if(k < repeat)
355 pchar(&you,' ');
356 do {
3f63e290 357 snrand(&money);
384a101e
SL
358 } while (money.col == finish.col && money.line == finish.line ||
359 money.col < 5 && money.line == 0 ||
360 money.col == you.col && money.line == you.line);
361 pchar(&money,TREASURE);
362 winnings(cashvalue);
363 continue;
364 }
365 if (same(&you,&finish))
366 {
367 win(&finish);
368 ll();
369 cook();
370 printf("You have won with $%d.\n",cashvalue);
371 fflush(stdout);
372 logit("won");
373 post(cashvalue,0);
374 length(moves);
3f63e290 375 done();
384a101e
SL
376 }
377 if (pushsnake())break;
378 }
379 fflush(stdout);
380 }
381}
382
383setup(){ /*
384 * setup the board
385 */
386 int i;
387
388 clear();
389 pchar(&you,ME);
390 pchar(&finish,GOAL);
391 pchar(&money,TREASURE);
392 for(i=1; i<6; i++) {
393 pchar(&snake[i],SNAKETAIL);
394 }
395 pchar(&snake[0], SNAKEHEAD);
396 drawbox();
397 fflush(stdout);
398}
399
400drawbox()
401{
402 register int i;
403 struct point p;
404
405 p.line = -1;
406 for (i= 0; i<ccnt; i++) {
407 p.col = i;
408 pchar(&p, '-');
409 }
410 p.col = ccnt;
411 for (i= -1; i<=lcnt; i++) {
412 p.line = i;
413 pchar(&p, '|');
414 }
415 p.col = -1;
416 for (i= -1; i<=lcnt; i++) {
417 p.line = i;
418 pchar(&p, '|');
419 }
420 p.line = lcnt;
421 for (i= 0; i<ccnt; i++) {
422 p.col = i;
423 pchar(&p, '-');
424 }
425}
426
3f63e290 427snrand(sp)
384a101e
SL
428struct point *sp;
429{
384a101e
SL
430 struct point p;
431 register int i;
432
3f63e290
KB
433 for (;;) {
434 p.col = random() % ccnt;
435 p.line = random() % lcnt;
384a101e
SL
436
437 /* make sure it's not on top of something else */
3f63e290
KB
438 if (p.line == 0 && p.col < 5)
439 continue;
440 if (same(&p, &you))
441 continue;
442 if (same(&p, &money))
443 continue;
444 if (same(&p, &finish))
445 continue;
446 for (i = 0; i < 5; i++)
447 if (same(&p, &snake[i]))
448 break;
449 if (i < 5)
450 continue;
451 break;
452 }
384a101e
SL
453 *sp = p;
454}
455
7cfc1f81
S
456post(iscore, flag)
457int iscore, flag;
384a101e 458{
7cfc1f81 459 short score = iscore;
384a101e 460 int rawscores;
7cfc1f81 461 short uid;
384a101e
SL
462 short oldbest=0;
463 short allbwho=0, allbscore=0;
464 struct passwd *p, *getpwuid();
465
466 /*
467 * Neg uid, 0, and 1 cannot have scores recorded.
468 */
469 if ((uid=getuid()) > 1 && (rawscores=open(SNAKERAWSCORES,2))>=0) {
470 /* Figure out what happened in the past */
471 read(rawscores, &allbscore, sizeof(short));
472 read(rawscores, &allbwho, sizeof(short));
473 lseek(rawscores, ((long)uid)*sizeof(short), 0);
474 read(rawscores, &oldbest, sizeof(short));
475 if (flag) return (score > oldbest ? 1 : 0);
476
477 /* Update this jokers best */
478 if (score > oldbest) {
479 lseek(rawscores, ((long)uid)*sizeof(short), 0);
480 write(rawscores, &score, sizeof(short));
481 printf("You bettered your previous best of $%d\n", oldbest);
482 } else
483 printf("Your best to date is $%d\n", oldbest);
484
485 /* See if we have a new champ */
486 p = getpwuid(allbwho);
487 if (p == NULL || score > allbscore) {
488 lseek(rawscores, (long)0, 0);
489 write(rawscores, &score, sizeof(short));
490 write(rawscores, &uid, sizeof(short));
491 if (p != NULL)
492 printf("You beat %s's old record of $%d!\n", p->pw_name, allbscore);
493 else
494 printf("You set a new record!\n");
495 } else
496 printf("The highest is %s with $%d\n", p->pw_name, allbscore);
497 close(rawscores);
498 } else
499 if (!flag)
500 printf("Unable to post score.\n");
501 return (1);
502}
503
504/*
505 * Flush typeahead to keep from buffering a bunch of chars and then
506 * overshooting. This loses horribly at 9600 baud, but works nicely
507 * if the terminal gets behind.
508 */
509flushi()
510{
511 stty(0, &new);
512}
513int mx [8] = {
514 0, 1, 1, 1, 0,-1,-1,-1};
515int my [8] = {
516 -1,-1, 0, 1, 1, 1, 0,-1};
517float absv[8]= {
518 1, 1.4, 1, 1.4, 1, 1.4, 1, 1.4
519};
520int oldw=0;
521chase (np, sp)
522struct point *sp, *np;
523{
524 /* this algorithm has bugs; otherwise the
525 snake would get too good */
526 struct point d;
527 int w, i, wt[8];
528 double sqrt(), v1, v2, vp, max;
529 point(&d,you.col-sp->col,you.line-sp->line);
530 v1 = sqrt( (double) (d.col*d.col + d.line*d.line) );
531 w=0;
532 max=0;
533 for(i=0; i<8; i++)
534 {
535 vp = d.col*mx[i] + d.line*my[i];
536 v2 = absv[i];
537 if (v1>0)
538 vp = ((double)vp)/(v1*v2);
539 else vp=1.0;
540 if (vp>max)
541 {
542 max=vp;
543 w=i;
544 }
545 }
546 for(i=0; i<8; i++)
547 {
548 point(&d,sp->col+mx[i],sp->line+my[i]);
549 wt[i]=0;
550 if (d.col<0 || d.col>=ccnt || d.line<0 || d.line>=lcnt)
551 continue;
3f63e290
KB
552 /*
553 * Change to allow snake to eat you if you're on the money,
554 * otherwise, you can just crouch there until the snake goes
555 * away. Not positive it's right.
556 *
557 * if (d.line == 0 && d.col < 5) continue;
558 */
384a101e
SL
559 if (same(&d,&money)) continue;
560 if (same(&d,&finish)) continue;
561 wt[i]= i==w ? loot/10 : 1;
562 if (i==oldw) wt [i] += loot/20;
563 }
564 for(w=i=0; i<8; i++)
565 w+= wt[i];
566 vp = (( rand() >> 6 ) & 01777) %w;
567 for(i=0; i<8; i++)
568 if (vp <wt[i])
569 break;
570 else
571 vp -= wt[i];
572 if (i==8) {
573 printf("failure\n");
574 i=0;
575 while (wt[i]==0) i++;
576 }
577 oldw=w=i;
578 point(np,sp->col+mx[w],sp->line+my[w]);
579}
580
581spacewarp(w)
582int w;{
583 struct point p;
584 int j;
3f63e290
KB
585 char *str;
586
587 snrand(&you);
384a101e
SL
588 point(&p,COLUMNS/2 - 8,LINES/2 - 1);
589 if (p.col < 0)
590 p.col = 0;
591 if (p.line < 0)
592 p.line = 0;
593 if (w) {
3f63e290 594 str = "BONUS!!!";
384a101e
SL
595 loot = loot - penalty;
596 penalty = 0;
597 } else {
3f63e290 598 str = "SPACE WARP!!!";
384a101e
SL
599 penalty += loot/PENALTY;
600 }
601 for(j=0;j<3;j++){
602 clear();
603 delay(5);
604 aprintf(&p,str);
605 delay(10);
606 }
607 setup();
608 winnings(cashvalue);
609}
610snap()
611{
612 struct point p;
613 int i;
614
615 if(you.line < 3){
616 pchar(point(&p,you.col,0),'-');
617 }
618 if(you.line > lcnt-4){
619 pchar(point(&p,you.col,lcnt-1),'_');
620 }
621 if(you.col < 10){
622 pchar(point(&p,0,you.line),'(');
623 }
624 if(you.col > ccnt-10){
625 pchar(point(&p,ccnt-1,you.line),')');
626 }
627 if (! stretch(&money)) if (! stretch(&finish)) delay(10);
628 if(you.line < 3){
629 point(&p,you.col,0);
630 remove(&p);
631 }
632 if(you.line > lcnt-4){
633 point(&p,you.col,lcnt-1);
634 remove(&p);
635 }
636 if(you.col < 10){
637 point(&p,0,you.line);
638 remove(&p);
639 }
640 if(you.col > ccnt-10){
641 point(&p,ccnt-1,you.line);
642 remove(&p);
643 }
644 fflush(stdout);
645}
646stretch(ps)
647struct point *ps;{
648 struct point p;
3f63e290 649
384a101e
SL
650 point(&p,you.col,you.line);
651 if(abs(ps->col-you.col) < 6){
652 if(you.line < ps->line){
653 for (p.line = you.line+1;p.line <= ps->line;p.line++)
654 pchar(&p,'v');
655 delay(10);
656 for (;p.line > you.line;p.line--)
657 remove(&p);
658 } else {
659 for (p.line = you.line-1;p.line >= ps->line;p.line--)
660 pchar(&p,'^');
661 delay(10);
662 for (;p.line < you.line;p.line++)
663 remove(&p);
664 }
665 return(1);
666 } else if(abs(ps->line-you.line) < 3){
667 p.line = you.line;
668 if(you.col < ps->col){
669 for (p.col = you.col+1;p.col <= ps->col;p.col++)
670 pchar(&p,'>');
671 delay(10);
672 for (;p.col > you.col;p.col--)
673 remove(&p);
674 } else {
675 for (p.col = you.col-1;p.col >= ps->col;p.col--)
676 pchar(&p,'<');
677 delay(10);
678 for (;p.col < you.col;p.col++)
679 remove(&p);
680 }
681 return(1);
682 }
683 return(0);
684}
685
686surround(ps)
687struct point *ps;{
688 struct point x;
689 int i,j;
690
691 if(ps->col == 0)ps->col++;
692 if(ps->line == 0)ps->line++;
693 if(ps->line == LINES -1)ps->line--;
694 if(ps->col == COLUMNS -1)ps->col--;
695 aprintf(point(&x,ps->col-1,ps->line-1),"/*\\\r* *\r\\*/");
696 for (j=0;j<20;j++){
697 pchar(ps,'@');
698 delay(1);
699 pchar(ps,' ');
700 delay(1);
701 }
702 if (post(cashvalue,1)) {
703 aprintf(point(&x,ps->col-1,ps->line-1)," \ro.o\r\\_/");
704 delay(6);
705 aprintf(point(&x,ps->col-1,ps->line-1)," \ro.-\r\\_/");
706 delay(6);
707 }
708 aprintf(point(&x,ps->col-1,ps->line-1)," \ro.o\r\\_/");
709}
710win(ps)
711struct point *ps;
712{
713 struct point x;
714 int j,k;
715 int boxsize; /* actually diameter of box, not radius */
716
717 boxsize = fast ? 10 : 4;
718 point(&x,ps->col,ps->line);
719 for(j=1;j<boxsize;j++){
720 for(k=0;k<j;k++){
721 pchar(&x,'#');
722 x.line--;
723 }
724 for(k=0;k<j;k++){
725 pchar(&x,'#');
726 x.col++;
727 }
728 j++;
729 for(k=0;k<j;k++){
730 pchar(&x,'#');
731 x.line++;
732 }
733 for(k=0;k<j;k++){
734 pchar(&x,'#');
735 x.col--;
736 }
737 }
738 fflush(stdout);
739}
740
741pushsnake()
742{
743 int i, bonus;
744 int issame = 0;
745
746 /*
747 * My manual says times doesn't return a value. Furthermore, the
748 * snake should get his turn every time no matter if the user is
749 * on a fast terminal with typematic keys or not.
750 * So I have taken the call to times out.
751 */
752 for(i=4; i>=0; i--)
753 if (same(&snake[i], &snake[5]))
754 issame++;
755 if (!issame)
756 pchar(&snake[5],' ');
757 for(i=4; i>=0; i--)
758 snake[i+1]= snake[i];
759 chase(&snake[0], &snake[1]);
760 pchar(&snake[1],SNAKETAIL);
761 pchar(&snake[0],SNAKEHEAD);
762 for(i=0; i<6; i++)
763 {
764 if (same(&snake[i],&you))
765 {
766 surround(&you);
767 i = (cashvalue) % 10;
768 bonus = ((rand()>>8) & 0377)% 10;
769 ll();
770 printf("%d\n", bonus);
771 delay(30);
772 if (bonus == i) {
773 spacewarp(1);
774 logit("bonus");
775 flushi();
776 return(1);
777 }
778 if ( loot >= penalty ){
779 printf("You and your $%d have been eaten\n",cashvalue);
780 } else {
781 printf("The snake ate you. You owe $%d.\n",-cashvalue);
782 }
783 logit("eaten");
784 length(moves);
785 done();
786 }
787 }
788 return(0);
789}
790
791remove(sp)
792struct point *sp;
793{
794 int j;
795
796 if (same(sp,&money)) {
797 pchar(sp,TREASURE);
798 return(2);
799 }
800 if (same(sp,&finish)) {
801 pchar(sp,GOAL);
802 return(3);
803 }
804 if (same(sp,&snake[0])) {
805 pchar(sp,SNAKEHEAD);
806 return(4);
807 }
808 for(j=1;j<6;j++){
809 if(same(sp,&snake[j])){
810 pchar(sp,SNAKETAIL);
811 return(4);
812 }
813 }
814 if ((sp->col < 4) && (sp->line == 0)){
815 winnings(cashvalue);
816 if((you.line == 0) && (you.col < 4)) pchar(&you,ME);
817 return(5);
818 }
819 if (same(sp,&you)) {
820 pchar(sp,ME);
821 return(1);
822 }
823 pchar(sp,' ');
824 return(0);
825}
826winnings(won)
827int won;
828{
829 struct point p;
830
831 p.line = p.col = 1;
832 if(won>0){
833 move(&p);
834 printf("$%d",won);
835 }
836}
837
838stop(){
839 signal(SIGINT,1);
840 ll();
841 length(moves);
842 done();
843}
844
845suspend()
846{
847 char *sh;
848
3f63e290 849 ll();
384a101e 850 cook();
384a101e 851 kill(getpid(), SIGTSTP);
384a101e
SL
852 raw();
853 setup();
854 winnings(cashvalue);
855}
856
857length(num)
858int num;
859{
860 printf("You made %d moves.\n",num);
861}
862
863logit(msg)
864char *msg;
865{
866 FILE *logfile;
867 long t;
868
869 if ((logfile=fopen(LOGFILE, "a")) != NULL) {
870 time(&t);
871 fprintf(logfile, "%s $%d %dx%d %s %s", getlogin(), cashvalue, lcnt, ccnt, msg, ctime(&t));
872 fclose(logfile);
873 }
874}