📄 snake.c
字号:
#ifndef lintstatic char sccsid[] = "@(#)snake.c 4.1 (Berkeley) 7/4/83";#endif/* * snake - crt hack game. * * You move around the screen with arrow keys trying to pick up money * without getting eaten by the snake. hjkl work as in vi in place of * arrow keys. You can leave at the exit any time. * * compile as follows: * cc -O snake.c move.c -o snake -lm -ltermlib */#include "snake.h"#include <pwd.h> /* * If CHECKBUSY is defined, the file BUSY must be executable * and must return a value which is used to determine the priority * a which snake runs. A zero value means no nice. * If BUSY does not exist, snake won't play. */#ifndef BUSY#define BUSY "/usr/games/lib/busy"#endif /* * This is the data file for scorekeeping. */#ifndef SNAKERAWSCORES#define SNAKERAWSCORES "/usr/games/lib/snakerawscores"#endif /* * If it exists, a log is kept here. Otherwise it isn't. */#ifndef LOGFILE#define LOGFILE "/usr/games/lib/snake.log"#endif#define PENALTY 10 /* % penalty for invoking spacewarp */#define EOT '\004'#define LF '\n'#define DEL '\177'#define ME 'I'#define SNAKEHEAD 'S'#define SNAKETAIL 's'#define TREASURE '$'#define GOAL '#'#define BSIZE 80struct point you;struct point money;struct point finish;struct point snake[6];int loot, penalty;int long tl, tm=0L;int argcount;char **argval;int moves;static char str[BSIZE];char stri[BSIZE];char *p;char ch, savec;char *kl, *kr, *ku, *kd;int fast=1;int repeat=1;long tv;char *tn;main(argc,argv)int argc;char **argv;{ int i,k; int j; long time(); int stop(); extern char _sobuf[]; argcount = argc; argval = argv; penalty = loot = 0; getcap(); ccnt -= 2; lcnt -= 2; /* compensate for border */ busy(); time(&tv); for (i=1; i<argc; i++) { switch(argv[i][1]) { case 'd': sscanf(argv[1], "-d%ld", &tv); break; case 'w': /* width */ case 'c': /* columns */ ccnt = atoi(argv[i]+2); break; case 'l': /* length */ case 'h': /* height */ case 'r': /* rows */ lcnt = atoi(argv[i]+2); break; default: printf("bad option %s\n", argv[1]); } } srand((int)tv); setbuf(stdout,_sobuf); i = ((lcnt < ccnt) ? lcnt : ccnt); /* min screen edge */ if (i < 4) { printf("Screen too small for a fair game\n"); done(); } /* * chunk is the amount of money the user gets for each $. * The formula below tries to be fair for various screen sizes. * We only pay attention to the smaller of the 2 edges, since * that seems to be the bottleneck. * This formula is a hyperbola which includes the following points: * (24, $25) (original scoring algorithm) * (12, $40) (experimentally derived by the "feel") * (48, $15) (a guess) * This will give a 4x4 screen $99/shot. We don't allow anything * smaller than 4x4 because there is a 3x3 game where you can win * an infinite amount of money. */ if (i < 12) i = 12; /* otherwise it isn't fair */ /* * Compensate for border. This really changes the game since * the screen is two squares smaller but we want the default * to be $25, and the high scores on small screens were a bit * much anyway. */ i += 2; chunk = (675.0 / (i+6)) + 2.5; /* min screen edge */ signal (SIGINT, stop); putpad(TI); /* String to begin programs that use cm */ putpad(KS); /* Put terminal in keypad transmit mode */ random(&finish); random(&you); random(&money); random(&snake[0]); if ((orig.sg_ospeed < B9600) || ((! CM) && (! TA))) fast=0; for(i=1;i<6;i++) chase (&snake[i], &snake[i-1]); setup(); mainloop();}/* Main command loop */mainloop(){ int j, k; for (;;) { int c,lastc,match; move(&you); fflush(stdout); if (((c = getchar() & 0177) <= '9') && (c >= '0')) { ungetc(c,stdin); j = scanf("%d",&repeat); c = getchar() & 0177; } else { if (c != '.') repeat = 1; } if (c == '.') { c = lastc; } if ((Klength > 0) && (c == *KL || c == *KR || c == *KU || c == *KD)) { savec = c; match = 0; kl = KL; kr = KR; ku = KU; kd = KD; for (j=Klength;j>0;j--){ if (match != 1) { match = 0; if (*kl++ == c) { ch = 'h'; match++; } if (*kr++ == c) { ch = 'l'; match++; } if (*ku++ == c) { ch = 'k'; match++; } if (*kd++ == c) { ch = 'j'; match++; } if (match == 0) { ungetc(c,stdin); ch = savec; /* Oops! * This works if we figure it out on second character. */ break; } } savec = c; if(j != 1) c = getchar() & 0177; } c = ch; } if (!fast) flushi(); lastc = c; switch (c){ case CTRL('z'): case CTRL('c'): suspend(); continue; case EOT: case 'x': case 0177: /* del or end of file */ ll(); length(moves); logit("quit"); done(); case '!': cook(); putchar('\n'); putchar(c); fflush(stdout); j = read(0,stri,BSIZE); stri[j] = 0; if (fork() == 0) { setuid(getuid()); system(stri); } else wait(0); printf("READY?\n"); fflush(stdout); raw(); c = getchar(); ungetc(c,stdin); putpad(KS); putpad(TI); point(&cursor,0,lcnt-1); case CTRL('l'): setup(); winnings(cashvalue); continue; case 'p': case 'd': snap(); continue; case 'w': spacewarp(0); continue; case 'A': repeat = you.col; c = 'h'; break; case 'H': case 'S': repeat = you.col - money.col; c = 'h'; break; case 'T': repeat = you.line; c = 'k'; break; case 'K': case 'E': repeat = you.line - money.line; c = 'k'; break; case 'P': repeat = ccnt - 1 - you.col; c = 'l'; break; case 'L': case 'F': repeat = money.col - you.col; c = 'l'; break; case 'B': repeat = lcnt - 1 - you.line; c = 'j'; break; case 'J': case 'C': repeat = money.line - you.line; c = 'j'; break; } for(k=1;k<=repeat;k++){ moves++; switch(c) { case 's': case 'h': case '\b': if (you.col >0) { if((fast)||(k == 1)) pchar(&you,' '); you.col--; if((fast) || (k == repeat) || (you.col == 0)) pchar(&you,ME); } break; case 'f': case 'l': case ' ': if (you.col < ccnt-1) { if((fast)||(k == 1)) pchar(&you,' '); you.col++; if((fast) || (k == repeat) || (you.col == ccnt-1)) pchar(&you,ME); } break; case CTRL('p'): case 'e': case 'k': case 'i': if (you.line > 0) { if((fast)||(k == 1)) pchar(&you,' '); you.line--; if((fast) || (k == repeat) || (you.line == 0)) pchar(&you,ME); } break; case CTRL('n'): case 'c': case 'j': case LF: case 'm': if (you.line+1 < lcnt) { if((fast)||(k == 1)) pchar(&you,' '); you.line++; if((fast) || (k == repeat) || (you.line == lcnt-1)) pchar(&you,ME); } break; } if (same(&you,&money)) { char xp[20]; struct point z; loot += 25; if(k < repeat) pchar(&you,' '); do { random(&money); } while (money.col == finish.col && money.line == finish.line || money.col < 5 && money.line == 0 || money.col == you.col && money.line == you.line); pchar(&money,TREASURE); winnings(cashvalue); continue; } if (same(&you,&finish)) { win(&finish); ll(); cook(); printf("You have won with $%d.\n",cashvalue); fflush(stdout); logit("won"); post(cashvalue,0); length(moves); done(0); } if (pushsnake())break; } fflush(stdout); }}setup(){ /* * setup the board */ int i; clear(); pchar(&you,ME); pchar(&finish,GOAL); pchar(&money,TREASURE); for(i=1; i<6; i++) { pchar(&snake[i],SNAKETAIL); } pchar(&snake[0], SNAKEHEAD); drawbox(); fflush(stdout);}drawbox(){ register int i; struct point p; p.line = -1; for (i= 0; i<ccnt; i++) { p.col = i; pchar(&p, '-'); } p.col = ccnt; for (i= -1; i<=lcnt; i++) { p.line = i; pchar(&p, '|'); } p.col = -1; for (i= -1; i<=lcnt; i++) { p.line = i; pchar(&p, '|'); } p.line = lcnt; for (i= 0; i<ccnt; i++) { p.col = i; pchar(&p, '-'); }}random(sp)struct point *sp;{ register int issame; struct point p; register int i; sp->col = sp->line = -1; /* impossible */ do { issame = 0; p.col = ((rand()>>8) & 0377)% ccnt; p.line = ((rand()>>8) & 0377)% lcnt; /* make sure it's not on top of something else */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -