diff options
author | Paul Janzen <pjanzen@cvs.openbsd.org> | 1999-03-13 02:08:21 +0000 |
---|---|---|
committer | Paul Janzen <pjanzen@cvs.openbsd.org> | 1999-03-13 02:08:21 +0000 |
commit | 606df7dfe35de43c6dad31da7b4a55bbab43c0e0 (patch) | |
tree | 2cdb636e7396f5677faebc5ec4635f1ec56c4e8e /games | |
parent | 82e562898d3caaa66b6c64b435bd0bb619faa450 (diff) |
Fix a few bugs (e.g. snake used to miss turns); use usleep() so display
speed is correct on xterms; put snscore functionality inside snake and
make snscore a symbolic link (to be phased out); clean up formatting;
install score file properly; disable the log file by default (logging should
be done through dm).
Diffstat (limited to 'games')
-rw-r--r-- | games/snake/Makefile | 18 | ||||
-rw-r--r-- | games/snake/move.c (renamed from games/snake/snake/move.c) | 410 | ||||
-rw-r--r-- | games/snake/pathnames.h (renamed from games/snake/snake/pathnames.h) | 3 | ||||
-rw-r--r-- | games/snake/snake.6 (renamed from games/snake/snake/snake.6) | 28 | ||||
-rw-r--r-- | games/snake/snake.c (renamed from games/snake/snake/snake.c) | 708 | ||||
-rw-r--r-- | games/snake/snake.h (renamed from games/snake/snake/snake.h) | 86 | ||||
-rw-r--r-- | games/snake/snake/Makefile | 12 | ||||
-rw-r--r-- | games/snake/snscore.c (renamed from games/snake/snscore/snscore.c) | 55 | ||||
-rw-r--r-- | games/snake/snscore/Makefile | 10 |
9 files changed, 735 insertions, 595 deletions
diff --git a/games/snake/Makefile b/games/snake/Makefile index 9b1a192ad10..3907cbed636 100644 --- a/games/snake/Makefile +++ b/games/snake/Makefile @@ -1,5 +1,17 @@ -# $OpenBSD: Makefile,v 1.2 1997/09/21 11:37:03 deraadt Exp $ +# $OpenBSD: Makefile,v 1.3 1999/03/13 02:08:09 pjanzen Exp $ +# @(#)Makefile 8.1 (Berkeley) 5/31/93 -SUBDIR= snake snscore +PROG= snake +SRCS= snake.c move.c snscore.c +MAN= snake.6 +DPADD= ${LIBM} ${LIBCURSES} +LDADD= -lm -lcurses +HIDEGAME=hidegame -.include <bsd.subdir.mk> +beforeinstall: + ${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} -m 664 /dev/null \ + ${DESTDIR}/var/games/snakerawscores + (cd ${DESTDIR}/usr/games; rm -f snscore; ln -s dm snscore) + (cd ${DESTDIR}/usr/games/hide; rm -f snscore; ln -s snake snscore) + +.include <bsd.prog.mk> diff --git a/games/snake/snake/move.c b/games/snake/move.c index a55244ed387..df8d50e1706 100644 --- a/games/snake/snake/move.c +++ b/games/snake/move.c @@ -1,3 +1,4 @@ +/* $OpenBSD: move.c,v 1.1 1999/03/13 02:08:09 pjanzen Exp $ */ /* $NetBSD: move.c,v 1.12 1996/05/19 20:22:09 pk Exp $ */ /* @@ -37,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)move.c 8.1 (Berkeley) 7/19/93"; #else -static char rcsid[] = "$NetBSD: move.c,v 1.12 1996/05/19 20:22:09 pk Exp $"; +static char rcsid[] = "$OpenBSD: move.c,v 1.1 1999/03/13 02:08:09 pjanzen Exp $"; #endif #endif /* not lint */ @@ -86,7 +87,8 @@ static char rcsid[] = "$NetBSD: move.c,v 1.12 1996/05/19 20:22:09 pk Exp $"; * getcap() initializes strings for later calls. * cap(string) outputs the string designated in the termcap * data base. (Should not move the cursor.) - * done() returns the terminal to intial state and exits. + * + * cook() returns the terminal to initial state. * * point(&p,x,y) return point set to x,y. * @@ -101,30 +103,36 @@ static char rcsid[] = "$NetBSD: move.c,v 1.12 1996/05/19 20:22:09 pk Exp $"; #else #include <varargs.h> #endif +#include <err.h> +#include <stdlib.h> +#include <term.h> +#include <unistd.h> #include "snake.h" -int CMlength; -int NDlength; -int BSlength; -int delaystr[10]; -speed_t ospeed; +int CMlength; +int NDlength; +int BSlength; +int delaystr[10]; +speed_t ospeed; static char str[80]; +void move(sp) -struct point *sp; + struct point *sp; { - int distance; - int tabcol,ct; + int distance; + int tabcol, ct; struct point z; - if (sp->line <0 || sp->col <0 || sp->col > COLUMNS){ - pr("move to [%d,%d]?",sp->line,sp->col); + if (sp->line < 0 || sp->col < 0 || sp->col > COLUMNS) { + pr("move to [%d,%d]?", sp->line, sp->col); return; } - if (sp->line >= LINES){ - move(point(&z,sp->col,LINES-1)); - while(sp->line-- >= LINES)putchar('\n'); + if (sp->line >= LINES) { + move(point(&z, sp->col, LINES - 1)); + while (sp->line-- >= LINES) + putchar('\n'); return; } @@ -132,34 +140,35 @@ struct point *sp; char *cmstr = tgoto(CM, sp->col, sp->line); CMlength = strlen(cmstr); - if(cursor.line == sp->line){ + if (cursor.line == sp->line) { distance = sp->col - cursor.col; - if(distance == 0)return; /* Already there! */ - if(distance > 0){ /* Moving to the right */ - if(distance*NDlength < CMlength){ + if (distance == 0) + return; /* Already there! */ + if (distance > 0) { /* Moving to the right */ + if (distance * NDlength < CMlength) { right(sp); return; } - if(TA){ - ct=sp->col&7; - tabcol=(cursor.col|7)+1; - do{ + if (TA) { + ct = sp->col & 7; + tabcol = (cursor.col | 7) + 1; + do { ct++; - tabcol=(tabcol|7)+1; + tabcol = (tabcol | 7) + 1; } - while(tabcol<sp->col); - if(ct<CMlength){ + while (tabcol < sp->col); + if (ct<CMlength) { right(sp); return; } } } else { /* Moving to the left */ - if (-distance*BSlength < CMlength){ + if (-distance * BSlength < CMlength) { gto(sp); return; } } - if(sp->col < CMlength){ + if (sp->col < CMlength) { cr(); right(sp); return; @@ -168,18 +177,17 @@ struct point *sp; } distance = sp->col - cursor.col; distance = distance > 0 ? - distance*NDlength : -distance * BSlength; + distance * NDlength : -distance * BSlength; if (distance < 0) - pr("ERROR: distance is negative: %d",distance); + pr("ERROR: distance is negative: %d", distance); distance += abs(sp->line - cursor.line); - if(distance >= CMlength){ + if (distance >= CMlength) { putpad(cmstr); cursor.line = sp->line; cursor.col = sp->col; return; } } - /* * If we get here we have a terminal that can't cursor * address but has local motions or one which can cursor @@ -187,45 +195,44 @@ struct point *sp; */ gto(sp); } + +void gto(sp) -struct point *sp; + struct point *sp; { - - int distance,f,tfield,j; + int distance, f, tfield; if (cursor.line > LINES || cursor.line <0 || - cursor.col <0 || cursor.col > COLUMNS) - pr("ERROR: cursor is at %d,%d\n", - cursor.line,cursor.col); - if (sp->line > LINES || sp->line <0 || - sp->col <0 || sp->col > COLUMNS) - pr("ERROR: target is %d,%d\n",sp->line,sp->col); + cursor.col <0 || cursor.col > COLUMNS) + pr("ERROR: cursor is at %d,%d\n", cursor.line, cursor.col); + if (sp->line > LINES || sp->line < 0 || sp->col < 0 || sp->col > COLUMNS) + pr("ERROR: target is %d,%d\n", sp->line, sp->col); tfield = (sp->col) >> 3; - if (sp->line == cursor.line){ - if (sp->col > cursor.col)right(sp); - else{ - distance = (cursor.col -sp->col)*BSlength; - if (((TA) && - (distance > tfield+((sp->col)&7)*NDlength) - ) || - (((cursor.col)*NDlength) < distance) - ){ + if (sp->line == cursor.line) { + if (sp->col > cursor.col) + right(sp); + else { + distance = (cursor.col - sp->col) * BSlength; + if (((TA) && (distance > tfield + ((sp->col) & 7) * NDlength)) || + (((cursor.col)*NDlength) < distance)) { cr(); right(sp); - } - else{ - while(cursor.col > sp->col) bs(); + } else { + while(cursor.col > sp->col) + bs(); } } return; } /*must change row */ - if (cursor.col - sp->col > (cursor.col >> 3)){ - if (cursor.col == 0)f = 0; - else f = -1; + if (cursor.col - sp->col > (cursor.col >> 3)) { + if (cursor.col == 0) + f = 0; + else + f = -1; } else f = cursor.col >> 3; - if (((sp->line << 1) + 1 < cursor.line - f) && (HO != 0)){ + if (((sp->line << 1) + 1 < cursor.line - f) && (HO != 0)) { /* * home quicker than rlf: * (sp->line + f > cursor.line - sp->line) @@ -235,11 +242,11 @@ struct point *sp; gto(sp); return; } - if (((sp->line << 1) > cursor.line + LINES+1 + f) && (LL != 0)){ + if (((sp->line << 1) > cursor.line + LINES + 1 + f) && (LL != 0)) { /* home,rlf quicker than lf * (LINES+1 - sp->line + f < sp->line - cursor.line) */ - if (cursor.line > f + 1){ + if (cursor.line > f + 1) { /* is home faster than wraparound lf? * (cursor.line + 20 - sp->line > 21 - sp->line + f) */ @@ -250,20 +257,23 @@ struct point *sp; } if ((LL != 0) && (sp->line > cursor.line + (LINES >> 1) - 1)) cursor.line += LINES; - while(sp->line > cursor.line)down(); - while(sp->line < cursor.line)up(); + while(sp->line > cursor.line) + down(); + while(sp->line < cursor.line) + up(); gto(sp); /*can recurse since cursor.line = sp->line */ } +void right(sp) -struct point *sp; + struct point *sp; { - int field,tfield; - int tabcol,strlength; + int field, tfield; + int tabcol, strlength; if (sp->col < cursor.col) pr("ERROR:right() can't move left\n"); - if(TA){ /* If No Tabs: can't send tabs because ttydrive + if (TA) { /* If No Tabs: can't send tabs because ttydrive * loses count with control characters. */ field = cursor.col >> 3; @@ -274,54 +284,56 @@ struct point *sp; * have addressible cursors, too). */ if (BW && (CM == 0) && - ((sp->col << 1) - field > (COLUMNS - 8) << 1 ) - ){ - if (cursor.line == 0){ + ((sp->col << 1) - field > (COLUMNS - 8) << 1 )) { + if (cursor.line == 0) outch('\n'); - } outch('\r'); cursor.col = COLUMNS + 1; - while(cursor.col > sp->col)bs(); - if (cursor.line != 0) outch('\n'); + while (cursor.col > sp->col) + bs(); + if (cursor.line != 0) + outch('\n'); return; } - tfield = sp->col >> 3; - while (field < tfield){ + while (field < tfield) { putpad(TA); cursor.col = ++field << 3; } - tabcol = (cursor.col|7) + 1; - strlength = (tabcol - sp->col)*BSlength + 1; + tabcol = (cursor.col | 7) + 1; + strlength = (tabcol - sp->col) * BSlength + 1; /* length of sequence to overshoot */ - if (((sp->col - cursor.col)*NDlength > strlength) && + if (((sp->col - cursor.col) * NDlength > strlength) && (tabcol < COLUMNS) ){ - /* - * Tab past and backup - */ + /* Tab past and backup */ putpad(TA); cursor.col = (cursor.col | 7) + 1; - while(cursor.col > sp->col)bs(); + while(cursor.col > sp->col) + bs(); } } - while (sp->col > cursor.col){ + while (sp->col > cursor.col) { nd(); } } -cr(){ +void +cr() +{ outch('\r'); cursor.col = 0; } -clear(){ +void +clear() +{ int i; if (CL){ putpad(CL); - cursor.col=cursor.line=0; + cursor.col = cursor.line = 0; } else { for(i=0; i<LINES; i++) { putchar('\n'); @@ -331,10 +343,12 @@ clear(){ } } -home(){ +void +home() +{ struct point z; - if(HO != 0){ + if (HO != 0) { putpad(HO); cursor.col = cursor.line = 0; return; @@ -343,50 +357,65 @@ home(){ move(&z); } -ll(){ - int j,l; +void +ll() +{ + int l; struct point z; l = lcnt + 2; - if(LL != NULL && LINES==l){ + if (LL != NULL && LINES == l) { putpad(LL); - cursor.line = LINES-1; + cursor.line = LINES - 1; cursor.col = 0; return; } z.col = 0; - z.line = l-1; + z.line = l - 1; move(&z); } -up(){ +void +up() +{ putpad(UP); cursor.line--; } -down(){ +void +down() +{ putpad(DO); cursor.line++; - if (cursor.line >= LINES)cursor.line=LINES-1; + if (cursor.line >= LINES) + cursor.line = LINES - 1; } -bs(){ - if (cursor.col > 0){ + +void +bs() +{ + if (cursor.col > 0) { putpad(BS); cursor.col--; } } -nd(){ +void +nd() +{ putpad(ND); cursor.col++; - if (cursor.col == COLUMNS+1){ + if (cursor.col == COLUMNS + 1) { cursor.line++; cursor.col = 0; - if (cursor.line >= LINES)cursor.line=LINES-1; + if (cursor.line >= LINES) + cursor.line = LINES - 1; } } +void pch(c) + int c; { outch(c); if(++cursor.col >= COLUMNS && AM) { @@ -408,7 +437,8 @@ apr(ps, fmt, va_alist) struct point p; va_list ap; - p.line = ps->line+1; p.col = ps->col+1; + p.line = ps->line + 1; + p.col = ps->col + 1; move(&p); #ifdef __STDC__ va_start(ap, fmt); @@ -441,19 +471,21 @@ pr(fmt, va_alist) pstring(str); } +void pstring(s) -char *s;{ + const char *s; +{ struct point z; int stcol; stcol = cursor.col; - while (s[0] != '\0'){ - switch (s[0]){ + while (s[0] != '\0') { + switch (s[0]) { case '\n': - move(point(&z,0,cursor.line+1)); + move(point(&z, 0, cursor.line + 1)); break; case '\r': - move(point(&z,stcol,cursor.line+1)); + move(point(&z, stcol, cursor.line + 1)); break; case '\t': z.col = (((cursor.col + 8) >> 3) << 3); @@ -467,115 +499,104 @@ char *s;{ outch(CTRL('g')); break; default: - if (s[0] < ' ')break; + if (s[0] < ' ') + break; pch(s[0]); } s++; } } +void pchar(ps,ch) -struct point *ps; -char ch;{ + struct point *ps; + char ch; +{ struct point p; - p.col = ps->col + 1; p.line = ps->line + 1; - if ( - (p.col >= 0) && - (p.line >= 0) && - ( - ( - (p.line < LINES) && - (p.col < COLUMNS) - ) || - ( - (p.col == COLUMNS) && - (p.line < LINES-1) - ) - ) - ){ + + p.col = ps->col + 1; + p.line = ps->line + 1; + if ((p.col >= 0) && (p.line >= 0) && + (((p.line < LINES) && (p.col < COLUMNS)) || + ((p.col == COLUMNS) && (p.line < LINES-1)))) { move(&p); pch(ch); } } - +int outch(c) + int c; { putchar(c); + return(0); } +void putpad(str) -char *str; + char *str; { if (str) tputs(str, 1, outch); } -delay(t) -int t; -{ - int k,j; - - k = (ospeed * t + 100) / 200; - for(j=0;j<k;j++){ - putchar(PC); - } -} -done() +void +delay(t) + int t; { - cook(); - exit(0); + useconds_t us; + /* This can't depend on terminal timing in light of X */ + + us = t * 50000; /* From units of 1/20 s */ + usleep(us); } +void cook() { delay(1); putpad(TE); putpad(KE); + putpad(VE); fflush(stdout); tcsetattr(0, TCSADRAIN, &orig); } +void raw() { tcsetattr(0, TCSADRAIN, &new); + putpad(VI); } -struct point *point(ps,x,y) -struct point *ps; -int x,y; +struct point * +point(ps, x, y) + struct point *ps; + int x, y; { - ps->col=x; - ps->line=y; + ps->col = x; + ps->line = y; return(ps); } -char *ap; - +void getcap() { - char *getenv(); - char *term; - char *xPC; - struct point z; - void stop(); + char *ap; + char *term; + char *xPC; #ifdef TIOCGWINSZ struct winsize win; #endif term = getenv("TERM"); - if (term==0) { - fprintf(stderr, "No TERM in environment\n"); - exit(1); - } - + if (term == 0) + errx(1, "No TERM in environment"); switch (tgetent(tbuf, term)) { case -1: - fprintf(stderr, "Cannot open termcap file\n"); - exit(2); + errx(2, "Cannot open termcap file"); case 0: - fprintf(stderr, "%s: unknown terminal", term); - exit(3); + errx(3, "unknown terminal `%s'", term); } ap = tcapbuf; @@ -593,6 +614,11 @@ getcap() lcnt = LINES - 2; if (!ccnt) ccnt = COLUMNS - 3; + /* make sure user didn't specify a screen larger than he has */ + if (lcnt > LINES - 2) + lcnt = LINES - 2; + if (ccnt > COLUMNS - 3) + ccnt = COLUMNS - 3; AM = tgetflag("am"); BW = tgetflag("bw"); @@ -605,11 +631,12 @@ getcap() DO = "\n"; BS = tgetstr("le", &ap); - if (BS == 0 && tgetflag("bs")) - BS = "\b"; - if (BS) - xBC = *BS; - + if (BS == 0) { + /* try using obsolete capabilities */ + BS = tgetstr("bc", &ap); + if (BS == 0 && tgetflag("bs")) + BS = "\b"; + } TA = tgetstr("ta", &ap); if (TA == 0 && tgetflag("pt")) TA = "\t"; @@ -627,59 +654,50 @@ getcap() Klength = strlen(KL); else Klength = 0; - /* NOTE: If KL, KR, KU, and KD are not - * all the same length, some problems - * may arise, since tests are made on - * all of them together. - */ + /* NOTE: If KL, KR, KU, and KD are not + * all the same length, some problems + * may arise, since tests are made on + * all of them together. + */ TI = tgetstr("ti", &ap); TE = tgetstr("te", &ap); KS = tgetstr("ks", &ap); KE = tgetstr("ke", &ap); + VE = tgetstr("ve", &ap); + VI = tgetstr("vi", &ap); xPC = tgetstr("pc", &ap); if (xPC) PC = *xPC; if ((CM == 0) && - (HO == 0 || UP == 0 || BS == 0 || ND == 0)) { - fprintf(stderr, "Terminal must have addressible "); - fprintf(stderr, "cursor or home + 4 local motions\n"); - exit(5); - } - if (ND == 0) { - fprintf(stderr, "Terminal must have `nd' capability\n"); - exit(5); - } + (HO == 0 || UP == 0 || BS == 0 || ND == 0)) + errx(5, "Terminal must have addressable cursor or home + 4 local motions"); + if (ND == 0) + errx(5, "Terminal must have `nd' capability"); NDlength = strlen(ND); - if (BS == 0) { - fprintf(stderr, "Terminal must have `bs' or `le' capability\n"); - exit(5); - } + if (BS == 0) + errx(5, "Terminal must have `le' or `bs' or `bc' capability"); BSlength = strlen(BS); - - if (tgetflag("os")) { - fprintf(stderr, "Terminal must not overstrike\n"); - exit(5); - } - if (LINES <= 0 || COLUMNS <= 0) { - fprintf(stderr, "Must know the screen size\n"); - exit(5); - } + if (tgetflag("os")) + errx(5, "Terminal must not overstrike"); + if (LINES <= 0 || COLUMNS <= 0) + errx(5, "Must know the screen size"); tcgetattr(0, &orig); new = orig; - new.c_lflag &= ~(ECHO|ICANON); - new.c_oflag &= ~(ONLCR|OXTABS); - signal(SIGINT,stop); + new.c_lflag &= ~(ECHO | ICANON); + new.c_oflag &= ~(ONLCR | OXTABS); + signal(SIGINT, stop); ospeed = cfgetospeed(&orig); new.c_cc[VSUSP] = _POSIX_VDISABLE; new.c_cc[VDSUSP] = _POSIX_VDISABLE; raw(); - if (orig.c_oflag & OXTABS) TA=0; + if (orig.c_oflag & OXTABS) + TA=0; putpad(KS); putpad(TI); - point(&cursor,0,LINES-1); + point(&cursor, 0, LINES - 1); } diff --git a/games/snake/snake/pathnames.h b/games/snake/pathnames.h index 2d71f4a3e9d..3c98c33c3af 100644 --- a/games/snake/snake/pathnames.h +++ b/games/snake/pathnames.h @@ -1,3 +1,4 @@ +/* $OpenBSD: pathnames.h,v 1.1 1999/03/13 02:08:09 pjanzen Exp $ */ /* $NetBSD: pathnames.h,v 1.3 1995/04/22 08:34:33 cgd Exp $ */ /* @@ -36,4 +37,6 @@ */ #define _PATH_RAWSCORES "/var/games/snakerawscores" +#ifdef LOGGING #define _PATH_LOGFILE "/var/games/snake.log" +#endif diff --git a/games/snake/snake/snake.6 b/games/snake/snake.6 index eb7def19794..45580c20827 100644 --- a/games/snake/snake/snake.6 +++ b/games/snake/snake.6 @@ -1,3 +1,4 @@ +.\" $OpenBSD: snake.6,v 1.1 1999/03/13 02:08:09 pjanzen Exp $ .\" $NetBSD: snake.6,v 1.5 1995/04/22 08:34:35 cgd Exp $ .\" .\" Copyright (c) 1980, 1993 @@ -44,11 +45,12 @@ .Nm snake .Op Fl w Ar width .Op Fl l Ar length +.Op Fl s .br .Nm snscore .Sh DESCRIPTION .Nm snake -is a display-based game which must be played on a CRT terminal. +is a display-based game. The object of the game is to make as much money as possible without getting eaten by the snake. The .Fl l @@ -56,6 +58,9 @@ and .Fl w options allow you to specify the length and width of the field. By default the entire screen (except for the last column) is used. +The +.Fl s +option shows all scores. .Pp You are represented on the screen by an I. The snake is 6 squares long and is represented by S's. @@ -63,8 +68,8 @@ The money is $, and an exit is #. Your score is posted in the upper left hand corner. .Pp You can move around using the same conventions as -.Xr vi 1 , -the +.Xr vi 1 : +that is, the .Ic h , .Ic j , .Ic k , @@ -85,12 +90,12 @@ to type a key repeatedly. The snake still gets all his turns. Likewise for the upper case versions on the left. .It Ic ATPB These keys move you to the four edges of the screen. -Their position on the keyboard is the mnemonic, e.g. +Their position on the keyboard is mnemonic, e.g. P is at the far right of the keyboard. .It Ic x This lets you quit the game at any time. .It Ic p -Points in a direction you might want to go. +Sometimes points in a direction you might want to go. .It Ic w Space warp to get out of tight squeezes, at a price. .El @@ -101,20 +106,23 @@ As you get richer, the snake gets hungrier. To leave the game, move to the exit (#). .Pp A record is kept of the personal best score of each player. -Scores are only counted if you leave at the exit, -getting eaten by the snake is worth nothing. +Scores are only counted if you leave at the exit. +Getting eaten by the snake is worth nothing. .Pp As in pinball, matching the last digit of your score to the number which appears after the game is worth a bonus. .Pp To see who wastes time playing snake, run -.Nm snscore . +.Nm snscore +or +.Nm snake +.Fl s . .Sh FILES .Bl -tag -width /var/games/snakerawscores -compact .It Pa /var/games/snakerawscores database of personal bests -.It Pa /var/games/snake.log -log of games played +.\".It Pa /var/games/snake.log +.\"log of games played .El .Sh BUGS When playing on a small screen, diff --git a/games/snake/snake/snake.c b/games/snake/snake.c index 4d768f4b4ce..767f3c51d5f 100644 --- a/games/snake/snake/snake.c +++ b/games/snake/snake.c @@ -1,3 +1,4 @@ +/* $OpenBSD: snake.c,v 1.1 1999/03/13 02:08:10 pjanzen Exp $ */ /* $NetBSD: snake.c,v 1.8 1995/04/29 00:06:41 mycroft Exp $ */ /* @@ -43,7 +44,7 @@ static char copyright[] = #if 0 static char sccsid[] = "@(#)snake.c 8.2 (Berkeley) 1/7/94"; #else -static char rcsid[] = "$NetBSD: snake.c,v 1.8 1995/04/29 00:06:41 mycroft Exp $"; +static char rcsid[] = "$OpenBSD: snake.c,v 1.1 1999/03/13 02:08:10 pjanzen Exp $"; #endif #endif /* not lint */ @@ -63,58 +64,47 @@ static char rcsid[] = "$NetBSD: snake.c,v 1.8 1995/04/29 00:06:41 mycroft Exp $" #include <errno.h> #include <fcntl.h> #include <pwd.h> -#include <stdlib.h> #include <time.h> #include <unistd.h> #include "snake.h" #include "pathnames.h" -#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 80 - struct point you; struct point money; struct point finish; struct point snake[6]; -int loot, penalty; -int long tl, tm=0L; -int moves; -char stri[BSIZE]; -char *p; -char ch, savec; -char *kl, *kr, *ku, *kd; -int fast=1; -int repeat=1; -time_t tv; -char *tn; +int loot, penalty; +int long tl, tm=0L; +int moves; +char stri[BSIZE]; +char *p; +char ch, savec; +char *kl, *kr, *ku, *kd; +int fast=1; +int repeat=1; +time_t tv; +char *tn; int rawscores; -FILE *logfile; +#ifdef LOGGING +FILE *logfile; +#endif -main(argc,argv) -int argc; -char **argv; +int +main(argc, argv) + int argc; + char **argv; { - extern char *optarg; - extern int optind; - int ch, i, j, k; - void stop(); + int ch, i; + char *p, **av; - rawscores = open(_PATH_RAWSCORES, O_RDWR|O_CREAT, 0644); + /* don't create the score file if it doesn't exist. */ + rawscores = open(_PATH_RAWSCORES, O_RDWR, 0664); +#ifdef LOGGING logfile = fopen(_PATH_LOGFILE, "a"); +#endif /* revoke privs */ setegid(getgid()); @@ -123,11 +113,21 @@ char **argv; (void)time(&tv); srandom((int)tv); - while ((ch = getopt(argc, argv, "l:w:")) != -1) - switch((char)ch) { -#ifdef notdef + /* check to see if we were called as snscore */ + av = argv; + p = strrchr(*av, '/'); + if (p++ == NULL) + p = *av; + if (strcmp(p,"snscore") == 0) { + snscore(rawscores, 0); + exit(0); + } + + while ((ch = getopt(argc, argv, "hl:sw:")) != -1) + switch ((char)ch) { +#if 0 case 'd': - tv = atol(optarg); + tv = atol(optarg); /* set seed */ break; #endif case 'w': /* width */ @@ -136,9 +136,15 @@ char **argv; case 'l': /* length */ lcnt = atoi(optarg); break; + case 's': /* score */ + snscore(rawscores, 0); + exit(0); + break; case '?': + case 'h': default: - fputs("usage: snake [-d seed] [-w width] [-l length]\n", stderr); + fputs("usage: snake [-w width] [-l length] [-s]\n", + stderr); exit(1); } @@ -148,10 +154,8 @@ char **argv; i = MIN(lcnt, ccnt); if (i < 4) { cook(); - pr("snake: screen too small for a fair game.\n"); - exit(1); + errx(1, "screen too small for a fair game."); } - /* * chunk is the amount of money the user gets for each $. * The formula below tries to be fair for various screen sizes. @@ -165,7 +169,8 @@ char **argv; * 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 */ + 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 @@ -173,45 +178,47 @@ char **argv; * much anyway. */ i += 2; - chunk = (675.0 / (i+6)) + 2.5; /* min screen edge */ + 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 */ + signal(SIGINT, stop); + putpad(TI); /* String to begin programs that use cm */ + putpad(KS); /* Put terminal in keypad transmit mode */ snrand(&finish); snrand(&you); snrand(&money); snrand(&snake[0]); - if (ospeed < 9600 || ((! CM) && (! TA))) fast=0; - for(i=1;i<6;i++) - chase (&snake[i], &snake[i-1]); + if (ospeed < 9600 || ((!CM) && (!TA))) + fast = 0; + for (i = 1; i < 6; i++) + chase(&snake[i], &snake[i - 1]); setup(); mainloop(); + /* NOT REACHED */ } /* Main command loop */ +void mainloop() { - int j, k; + int j, k; + int c, match, lastc = 0; for (;;) { - int c,lastc,match; - move(&you); fflush(stdout); if (((c = getchar() & 0177) <= '9') && (c >= '0')) { - ungetc(c,stdin); - j = scanf("%d",&repeat); + ungetc(c, stdin); + j = scanf("%d", &repeat); c = getchar() & 0177; } else { - if (c != '.') repeat = 1; + if (c != '.') + repeat = 1; } - if (c == '.') { + if (c == '.') c = lastc; - } - if ((Klength > 0) && + if ((Klength > 0) && (c == *KL || c == *KR || c == *KU || c == *KD)) { savec = c; match = 0; @@ -219,9 +226,9 @@ mainloop() kr = KR; ku = KU; kd = KD; - for (j=Klength;j>0;j--){ + for (j = Klength; j > 0; j--) { if (match != 1) { - match = 0; + match = 0; if (*kl++ == c) { ch = 'h'; match++; @@ -239,7 +246,7 @@ mainloop() match++; } if (match == 0) { - ungetc(c,stdin); + ungetc(c, stdin); ch = savec; /* Oops! * This works if we figure it out on second character. @@ -248,13 +255,15 @@ mainloop() } } savec = c; - if(j != 1) c = getchar() & 0177; + if (j != 1) + c = getchar() & 0177; } c = ch; } - if (!fast) flushi(); + if (!fast) + flushi(); lastc = c; - switch (c){ + switch (c) { case CTRL('z'): suspend(); continue; @@ -262,9 +271,12 @@ mainloop() case 'x': case 0177: /* del or end of file */ ll(); + cook(); length(moves); +#ifdef LOGGING logit("quit"); - done(); +#endif + exit(0); case CTRL('l'): setup(); winnings(cashvalue); @@ -313,18 +325,17 @@ mainloop() c = 'j'; break; } - for(k=1;k<=repeat;k++){ + for(k = 1; k <= repeat; k++) { moves++; - switch(c) { + switch (c) { case 's': case 'h': case '\b': if (you.col >0) { - if((fast)||(k == 1)) + if ((fast) || (k == 1)) pchar(&you,' '); you.col--; - if((fast) || (k == repeat) || - (you.col == 0)) + if ((fast) || (k == repeat) || (you.col == 0)) pchar(&you,ME); } break; @@ -332,12 +343,11 @@ mainloop() case 'l': case ' ': if (you.col < ccnt-1) { - if((fast)||(k == 1)) - pchar(&you,' '); + if ((fast) || (k == 1)) + pchar(&you, ' '); you.col++; - if((fast) || (k == repeat) || - (you.col == ccnt-1)) - pchar(&you,ME); + if ((fast) || (k == repeat) || (you.col == ccnt-1)) + pchar(&you, ME); } break; case CTRL('p'): @@ -345,11 +355,10 @@ mainloop() case 'k': case 'i': if (you.line > 0) { - if((fast)||(k == 1)) + if ((fast) || (k == 1)) pchar(&you,' '); you.line--; - if((fast) || (k == repeat) || - (you.line == 0)) + if ((fast) || (k == repeat) || (you.line == 0)) pchar(&you,ME); } break; @@ -359,99 +368,100 @@ mainloop() case LF: case 'm': if (you.line+1 < lcnt) { - if((fast)||(k == 1)) + if ((fast) || (k == 1)) pchar(&you,' '); you.line++; - if((fast) || (k == repeat) || - (you.line == lcnt-1)) + if ((fast) || (k == repeat) || (you.line == lcnt-1)) pchar(&you,ME); } break; } - if (same(&you,&money)) - { - char xp[20]; - struct point z; + if (same(&you, &money)) { loot += 25; - if(k < repeat) - pchar(&you,' '); + if (k < repeat) + pchar(&you, ' '); do { snrand(&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); + } 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; +/* continue; Previously, snake missed a turn! */ } - if (same(&you,&finish)) - { + if (same(&you,&finish)) { win(&finish); ll(); cook(); - pr("You have won with $%d.\n",cashvalue); - fflush(stdout); + printf("You have won with $%d.\n", cashvalue); +#ifdef LOGGING logit("won"); - post(cashvalue,1); +#endif length(moves); - done(); + post(cashvalue, 1); + close(rawscores); + exit(0); } - if (pushsnake())break; + if (pushsnake()) + break; } fflush(stdout); } } -setup(){ /* - * setup the board - */ - int i; +/* set up the board */ +void +setup() +{ + int i; clear(); - pchar(&you,ME); - pchar(&finish,GOAL); - pchar(&money,TREASURE); - for(i=1; i<6; i++) { - pchar(&snake[i],SNAKETAIL); + 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); } +void drawbox() { - register int i; + int i; struct point p; p.line = -1; - for (i= 0; i<ccnt; i++) { + for (i = 0; i < ccnt; i++) { p.col = i; pchar(&p, '-'); } p.col = ccnt; - for (i= -1; i<=lcnt; i++) { + for (i = -1; i <= lcnt; i++) { p.line = i; pchar(&p, '|'); } p.col = -1; - for (i= -1; i<=lcnt; i++) { + for (i = -1; i <= lcnt; i++) { p.line = i; pchar(&p, '|'); } p.line = lcnt; - for (i= 0; i<ccnt; i++) { + for (i = 0; i < ccnt; i++) { p.col = i; pchar(&p, '-'); } } +void snrand(sp) -struct point *sp; + struct point *sp; { struct point p; - register int i; + int i; for (;;) { p.col = random() % ccnt; @@ -466,68 +476,61 @@ struct point *sp; continue; if (same(&p, &finish)) continue; - for (i = 0; i < 5; i++) + for (i = 0; i < 6; i++) if (same(&p, &snake[i])) break; - if (i < 5) + if (i < 6) continue; break; } *sp = p; } +int post(iscore, flag) -int iscore, flag; + int iscore, flag; { short score = iscore; - uid_t uid; short oldbest=0; - short allbwho=0, allbscore=0; - struct passwd *p; + uid_t uid; + /* I want to printf() the scores for terms that clear on cook(), + * but this routine also gets called with flag == 0 to see if + * the snake should wink. If (flag) then we're at game end and + * can printf. + */ /* - * Neg uid, 0, and 1 cannot have scores recorded. + * Neg uid cannot have scores recorded. */ - if ((uid = getuid()) <= 1) { - pr("No saved scores for uid %d.\n", uid); + if ((uid = getuid()) < 0) { + if (flag) + printf("\nNo saved scores for uid %d.\n", uid); return(1); } if (rawscores == -1) { - pr("No score file %s: %s.\n", _PATH_RAWSCORES, - strerror(errno)); + if (flag) + printf("Can't open score file %s: %s.\n", + _PATH_RAWSCORES, strerror(errno)); return(1); } /* Figure out what happened in the past */ - read(rawscores, &allbscore, sizeof(short)); - read(rawscores, &allbwho, sizeof(short)); - lseek(rawscores, uid*sizeof(short), 0); + lseek(rawscores, uid * sizeof(short), SEEK_SET); read(rawscores, &oldbest, sizeof(short)); if (!flag) return (score > oldbest ? 1 : 0); /* Update this jokers best */ if (score > oldbest) { - lseek(rawscores, uid*sizeof(short), 0); + lseek(rawscores, uid * sizeof(short), SEEK_SET); write(rawscores, &score, sizeof(short)); - pr("You bettered your previous best of $%d\n", oldbest); + printf("\nYou bettered your previous best of $%d\n", oldbest); } else - pr("Your best to date is $%d\n", oldbest); + printf("\nYour best to date is $%d\n", oldbest); + fsync(rawscores); /* See if we have a new champ */ - p = getpwuid(allbwho); - if (p == NULL || score > allbscore) { - lseek(rawscores, 0, 0); - write(rawscores, &score, sizeof(short)); - write(rawscores, &uid, sizeof(short)); - if (allbwho) - pr("You beat %s's old record of $%d!\n", - p->pw_name, allbscore); - else - pr("You set a new record!\n"); - } else - pr("The highest is %s with $%d\n", p->pw_name, allbscore); - close(rawscores); - return (1); + snscore(rawscores, TOPN); + return(1); } /* @@ -535,86 +538,89 @@ int iscore, flag; * overshooting. This loses horribly at 9600 baud, but works nicely * if the terminal gets behind. */ +void flushi() { tcflush(0, TCIFLUSH); } -int mx [8] = { - 0, 1, 1, 1, 0,-1,-1,-1}; -int my [8] = { - -1,-1, 0, 1, 1, 1, 0,-1}; -float absv[8]= { - 1, 1.4, 1, 1.4, 1, 1.4, 1, 1.4 -}; -int oldw=0; + +int mx [8] = { 0, 1, 1, 1, 0,-1,-1,-1}; +int my [8] = {-1,-1, 0, 1, 1, 1, 0,-1}; +float absv[8] = {1, 1.4, 1, 1.4, 1, 1.4, 1, 1.4}; +int oldw = 0; + +void chase (np, sp) -struct point *sp, *np; + struct point *sp, *np; { - /* this algorithm has bugs; otherwise the - snake would get too good */ + /* this algorithm has bugs; otherwise the snake would get too good */ struct point d; - int w, i, wt[8]; - double v1, v2, vp, max; - point(&d,you.col-sp->col,you.line-sp->line); - v1 = sqrt( (double) (d.col*d.col + d.line*d.line) ); - w=0; - max=0; - for(i=0; i<8; i++) + int w, i, wt[8]; + double v1, v2, vp, max; + + point(&d, you.col-sp->col, you.line-sp->line); + v1 = sqrt((double)(d.col * d.col + d.line * d.line) ); + w = 0; + max = 0; + for(i = 0; i < 8; i++) { - vp = d.col*mx[i] + d.line*my[i]; + vp = d.col * mx[i] + d.line * my[i]; v2 = absv[i]; - if (v1>0) - vp = ((double)vp)/(v1*v2); - else vp=1.0; - if (vp>max) - { - max=vp; - w=i; + if (v1 > 0) + vp = ((double)vp) / (v1 * v2); + else + vp = 1.0; + if (vp > max) { + max = vp; + w = i; } } - for(i=0; i<8; i++) - { - point(&d,sp->col+mx[i],sp->line+my[i]); - wt[i]=0; - if (d.col<0 || d.col>=ccnt || d.line<0 || d.line>=lcnt) + for (i = 0; i < 8; i++) { + point(&d, sp->col + mx[i], sp->line + my[i]); + wt[i] = 0; + if (d.col < 0 || d.col >= ccnt || d.line < 0 || d.line >= lcnt) continue; /* - * Change to allow snake to eat you if you're on the money, + * Change to allow snake to eat you if you're on the money; * otherwise, you can just crouch there until the snake goes * away. Not positive it's right. * * if (d.line == 0 && d.col < 5) continue; */ - if (same(&d,&money)) continue; - if (same(&d,&finish)) continue; - wt[i]= i==w ? loot/10 : 1; - if (i==oldw) wt [i] += loot/20; - } - for(w=i=0; i<8; i++) - w+= wt[i]; - vp = (( rand() >> 6 ) & 01777) %w; - for(i=0; i<8; i++) - if (vp <wt[i]) + if (same(&d, &money) || same(&d,&finish)) + continue; + wt[i] = (i == w ? loot/10 : 1); + if (i == oldw) + wt[i] += loot/20; + } + for (w = i = 0; i < 8; i++) + w += wt[i]; + vp = ((rand() >> 6) & 01777) % w; + for (i = 0; i < 8; i++) + if (vp < wt[i]) break; else vp -= wt[i]; - if (i==8) { + if (i == 8) { pr("failure\n"); - i=0; - while (wt[i]==0) i++; + i = 0; + while (wt[i] == 0) + i++; } - oldw=w=i; - point(np,sp->col+mx[w],sp->line+my[w]); + oldw = w = i; + point(np, sp->col + mx[w], sp->line + my[w]); } +void spacewarp(w) -int w;{ + int w; +{ struct point p; - int j; - char *str; + int j; + char *str; snrand(&you); - point(&p,COLUMNS/2 - 8,LINES/2 - 1); + point(&p, COLUMNS / 2 - 8, LINES / 2 - 1); if (p.col < 0) p.col = 0; if (p.line < 0) @@ -625,86 +631,105 @@ int w;{ penalty = 0; } else { str = "SPACE WARP!!!"; - penalty += loot/PENALTY; + penalty += loot / PENALTY; } - for(j=0;j<3;j++){ + for (j = 0; j < 3; j++) { clear(); + fflush(stdout); delay(5); - apr(&p,str); + apr(&p, str); + fflush(stdout); delay(10); } setup(); winnings(cashvalue); } + +void snap() { struct point p; - int i; - if(you.line < 3){ - pchar(point(&p,you.col,0),'-'); - } - if(you.line > lcnt-4){ - pchar(point(&p,you.col,lcnt-1),'_'); - } - if(you.col < 10){ - pchar(point(&p,0,you.line),'('); - } - if(you.col > ccnt-10){ - pchar(point(&p,ccnt-1,you.line),')'); - } - if (! stretch(&money)) if (! stretch(&finish)) delay(10); - if(you.line < 3){ - point(&p,you.col,0); - chk(&p); - } - if(you.line > lcnt-4){ - point(&p,you.col,lcnt-1); - chk(&p); - } - if(you.col < 10){ - point(&p,0,you.line); - chk(&p); - } - if(you.col > ccnt-10){ - point(&p,ccnt-1,you.line); - chk(&p); - } + /* I don't see the graphical purpose of the next block of code. + * It just makes no sense. + * + * if (you.line < 3) + * pchar(point(&p, you.col, 0), '-'); + * if (you.line > lcnt - 4) + * pchar(point(&p, you.col, lcnt - 1), '_'); + * if(you.col < 10) + * pchar(point(&p, 0, you.line), '('); + * if(you.col > ccnt-10) + * pchar(point(&p, ccnt-1, you.line), ')'); + */ + if (!stretch(&money)) + if (!stretch(&finish)) { + pchar(point(&p, you.col, you.line), '?'); + fflush(stdout); + delay(10); + pchar(point(&p, you.col, you.line), ME); + } + /* Again, I don't see the point of the following either. + * + * if (you.line < 3) { + * point(&p, you.col, 0); + * chk(&p); + * } + * if (you.line > lcnt - 4) { + * point(&p, you.col, lcnt - 1); + * chk(&p); + * } + * if (you.col < 10) { + * point(&p, 0, you.line); + * chk(&p); + * } + * if (you.col > ccnt-10) { + * point(&p, ccnt - 1, you.line); + * chk(&p); + * } + */ fflush(stdout); } + +int stretch(ps) -struct point *ps;{ + struct point *ps; +{ struct point p; - point(&p,you.col,you.line); - if(abs(ps->col-you.col) < 6){ - if(you.line < ps->line){ - for (p.line = you.line+1;p.line <= ps->line;p.line++) - pchar(&p,'v'); + point(&p, you.col, you.line); + if ((abs(ps->col - you.col) < (ccnt / 12)) && (you.line != ps->line)) { + if (you.line < ps->line) { + for (p.line = you.line + 1; p.line <= ps->line; p.line++) + pchar(&p, 'v'); + fflush(stdout); delay(10); - for (;p.line > you.line;p.line--) + for (; p.line > you.line; p.line--) chk(&p); } else { - for (p.line = you.line-1;p.line >= ps->line;p.line--) - pchar(&p,'^'); + for (p.line = you.line - 1; p.line >= ps->line; p.line--) + pchar(&p, '^'); + fflush(stdout); delay(10); - for (;p.line < you.line;p.line++) + for (; p.line < you.line; p.line++) chk(&p); } return(1); - } else if(abs(ps->line-you.line) < 3){ + } else if ((abs(ps->line - you.line) < (lcnt / 7)) && (you.col != ps->col)) { p.line = you.line; - if(you.col < ps->col){ - for (p.col = you.col+1;p.col <= ps->col;p.col++) - pchar(&p,'>'); + if (you.col < ps->col) { + for (p.col = you.col + 1; p.col <= ps->col; p.col++) + pchar(&p, '>'); + fflush(stdout); delay(10); - for (;p.col > you.col;p.col--) + for (; p.col > you.col; p.col--) chk(&p); } else { - for (p.col = you.col-1;p.col >= ps->col;p.col--) - pchar(&p,'<'); + for (p.col = you.col - 1; p.col >= ps->col; p.col--) + pchar(&p, '<'); + fflush(stdout); delay(10); - for (;p.col < you.col;p.col++) + for (; p.col < you.col; p.col++) chk(&p); } return(1); @@ -712,65 +737,80 @@ struct point *ps;{ return(0); } +void surround(ps) -struct point *ps;{ + struct point *ps; +{ struct point x; - int i,j; - - if(ps->col == 0)ps->col++; - if(ps->line == 0)ps->line++; - if(ps->line == LINES -1)ps->line--; - if(ps->col == COLUMNS -1)ps->col--; - apr(point(&x,ps->col-1,ps->line-1),"/*\\\r* *\r\\*/"); - for (j=0;j<20;j++){ - pchar(ps,'@'); + int j; + + if (ps->col == 0) + ps->col++; + if (ps->line == 0) + ps->line++; + if (ps->line == LINES -1) + ps->line--; + if (ps->col == COLUMNS -1) + ps->col--; + apr(point(&x, ps->col-1, ps->line-1), "/*\\\r* *\r\\*/"); + for (j = 0; j < 20; j++) { + pchar(ps, '@'); + fflush(stdout); delay(1); pchar(ps,' '); + fflush(stdout); delay(1); } - if (post(cashvalue,0)) { - apr(point(&x,ps->col-1,ps->line-1)," \ro.o\r\\_/"); + if (post(cashvalue, 0)) { + apr(point(&x, ps->col - 1, ps->line - 1), " \ro.o\r\\_/"); + fflush(stdout); delay(6); - apr(point(&x,ps->col-1,ps->line-1)," \ro.-\r\\_/"); + apr(point(&x,ps->col - 1, ps->line - 1), " \ro.-\r\\_/"); + fflush(stdout); delay(6); } - apr(point(&x,ps->col-1,ps->line-1)," \ro.o\r\\_/"); + apr(point(&x, ps->col - 1, ps->line - 1), " \ro.o\r\\_/"); } + +void win(ps) -struct point *ps; + struct point *ps; { struct point x; - int j,k; - int boxsize; /* actually diameter of box, not radius */ - - boxsize = fast ? 10 : 4; - point(&x,ps->col,ps->line); - for(j=1;j<boxsize;j++){ - for(k=0;k<j;k++){ - pchar(&x,'#'); + int j,k; + int boxsize; /* actually diameter of box, not radius */ + + boxsize = (fast ? 10 : 4); + point(&x, ps->col, ps->line); + for (j = 1; j < boxsize; j++) { + for (k = 0; k < j; k++) { + pchar(&x, '#'); x.line--; } - for(k=0;k<j;k++){ - pchar(&x,'#'); + for (k = 0; k < j; k++) { + pchar(&x, '#'); x.col++; } j++; - for(k=0;k<j;k++){ - pchar(&x,'#'); + for (k = 0; k < j; k++) { + pchar(&x, '#'); x.line++; } - for(k=0;k<j;k++){ - pchar(&x,'#'); + for (k = 0; k < j; k++) { + pchar(&x, '#'); x.col--; } + fflush(stdout); + delay(1); } - fflush(stdout); } +int pushsnake() { - int i, bonus; - int issame = 0; + int i, bonus; + int issame = 0; + struct point tmp; /* * My manual says times doesn't return a value. Furthermore, the @@ -778,106 +818,118 @@ pushsnake() * on a fast terminal with typematic keys or not. * So I have taken the call to times out. */ - for(i=4; i>=0; i--) + for (i = 4; i >=0; i--) if (same(&snake[i], &snake[5])) issame++; if (!issame) - pchar(&snake[5],' '); - for(i=4; i>=0; i--) - snake[i+1]= snake[i]; + pchar(&snake[5], ' '); + /* Need the following to catch you if you step on the snake's tail */ + tmp.col = snake[5].col; tmp.line = snake[5].line; + for (i = 4; i >= 0; i--) + snake[i + 1] = snake[i]; chase(&snake[0], &snake[1]); - pchar(&snake[1],SNAKETAIL); - pchar(&snake[0],SNAKEHEAD); - for(i=0; i<6; i++) - { - if (same(&snake[i],&you)) - { + pchar(&snake[1], SNAKETAIL); + pchar(&snake[0], SNAKEHEAD); + for (i = 0; i < 6; i++) { + if ((same(&snake[i], &you)) || (same(&tmp, &you))) { surround(&you); i = (cashvalue) % 10; - bonus = ((rand()>>8) & 0377)% 10; + bonus = ((random() >> 8) & 0377) % 10; ll(); pr("%d\n", bonus); + fflush(stdout); delay(30); if (bonus == i) { spacewarp(1); +#ifdef LOGGING logit("bonus"); +#endif flushi(); return(1); } - if ( loot >= penalty ){ - pr("You and your $%d have been eaten\n", - cashvalue); + cook(); + if ( loot >= penalty ) { + printf("\nYou and your $%d have been eaten\n", cashvalue); } else { - pr("The snake ate you. You owe $%d.\n", - -cashvalue); + printf("\nThe snake ate you. You owe $%d.\n", -cashvalue); } +#ifdef LOGGING logit("eaten"); +#endif length(moves); - done(); + snscore(rawscores, TOPN); + close(rawscores); + exit(0); } } return(0); } +int chk(sp) struct point *sp; { - int j; + int j; - if (same(sp,&money)) { - pchar(sp,TREASURE); + if (same(sp, &money)) { + pchar(sp, TREASURE); return(2); } - if (same(sp,&finish)) { - pchar(sp,GOAL); + if (same(sp, &finish)) { + pchar(sp, GOAL); return(3); } - if (same(sp,&snake[0])) { - pchar(sp,SNAKEHEAD); + if (same(sp, &snake[0])) { + pchar(sp, SNAKEHEAD); return(4); } - for(j=1;j<6;j++){ - if(same(sp,&snake[j])){ - pchar(sp,SNAKETAIL); + for (j = 1; j < 6; j++) { + if (same(sp, &snake[j])) { + pchar(sp, SNAKETAIL); return(4); } } - if ((sp->col < 4) && (sp->line == 0)){ + if ((sp->col < 4) && (sp->line == 0)) { winnings(cashvalue); - if((you.line == 0) && (you.col < 4)) pchar(&you,ME); + if ((you.line == 0) && (you.col < 4)) + pchar(&you,ME); return(5); } - if (same(sp,&you)) { - pchar(sp,ME); + if (same(sp, &you)) { + pchar(sp, ME); return(1); } - pchar(sp,' '); + pchar(sp, ' '); return(0); } + +void winnings(won) -int won; + int won; { struct point p; p.line = p.col = 1; - if(won>0){ + if (won > 0) { move(&p); - pr("$%d",won); + pr("$%d ", won); } } void -stop(){ - signal(SIGINT,SIG_IGN); +stop(dummy) + int dummy; +{ + signal(SIGINT, SIG_IGN); ll(); + cook(); length(moves); - done(); + exit(0); } +void suspend() { - char *sh; - ll(); cook(); kill(getpid(), SIGTSTP); @@ -886,14 +938,17 @@ suspend() winnings(cashvalue); } +void length(num) -int num; + int num; { - pr("You made %d moves.\n",num); + printf("You made %d moves.\n",num); } +#ifdef LOGGING +void logit(msg) -char *msg; + char *msg; { time_t t; @@ -904,3 +959,4 @@ char *msg; fclose(logfile); } } +#endif diff --git a/games/snake/snake/snake.h b/games/snake/snake.h index b2900882dfd..ae1770b8176 100644 --- a/games/snake/snake/snake.h +++ b/games/snake/snake.h @@ -1,4 +1,4 @@ -/* $NetBSD: snake.h,v 1.6 1995/04/29 01:17:15 mycroft Exp $ */ +/* $OpenBSD: snake.h,v 1.1 1999/03/13 02:08:10 pjanzen Exp $ */ /* * Copyright (c) 1980, 1993 @@ -35,15 +35,31 @@ * @(#)snake.h 8.1 (Berkeley) 5/31/93 */ -# include <stdio.h> -# include <string.h> -# include <assert.h> -# include <sys/types.h> -# include <signal.h> -# include <termios.h> -# include <math.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <err.h> +#include <math.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <termios.h> +#define PENALTY 10 /* % penalty for invoking spacewarp */ + +#define EOT '\004' #define ESC '\033' +#define LF '\n' +#define DEL '\177' + +#define ME 'I' +#define SNAKEHEAD 'S' +#define SNAKETAIL 's' +#define TREASURE '$' +#define GOAL '#' + +#define BSIZE 80 +#define TOPN 3 /* top scores to print if you lose */ struct tbuffer { long t[4]; @@ -53,17 +69,17 @@ char *CL, *UP, *DO, *ND, *BS, *HO, *CM, *TA, *LL, *KL, *KR, *KU, *KD, - *TI, *TE, *KS, *KE; + *TI, *TE, *KS, *KE, *VE, *VI; int LINES, COLUMNS; /* physical screen size. */ int lcnt, ccnt; /* user's idea of screen size */ -char xBC, PC; +char PC; int AM, BW; char tbuf[1024], tcapbuf[128]; char *tgetstr(), *tgoto(); int Klength; /* length of KX strings */ int chunk; /* amount of money given at a time */ speed_t ospeed; -#ifdef debug +#ifdef DEBUG #define cashvalue (loot-penalty)/25 #else #define cashvalue chunk*(loot-penalty)/25 @@ -84,3 +100,51 @@ void pr(); #endif #define same(s1, s2) ((s1)->line == (s2)->line && (s1)->col == (s2)->col) + +void snscore __P((int, int)); + +void mainloop __P((void)); +void chase __P((struct point *, struct point *)); +void setup __P((void)); +void drawbox __P((void)); +void snrand __P((struct point *)); +int post __P((int, int)); +void flushi __P((void)); +void spacewarp __P((int)); +void snap __P((void)); +int stretch __P((struct point *)); +void surround __P((struct point *)); +void win __P((struct point *)); +int pushsnake __P((void)); +int chk __P((struct point *)); +void winnings __P((int)); +void stop __P((int)); +void suspend __P((void)); +void length __P((int)); +void move __P((struct point *)); + +#ifdef LOGGING +void logit __P((char *)); +#endif + +void gto __P((struct point *)); +void right __P((struct point *)); +void up __P((void)); +void down __P((void)); +void bs __P((void)); +void nd __P((void)); +void clear __P((void)); +void home __P((void)); +void ll __P((void)); +void cr __P((void)); +void pstring __P((const char *)); +void pch __P((int)); +void pchar __P((struct point *, char)); +int outch __P((int)); +void putpad __P((char *)); +void cook __P((void)); +void raw __P((void)); +struct point *point __P((struct point *, int, int)); +void delay __P((int)); +void getcap __P((void)); + diff --git a/games/snake/snake/Makefile b/games/snake/snake/Makefile deleted file mode 100644 index 1dc9498bd56..00000000000 --- a/games/snake/snake/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# $NetBSD: Makefile,v 1.6 1995/04/22 08:34:27 cgd Exp $ -# @(#)Makefile 8.1 (Berkeley) 5/31/93 - -PROG= snake -SRCS= snake.c move.c -MAN= snake.6 -DPADD= ${LIBM} ${LIBCURSES} ${LIBCOMPAT} -LDADD= -lm -lcurses -lcompat -HIDEGAME=hidegame - -.include "../../Makefile.inc" -.include <bsd.prog.mk> diff --git a/games/snake/snscore/snscore.c b/games/snake/snscore.c index 3f02356aad4..124a544dc1d 100644 --- a/games/snake/snscore/snscore.c +++ b/games/snake/snscore.c @@ -1,3 +1,4 @@ +/* $OpenBSD: snscore.c,v 1.1 1999/03/13 02:08:10 pjanzen Exp $ */ /* $NetBSD: snscore.c,v 1.5 1995/04/24 12:25:43 cgd Exp $ */ /* @@ -43,69 +44,66 @@ static char copyright[] = #if 0 static char sccsid[] = "@(#)snscore.c 8.1 (Berkeley) 7/19/93"; #else -static char rcsid[] = "$NetBSD: snscore.c,v 1.5 1995/04/24 12:25:43 cgd Exp $"; +static char rcsid[] = "$OpenBSD: snscore.c,v 1.1 1999/03/13 02:08:10 pjanzen Exp $"; #endif #endif /* not lint */ #include <sys/types.h> +#include <err.h> +#include <fcntl.h> #include <pwd.h> #include <stdio.h> #include <stdlib.h> +#include <stdio.h> #include <string.h> #include <unistd.h> #include "pathnames.h" -char *recfile = _PATH_RAWSCORES; #define MAXPLAYERS 256 -struct player { +struct player { uid_t uids; short scores; char *name; } players[MAXPLAYERS], temp; -int -main() +void +snscore(fd, topn) + int fd, topn; { uid_t uid; short score; - FILE *fd; int noplayers; int i, j, notsorted; - short whoallbest, allbest; char *q; struct passwd *p; - fd = fopen(recfile, "r"); - - if (fd == NULL) { - perror(recfile); - exit(1); + if (fd < 0) { + fd = open(_PATH_RAWSCORES, O_RDONLY, 0); + if (fd < 0) + errx(1, "Couldn't open raw scorefile"); } - /* revoke privs */ - setegid(getgid()); - setgid(getgid()); - - printf("Snake players scores to date\n"); - fread(&whoallbest, sizeof(short), 1, fd); - fread(&allbest, sizeof(short), 1, fd); + lseek(fd, 0, SEEK_SET); + printf("%sSnake scores to date\n", topn > 0 ? "Top " : ""); + /* read(fd, &whoallbest, sizeof(uid_t)); + * read(fd, &allbest, sizeof(short)); SCOREFILE FORMAT CHANGE + */ noplayers = 0; - for (uid = 2; ;uid++) { - if(fread(&score, sizeof(short), 1, fd) == 0) + for (uid = 0; ; uid++) { + if (read(fd, &score, sizeof(short)) == 0) break; if (score > 0) { - if (noplayers > MAXPLAYERS) { - printf("too many players\n"); - exit(2); - } + if (noplayers > MAXPLAYERS) + errx(2, "Too many entries in scorefile!"); players[noplayers].uids = uid; players[noplayers].scores = score; p = getpwuid(uid); if (p == NULL) continue; q = p -> pw_name; - players[noplayers].name = malloc(strlen(q) + 1); + if ((players[noplayers].name = malloc(strlen(q) + 1)) == NULL) + errx(1, "malloc"); strcpy(players[noplayers].name, q); noplayers++; } @@ -123,11 +121,14 @@ main() } } + if ((topn > 0) && (topn < noplayers)) + noplayers = topn; j = 1; for (i = 0; i < noplayers; i++) { printf("%d:\t$%d\t%s\n", j, players[i].scores, players[i].name); if (players[i].scores > players[i + 1].scores) j = i + 2; } - exit(0); + if (noplayers == 0) + printf("None.\n"); } diff --git a/games/snake/snscore/Makefile b/games/snake/snscore/Makefile deleted file mode 100644 index 08ebc76743b..00000000000 --- a/games/snake/snscore/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# $NetBSD: Makefile,v 1.3 1995/04/22 08:34:41 cgd Exp $ -# @(#)Makefile 8.1 (Berkeley) 5/31/93 - -PROG= snscore -CFLAGS+=-I${.CURDIR}/../snake -NOMAN= noman -HIDEGAME=hidegame - -.include "../../Makefile.inc" -.include <bsd.prog.mk> |