snake.c revision 1.3
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
35char 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";*/
42static 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
79struct point you;
80struct point money;
81struct point finish;
82struct point snake[6];
83
84int loot, penalty;
85int long tl, tm=0L;
86int moves;
87char stri[BSIZE];
88char *p;
89char ch, savec;
90char *kl, *kr, *ku, *kd;
91int fast=1;
92int repeat=1;
93long tv;
94char *tn;
95
96main(argc,argv)
97int argc;
98char **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 */
178mainloop()
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
389setup(){	/*
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
406drawbox()
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
433snrand(sp)
434struct 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
462post(iscore, flag)
463int	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 */
522flushi()
523{
524	stty(0, &new);
525}
526int mx [8] = {
527	0, 1, 1, 1, 0,-1,-1,-1};
528int my [8] = {
529	-1,-1, 0, 1, 1, 1, 0,-1};
530float absv[8]= {
531	1, 1.4, 1, 1.4, 1, 1.4, 1, 1.4
532};
533int oldw=0;
534chase (np, sp)
535struct 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
594spacewarp(w)
595int 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}
623snap()
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}
659stretch(ps)
660struct 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
699surround(ps)
700struct 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}
723win(ps)
724struct 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
754pushsnake()
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
806chk(sp)
807struct 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}
841winnings(won)
842int 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
853void
854stop(){
855	signal(SIGINT,SIG_IGN);
856	ll();
857	length(moves);
858	done();
859}
860
861suspend()
862{
863	char *sh;
864
865	ll();
866	cook();
867	kill(getpid(), SIGTSTP);
868	raw();
869	setup();
870	winnings(cashvalue);
871}
872
873length(num)
874int num;
875{
876	pr("You made %d moves.\n",num);
877}
878
879logit(msg)
880char *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}
892