diff options
author | jkh <jkh@FreeBSD.org> | 1994-09-04 04:03:31 +0000 |
---|---|---|
committer | jkh <jkh@FreeBSD.org> | 1994-09-04 04:03:31 +0000 |
commit | 057afceb86e030ad65b0130436860d9a18066186 (patch) | |
tree | a0ced9c9b9278eb776d89cd2565c27ddcf020b51 /games/snake | |
parent | eedec95276cdb8aef98e92c5371000f10b8d6ba7 (diff) | |
download | FreeBSD-src-057afceb86e030ad65b0130436860d9a18066186.zip FreeBSD-src-057afceb86e030ad65b0130436860d9a18066186.tar.gz |
Bring in the 4.4 Lite games directory, modulo man page changes and segregation
of the x11 based games. I'm not going to tag the originals with bsd_44_lite
and do this in two stages since it's just not worth it for this collection,
and I've got directory renames to deal with that way. Bleah.
Submitted by: jkh
Diffstat (limited to 'games/snake')
-rw-r--r-- | games/snake/Makefile | 5 | ||||
-rw-r--r-- | games/snake/snake/Makefile | 11 | ||||
-rw-r--r-- | games/snake/snake/move.c | 694 | ||||
-rw-r--r-- | games/snake/snake/pathnames.h | 37 | ||||
-rw-r--r-- | games/snake/snake/snake.6 | 113 | ||||
-rw-r--r-- | games/snake/snake/snake.c | 892 | ||||
-rw-r--r-- | games/snake/snake/snake.h | 85 | ||||
-rw-r--r-- | games/snake/snscore/Makefile | 9 | ||||
-rw-r--r-- | games/snake/snscore/snscore.c | 118 |
9 files changed, 1964 insertions, 0 deletions
diff --git a/games/snake/Makefile b/games/snake/Makefile new file mode 100644 index 0000000..0b8a472 --- /dev/null +++ b/games/snake/Makefile @@ -0,0 +1,5 @@ +# @(#)Makefile 8.1 (Berkeley) 5/31/93 + +SUBDIR= snake snscore + +.include <bsd.subdir.mk> diff --git a/games/snake/snake/Makefile b/games/snake/snake/Makefile new file mode 100644 index 0000000..c8b677b --- /dev/null +++ b/games/snake/snake/Makefile @@ -0,0 +1,11 @@ +# @(#)Makefile 8.1 (Berkeley) 5/31/93 + +PROG= snake +SRCS= snake.c move.c +MAN6= snake.6 +DPADD= ${LIBM} ${LIBTERM} ${LIBCOMPAT} +LDADD= -lm -ltermcap -lcompat +HIDEGAME=hidegame + +.include "../../Makefile.inc" +.include <bsd.prog.mk> diff --git a/games/snake/snake/move.c b/games/snake/snake/move.c new file mode 100644 index 0000000..ceaf3e8 --- /dev/null +++ b/games/snake/snake/move.c @@ -0,0 +1,694 @@ +/* + * Copyright (c) 1980, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)move.c 8.1 (Berkeley) 7/19/93"; +#endif /* not lint */ + +/************************************************************************* + * + * MOVE LIBRARY + * + * This set of subroutines moves a cursor to a predefined + * location, independent of the terminal type. If the + * terminal has an addressable cursor, it uses it. If + * not, it optimizes for tabs (currently) even if you don't + * have them. + * + * At all times the current address of the cursor must be maintained, + * and that is available as structure cursor. + * + * The following calls are allowed: + * move(sp) move to point sp. + * up() move up one line. + * down() move down one line. + * bs() move left one space (except column 0). + * nd() move right one space(no write). + * clear() clear screen. + * home() home. + * ll() move to lower left corner of screen. + * cr() carriage return (no line feed). + * pr() just like standard printf, but keeps track + * of cursor position. (Uses pstring). + * apr() same as printf, but first argument is &point. + * (Uses pstring). + * pstring(s) output the string of printing characters. + * However, '\r' is interpreted to mean return + * to column of origination AND do linefeed. + * '\n' causes <cr><lf>. + * putpad(str) calls tputs to output character with proper + * padding. + * outch() the output routine for a character used by + * tputs. It just calls putchar. + * pch(ch) output character to screen and update + * cursor address (must be a standard + * printing character). WILL SCROLL. + * pchar(ps,ch) prints one character if it is on the + * screen at the specified location; + * otherwise, dumps it.(no wrap-around). + * + * 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. + * + * point(&p,x,y) return point set to x,y. + * + * baudrate(x) returns the baudrate of the terminal. + * delay(t) causes an approximately constant delay + * independent of baudrate. + * Duration is ~ t/20 seconds. + * + ******************************************************************************/ + +#if __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif +#include "snake.h" + +int CMlength; +int NDlength; +int BSlength; +int delaystr[10]; +short ospeed; + +static char str[80]; + +move(sp) +struct point *sp; +{ + 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); + return; + } + if (sp->line >= LINES){ + move(point(&z,sp->col,LINES-1)); + while(sp->line-- >= LINES)putchar('\n'); + return; + } + + if (CM != 0) { + char *cmstr = tgoto(CM, sp->col, sp->line); + + CMlength = strlen(cmstr); + 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){ + right(sp); + return; + } + if(TA){ + ct=sp->col&7; + tabcol=(cursor.col|7)+1; + do{ + ct++; + tabcol=(tabcol|7)+1; + } + while(tabcol<sp->col); + if(ct<CMlength){ + right(sp); + return; + } + } + } else { /* Moving to the left */ + if (-distance*BSlength < CMlength){ + gto(sp); + return; + } + } + if(sp->col < CMlength){ + cr(); + right(sp); + return; + } + /* No more optimizations on same row. */ + } + distance = sp->col - cursor.col; + distance = distance > 0 ? + distance*NDlength : -distance * BSlength; + if (distance < 0) + pr("ERROR: distance is negative: %d",distance); + distance += abs(sp->line - cursor.line); + 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 + * address but can get there quicker with local motions. + */ + gto(sp); +} +gto(sp) +struct point *sp; +{ + + int distance,f,tfield,j; + + 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); + 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) + ){ + cr(); + right(sp); + } + 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; + } + else f = cursor.col >> 3; + if (((sp->line << 1) + 1 < cursor.line - f) && (HO != 0)){ + /* + * home quicker than rlf: + * (sp->line + f > cursor.line - sp->line) + */ + putpad(HO); + cursor.col = cursor.line = 0; + gto(sp); + return; + } + 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){ + /* is home faster than wraparound lf? + * (cursor.line + 20 - sp->line > 21 - sp->line + f) + */ + ll(); + gto(sp); + return; + } + } + 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(); + gto(sp); /*can recurse since cursor.line = sp->line */ +} + +right(sp) +struct point *sp; +{ + 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 + * loses count with control characters. + */ + field = cursor.col >> 3; +/* + * This code is useful for a terminal which wraps around on backspaces. + * (Mine does.) Unfortunately, this is not specified in termcap, and + * most terminals don't work that way. (Of course, most terminals + * have addressible cursors, too). + */ + if (BW && (CM == 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'); + return; + } + + tfield = sp->col >> 3; + + while (field < tfield){ + putpad(TA); + cursor.col = ++field << 3; + } + tabcol = (cursor.col|7) + 1; + strlength = (tabcol - sp->col)*BSlength + 1; + /* length of sequence to overshoot */ + if (((sp->col - cursor.col)*NDlength > strlength) && + (tabcol < COLUMNS) + ){ + /* + * Tab past and backup + */ + putpad(TA); + cursor.col = (cursor.col | 7) + 1; + while(cursor.col > sp->col)bs(); + } + } + while (sp->col > cursor.col){ + nd(); + } +} + +cr(){ + outch('\r'); + cursor.col = 0; +} + +clear(){ + int i; + + if (CL){ + putpad(CL); + cursor.col=cursor.line=0; + } else { + for(i=0; i<LINES; i++) { + putchar('\n'); + } + cursor.line = LINES - 1; + home(); + } +} + +home(){ + struct point z; + + if(HO != 0){ + putpad(HO); + cursor.col = cursor.line = 0; + return; + } + z.col = z.line = 0; + move(&z); +} + +ll(){ + int j,l; + struct point z; + + l = lcnt + 2; + if(LL != NULL && LINES==l){ + putpad(LL); + cursor.line = LINES-1; + cursor.col = 0; + return; + } + z.col = 0; + z.line = l-1; + move(&z); +} + +up(){ + putpad(UP); + cursor.line--; +} + +down(){ + putpad(DO); + cursor.line++; + if (cursor.line >= LINES)cursor.line=LINES-1; +} +bs(){ + if (cursor.col > 0){ + putpad(BS); + cursor.col--; + } +} + +nd(){ + putpad(ND); + cursor.col++; + if (cursor.col == COLUMNS+1){ + cursor.line++; + cursor.col = 0; + if (cursor.line >= LINES)cursor.line=LINES-1; + } +} + +pch(c) +{ + outch(c); + if(++cursor.col >= COLUMNS && AM) { + cursor.col = 0; + ++cursor.line; + } +} + +void +#if __STDC__ +apr(struct point *ps, const char *fmt, ...) +#else +apr(ps, fmt, va_alist) + struct point *ps; + char *fmt; + va_dcl +#endif +{ + struct point p; + va_list ap; + + p.line = ps->line+1; p.col = ps->col+1; + move(&p); +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + (void)vsprintf(str, fmt, ap); + va_end(ap); + pstring(str); +} + +void +#if __STDC__ +pr(const char *fmt, ...) +#else +pr(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + va_list ap; + +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + (void)vsprintf(str, fmt, ap); + va_end(ap); + pstring(str); +} + +pstring(s) +char *s;{ + struct point z; + int stcol; + + stcol = cursor.col; + while (s[0] != '\0'){ + switch (s[0]){ + case '\n': + move(point(&z,0,cursor.line+1)); + break; + case '\r': + move(point(&z,stcol,cursor.line+1)); + break; + case '\t': + z.col = (((cursor.col + 8) >> 3) << 3); + z.line = cursor.line; + move(&z); + break; + case '\b': + bs(); + break; + case CTRL('g'): + outch(CTRL('g')); + break; + default: + if (s[0] < ' ')break; + pch(s[0]); + } + s++; + } +} + +pchar(ps,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) + ) + ) + ){ + move(&p); + pch(ch); + } +} + + +outch(c) +{ + putchar(c); +} + +putpad(str) +char *str; +{ + if (str) + tputs(str, 1, outch); +} +baudrate() +{ + + switch (orig.sg_ospeed){ + case B300: + return(300); + case B1200: + return(1200); + case B4800: + return(4800); + case B9600: + return(9600); + default: + return(0); + } +} +delay(t) +int t; +{ + int k,j; + + k = baudrate() * t / 300; + for(j=0;j<k;j++){ + putchar(PC); + } +} + +done() +{ + cook(); + exit(0); +} + +cook() +{ + delay(1); + putpad(TE); + putpad(KE); + fflush(stdout); + stty(0, &orig); +#ifdef TIOCSLTC + ioctl(0, TIOCSLTC, &olttyc); +#endif +} + +raw() +{ + stty(0, &new); +#ifdef TIOCSLTC + ioctl(0, TIOCSLTC, &nlttyc); +#endif +} + +struct point *point(ps,x,y) +struct point *ps; +int x,y; +{ + ps->col=x; + ps->line=y; + return(ps); +} + +char *ap; + +getcap() +{ + char *getenv(); + char *term; + char *xPC; + struct point z; + void stop(); +#ifdef TIOCGWINSZ + struct winsize win; +#endif + + term = getenv("TERM"); + if (term==0) { + fprintf(stderr, "No TERM in environment\n"); + exit(1); + } + + switch (tgetent(tbuf, term)) { + case -1: + fprintf(stderr, "Cannot open termcap file\n"); + exit(2); + case 0: + fprintf(stderr, "%s: unknown terminal", term); + exit(3); + } + + ap = tcapbuf; + +#ifdef TIOCGWINSZ + if (ioctl(0, TIOCGWINSZ, (char *) &win) < 0 || + (LINES = win.ws_row) == 0 || (COLUMNS = win.ws_col) == 0) { +#endif + LINES = tgetnum("li"); + COLUMNS = tgetnum("co"); +#ifdef TIOCGWINSZ + } +#endif + if (!lcnt) + lcnt = LINES - 2; + if (!ccnt) + ccnt = COLUMNS - 3; + + AM = tgetflag("am"); + BW = tgetflag("bw"); + + ND = tgetstr("nd", &ap); + UP = tgetstr("up", &ap); + + DO = tgetstr("do", &ap); + if (DO == 0) + DO = "\n"; + + BS = tgetstr("bc", &ap); + if (BS == 0 && tgetflag("bs")) + BS = "\b"; + if (BS) + xBC = *BS; + + TA = tgetstr("ta", &ap); + if (TA == 0 && tgetflag("pt")) + TA = "\t"; + + HO = tgetstr("ho", &ap); + CL = tgetstr("cl", &ap); + CM = tgetstr("cm", &ap); + LL = tgetstr("ll", &ap); + + KL = tgetstr("kl", &ap); + KR = tgetstr("kr", &ap); + KU = tgetstr("ku", &ap); + KD = tgetstr("kd", &ap); + Klength = strlen(KL); + /* 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); + + xPC = tgetstr("pc", &ap); + if (xPC) + PC = *xPC; + + NDlength = strlen(ND); + BSlength = strlen(BS); + 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 (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); + } + + gtty(0, &orig); + new=orig; + new.sg_flags &= ~(ECHO|CRMOD|ALLDELAY|XTABS); + new.sg_flags |= CBREAK; + signal(SIGINT,stop); + ospeed = orig.sg_ospeed; +#ifdef TIOCGLTC + ioctl(0, TIOCGLTC, &olttyc); + nlttyc = olttyc; + nlttyc.t_suspc = '\377'; + nlttyc.t_dsuspc = '\377'; +#endif + raw(); + + if ((orig.sg_flags & XTABS) == XTABS) TA=0; + putpad(KS); + putpad(TI); + point(&cursor,0,LINES-1); +} diff --git a/games/snake/snake/pathnames.h b/games/snake/snake/pathnames.h new file mode 100644 index 0000000..72713d1 --- /dev/null +++ b/games/snake/snake/pathnames.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)pathnames.h 8.1 (Berkeley) 5/31/93 + */ + +#define _PATH_RAWSCORES "/var/games/snakerawscores" +#define _PATH_LOGFILE "/var/games/snake.log" diff --git a/games/snake/snake/snake.6 b/games/snake/snake/snake.6 new file mode 100644 index 0000000..14d86bf --- /dev/null +++ b/games/snake/snake/snake.6 @@ -0,0 +1,113 @@ +.\" Copyright (c) 1980, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)snake.6 8.1 (Berkeley) 5/31/93 +.\" +.TH SNAKE 6 "May 31, 1993" +.UC 4 +.SH NAME +snake, snscore \- display chase game +.SH SYNOPSIS +.B snake +[ +.B -w width +] [ +.B -l length +] +.br +.B snscore +.SH DESCRIPTION +Snake is a display-based game which must be played on a CRT terminal. +The object of the game is to make as much money as possible without +getting eaten by the snake. The +.B \-l +and +.B \-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. +.PP +You are represented on the screen by an I. +The snake is 6 squares long and is represented by S's. +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 vi(1), +the h, j, k, and l keys work, as do the arrow keys. +Other possibilities include: +.IP sefc +These keys are like hjkl but form a directed pad around the d key. +.IP HJKL +These keys move you all the way in the indicated direction to the +same row or column as the money. This does +.I not +let you jump away from the snake, but rather saves you from having +to type a key repeatedly. The snake still gets all his turns. +.IP SEFC +Likewise for the upper case versions on the left. +.IP ATPB +These keys move you to the four edges of the screen. +Their position on the keyboard is the mnemonic, e.g. +P is at the far right of the keyboard. +.IP x +This lets you quit the game at any time. +.IP p +Points in a direction you might want to go. +.IP w +Space warp to get out of tight squeezes, at a price. +.PP +To earn money, move to the same square the money is on. +A new $ will appear when you earn the current one. +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. +.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 +.I snscore . +.SH FILES +.nf +.ta \w'/usr/games/lib/snakerawscores 'u +/usr/games/lib/snakerawscores database of personal bests +/usr/games/lib/snake.log log of games played +.DT +.fi +.SH BUGS +.PP +When playing on a small screen, +it's hard to tell when you hit the edge of the screen. +.PP +The scoring function takes into account the size of the screen. +A perfect function to do this equitably has not been devised. diff --git a/games/snake/snake/snake.c b/games/snake/snake/snake.c new file mode 100644 index 0000000..b99da10 --- /dev/null +++ b/games/snake/snake/snake.c @@ -0,0 +1,892 @@ +/* + * Copyright (c) 1980, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1980, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)snake.c 8.2 (Berkeley) 1/7/94"; +#endif /* not lint */ + +/* + * 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 <sys/param.h> + +#include <errno.h> +#include <fcntl.h> +#include <pwd.h> +#include <time.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; +long tv; +char *tn; + +main(argc,argv) +int argc; +char **argv; +{ + extern char *optarg; + extern int optind; + int ch, i, j, k; + long atol(); + void stop(); + + (void)time(&tv); + srandom((int)tv); + + while ((ch = getopt(argc, argv, "l:w:")) != EOF) + switch((char)ch) { +#ifdef notdef + case 'd': + tv = atol(optarg); + break; +#endif + case 'w': /* width */ + ccnt = atoi(optarg); + break; + case 'l': /* length */ + lcnt = atoi(optarg); + break; + case '?': + default: + fputs("usage: snake [-d seed] [-w width] [-l length]\n", stderr); + exit(1); + } + + penalty = loot = 0; + getcap(); + + i = MIN(lcnt, ccnt); + if (i < 4) { + cook(); + pr("snake: screen too small for a fair game.\n"); + exit(1); + } + + /* + * 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 */ + + snrand(&finish); + snrand(&you); + snrand(&money); + snrand(&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'): + suspend(); + continue; + case EOT: + case 'x': + case 0177: /* del or end of file */ + ll(); + length(moves); + logit("quit"); + done(); + 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 { + 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); + winnings(cashvalue); + continue; + } + if (same(&you,&finish)) + { + win(&finish); + ll(); + cook(); + pr("You have won with $%d.\n",cashvalue); + fflush(stdout); + logit("won"); + post(cashvalue,1); + length(moves); + done(); + } + 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, '-'); + } +} + +snrand(sp) +struct point *sp; +{ + struct point p; + register int i; + + for (;;) { + p.col = random() % ccnt; + p.line = random() % lcnt; + + /* make sure it's not on top of something else */ + if (p.line == 0 && p.col < 5) + continue; + if (same(&p, &you)) + continue; + if (same(&p, &money)) + continue; + if (same(&p, &finish)) + continue; + for (i = 0; i < 5; i++) + if (same(&p, &snake[i])) + break; + if (i < 5) + continue; + break; + } + *sp = p; +} + +post(iscore, flag) +int iscore, flag; +{ + short score = iscore; + int rawscores; + short uid; + short oldbest=0; + short allbwho=0, allbscore=0; + struct passwd *p; + + /* + * Neg uid, 0, and 1 cannot have scores recorded. + */ + if ((uid = getuid()) <= 1) { + pr("No saved scores for uid %d.\n", uid); + return(1); + } + if ((rawscores = open(_PATH_RAWSCORES, O_RDWR|O_CREAT, 0644)) < 0) { + pr("No 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, ((long)uid)*sizeof(short), 0); + read(rawscores, &oldbest, sizeof(short)); + if (!flag) + return (score > oldbest ? 1 : 0); + + /* Update this jokers best */ + if (score > oldbest) { + lseek(rawscores, ((long)uid)*sizeof(short), 0); + write(rawscores, &score, sizeof(short)); + pr("You bettered your previous best of $%d\n", oldbest); + } else + pr("Your best to date is $%d\n", oldbest); + + /* See if we have a new champ */ + p = getpwuid(allbwho); + if (p == NULL || score > allbscore) { + lseek(rawscores, (long)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); +} + +/* + * Flush typeahead to keep from buffering a bunch of chars and then + * overshooting. This loses horribly at 9600 baud, but works nicely + * if the terminal gets behind. + */ +flushi() +{ + stty(0, &new); +} +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; +chase (np, sp) +struct point *sp, *np; +{ + /* 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++) + { + 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; + } + } + 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, + * 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]) + break; + else + vp -= wt[i]; + if (i==8) { + pr("failure\n"); + i=0; + while (wt[i]==0) i++; + } + oldw=w=i; + point(np,sp->col+mx[w],sp->line+my[w]); +} + +spacewarp(w) +int w;{ + struct point p; + int j; + char *str; + + snrand(&you); + point(&p,COLUMNS/2 - 8,LINES/2 - 1); + if (p.col < 0) + p.col = 0; + if (p.line < 0) + p.line = 0; + if (w) { + str = "BONUS!!!"; + loot = loot - penalty; + penalty = 0; + } else { + str = "SPACE WARP!!!"; + penalty += loot/PENALTY; + } + for(j=0;j<3;j++){ + clear(); + delay(5); + apr(&p,str); + delay(10); + } + setup(); + winnings(cashvalue); +} +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); + } + fflush(stdout); +} +stretch(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'); + delay(10); + for (;p.line > you.line;p.line--) + chk(&p); + } else { + for (p.line = you.line-1;p.line >= ps->line;p.line--) + pchar(&p,'^'); + delay(10); + for (;p.line < you.line;p.line++) + chk(&p); + } + return(1); + } else if(abs(ps->line-you.line) < 3){ + p.line = you.line; + if(you.col < ps->col){ + for (p.col = you.col+1;p.col <= ps->col;p.col++) + pchar(&p,'>'); + delay(10); + for (;p.col > you.col;p.col--) + chk(&p); + } else { + for (p.col = you.col-1;p.col >= ps->col;p.col--) + pchar(&p,'<'); + delay(10); + for (;p.col < you.col;p.col++) + chk(&p); + } + return(1); + } + return(0); +} + +surround(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,'@'); + delay(1); + pchar(ps,' '); + delay(1); + } + if (post(cashvalue,0)) { + apr(point(&x,ps->col-1,ps->line-1)," \ro.o\r\\_/"); + delay(6); + apr(point(&x,ps->col-1,ps->line-1)," \ro.-\r\\_/"); + delay(6); + } + apr(point(&x,ps->col-1,ps->line-1)," \ro.o\r\\_/"); +} +win(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,'#'); + x.line--; + } + for(k=0;k<j;k++){ + pchar(&x,'#'); + x.col++; + } + j++; + for(k=0;k<j;k++){ + pchar(&x,'#'); + x.line++; + } + for(k=0;k<j;k++){ + pchar(&x,'#'); + x.col--; + } + } + fflush(stdout); +} + +pushsnake() +{ + int i, bonus; + int issame = 0; + + /* + * My manual says times doesn't return a value. Furthermore, the + * snake should get his turn every time no matter if the user is + * on a fast terminal with typematic keys or not. + * So I have taken the call to times out. + */ + 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]; + chase(&snake[0], &snake[1]); + pchar(&snake[1],SNAKETAIL); + pchar(&snake[0],SNAKEHEAD); + for(i=0; i<6; i++) + { + if (same(&snake[i],&you)) + { + surround(&you); + i = (cashvalue) % 10; + bonus = ((rand()>>8) & 0377)% 10; + ll(); + pr("%d\n", bonus); + delay(30); + if (bonus == i) { + spacewarp(1); + logit("bonus"); + flushi(); + return(1); + } + if ( loot >= penalty ){ + pr("You and your $%d have been eaten\n", + cashvalue); + } else { + pr("The snake ate you. You owe $%d.\n", + -cashvalue); + } + logit("eaten"); + length(moves); + done(); + } + } + return(0); +} + +chk(sp) +struct point *sp; +{ + int j; + + if (same(sp,&money)) { + pchar(sp,TREASURE); + return(2); + } + if (same(sp,&finish)) { + pchar(sp,GOAL); + return(3); + } + if (same(sp,&snake[0])) { + pchar(sp,SNAKEHEAD); + return(4); + } + for(j=1;j<6;j++){ + if(same(sp,&snake[j])){ + pchar(sp,SNAKETAIL); + return(4); + } + } + if ((sp->col < 4) && (sp->line == 0)){ + winnings(cashvalue); + if((you.line == 0) && (you.col < 4)) pchar(&you,ME); + return(5); + } + if (same(sp,&you)) { + pchar(sp,ME); + return(1); + } + pchar(sp,' '); + return(0); +} +winnings(won) +int won; +{ + struct point p; + + p.line = p.col = 1; + if(won>0){ + move(&p); + pr("$%d",won); + } +} + +void +stop(){ + signal(SIGINT,SIG_IGN); + ll(); + length(moves); + done(); +} + +suspend() +{ + char *sh; + + ll(); + cook(); + kill(getpid(), SIGTSTP); + raw(); + setup(); + winnings(cashvalue); +} + +length(num) +int num; +{ + pr("You made %d moves.\n",num); +} + +logit(msg) +char *msg; +{ + FILE *logfile; + long t; + + if ((logfile=fopen(_PATH_LOGFILE, "a")) != NULL) { + time(&t); + fprintf(logfile, "%s $%d %dx%d %s %s", + getlogin(), cashvalue, lcnt, ccnt, msg, ctime(&t)); + fclose(logfile); + } +} diff --git a/games/snake/snake/snake.h b/games/snake/snake/snake.h new file mode 100644 index 0000000..792fc36 --- /dev/null +++ b/games/snake/snake/snake.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 1980, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)snake.h 8.1 (Berkeley) 5/31/93 + */ + +# include <stdio.h> +# include <assert.h> +# include <sys/types.h> +# include <sgtty.h> +# include <signal.h> +# include <math.h> + +#define ESC '\033' + +struct tbuffer { + long t[4]; +} tbuffer; + +char *CL, *UP, *DO, *ND, *BS, + *HO, *CM, + *TA, *LL, + *KL, *KR, *KU, *KD, + *TI, *TE, *KS, *KE; +int LINES, COLUMNS; /* physical screen size. */ +int lcnt, ccnt; /* user's idea of screen size */ +char xBC, 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 */ +#ifdef debug +#define cashvalue (loot-penalty)/25 +#else +#define cashvalue chunk*(loot-penalty)/25 +#endif + +struct point { + int col, line; +}; +struct point cursor; +struct sgttyb orig, new; +#ifdef TIOCLGET +struct ltchars olttyc, nlttyc; +#endif +struct point *point(); +#if __STDC__ +void apr(struct point *, const char *, ...); +void pr(const char *, ...); +#else +void apr(); +void pr(); +#endif + +#define same(s1, s2) ((s1)->line == (s2)->line && (s1)->col == (s2)->col) diff --git a/games/snake/snscore/Makefile b/games/snake/snscore/Makefile new file mode 100644 index 0000000..29feb57 --- /dev/null +++ b/games/snake/snscore/Makefile @@ -0,0 +1,9 @@ +# @(#)Makefile 8.1 (Berkeley) 5/31/93 + +PROG= snscore +CFLAGS+=-I${.CURDIR}/../snake +NOMAN= noman +HIDEGAME=hidegame + +.include "../../Makefile.inc" +.include <bsd.prog.mk> diff --git a/games/snake/snscore/snscore.c b/games/snake/snscore/snscore.c new file mode 100644 index 0000000..1590404 --- /dev/null +++ b/games/snake/snscore/snscore.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 1980, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1980, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)snscore.c 8.1 (Berkeley) 7/19/93"; +#endif /* not lint */ + +#include <sys/types.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include "pathnames.h" + +char *recfile = _PATH_RAWSCORES; +#define MAXPLAYERS 256 + +struct player { + short uids; + short scores; + char *name; +} players[MAXPLAYERS], temp; + +int +main() +{ + short uid, 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); + } + printf("Snake players scores to date\n"); + fread(&whoallbest, sizeof(short), 1, fd); + fread(&allbest, sizeof(short), 1, fd); + noplayers = 0; + for (uid = 2; ;uid++) { + if(fread(&score, sizeof(short), 1, fd) == 0) + break; + if (score > 0) { + if (noplayers > MAXPLAYERS) { + printf("too many players\n"); + exit(2); + } + 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); + strcpy(players[noplayers].name, q); + noplayers++; + } + } + + /* bubble sort scores */ + for (notsorted = 1; notsorted; ) { + notsorted = 0; + for (i = 0; i < noplayers - 1; i++) + if (players[i].scores < players[i + 1].scores) { + temp = players[i]; + players[i] = players[i + 1]; + players[i + 1] = temp; + notsorted++; + } + } + + 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); +} |