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