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