mirror of
https://github.com/vattam/BSDGames.git
synced 2025-12-20 19:04:49 +00:00
Initial revision
git-svn-id: file:///srv/svn/joey/bsdgames-trunk@5086 a4a2c43b-8ac3-0310-8836-e0e880c912e2
This commit is contained in:
6
snake/Makefile.bsd
Normal file
6
snake/Makefile.bsd
Normal file
@@ -0,0 +1,6 @@
|
||||
# $NetBSD: Makefile,v 1.3 1995/04/22 08:34:18 cgd Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||
|
||||
SUBDIR= snake snscore
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
5
snake/Makefrag
Normal file
5
snake/Makefrag
Normal file
@@ -0,0 +1,5 @@
|
||||
# Makefrag - makefile fragment for snake
|
||||
|
||||
snake_all:
|
||||
|
||||
snake_install:
|
||||
13
snake/snake/Makefile.bsd
Normal file
13
snake/snake/Makefile.bsd
Normal file
@@ -0,0 +1,13 @@
|
||||
# $NetBSD: Makefile,v 1.8 1998/02/04 10:24:13 christos Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||
|
||||
PROG= snake
|
||||
SRCS= snake.c move.c
|
||||
MAN= snake.6
|
||||
DPADD= ${LIBM} ${LIBTERMCAP}
|
||||
LDADD= -lm -ltermcap
|
||||
HIDEGAME=hidegame
|
||||
SETGIDGAME=yes
|
||||
|
||||
.include "../../Makefile.inc"
|
||||
.include <bsd.prog.mk>
|
||||
12
snake/snake/Makefrag
Normal file
12
snake/snake/Makefrag
Normal file
@@ -0,0 +1,12 @@
|
||||
# Makefrag - makefile fragment for snake/snake
|
||||
|
||||
snake_snake_DIRS := $(GAMESDIR) $(MAN6DIR)
|
||||
|
||||
snake_snake_all: snake/snake/snake snake/snake/snake.6
|
||||
|
||||
snake_snake_install: snake_snake_all
|
||||
$(INSTALL_SCORE_GAME) snake/snake/snake $(INSTALL_PREFIX)$(GAMESDIR)/snake
|
||||
$(HIDE_GAME) snake
|
||||
$(INSTALL_SCORE_FILE) $(SNAKE_SCOREFILE)
|
||||
$(INSTALL_SCORE_FILE) $(SNAKE_RAWSCOREFILE)
|
||||
$(INSTALL_MANUAL) snake/snake/snake.6
|
||||
717
snake/snake/move.c
Normal file
717
snake/snake/move.c
Normal file
@@ -0,0 +1,717 @@
|
||||
/* $NetBSD: move.c,v 1.15 1997/10/14 01:02:48 lukem Exp $ */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)move.c 8.1 (Berkeley) 7/19/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: move.c,v 1.15 1997/10/14 01:02:48 lukem Exp $");
|
||||
#endif
|
||||
#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.
|
||||
*
|
||||
* 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 <unistd.h> /* For _POSIX_VDISABLE */
|
||||
#include "snake.h"
|
||||
|
||||
int CMlength;
|
||||
int NDlength;
|
||||
int BSlength;
|
||||
int delaystr[10];
|
||||
#ifndef NCURSES_VERSION
|
||||
speed_t ospeed;
|
||||
#endif
|
||||
|
||||
static char str[80];
|
||||
|
||||
void
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
gto(sp)
|
||||
struct point *sp;
|
||||
{
|
||||
|
||||
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);
|
||||
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 */
|
||||
}
|
||||
|
||||
void
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cr()
|
||||
{
|
||||
outch('\r');
|
||||
cursor.col = 0;
|
||||
}
|
||||
|
||||
void
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
home()
|
||||
{
|
||||
struct point z;
|
||||
|
||||
if (HO != 0) {
|
||||
putpad(HO);
|
||||
cursor.col = cursor.line = 0;
|
||||
return;
|
||||
}
|
||||
z.col = z.line = 0;
|
||||
move(&z);
|
||||
}
|
||||
|
||||
void
|
||||
ll()
|
||||
{
|
||||
int 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);
|
||||
}
|
||||
|
||||
void
|
||||
up()
|
||||
{
|
||||
putpad(UP);
|
||||
cursor.line--;
|
||||
}
|
||||
|
||||
void
|
||||
down()
|
||||
{
|
||||
putpad(DO);
|
||||
cursor.line++;
|
||||
if (cursor.line >= LINES)
|
||||
cursor.line = LINES - 1;
|
||||
}
|
||||
|
||||
void
|
||||
bs()
|
||||
{
|
||||
if (cursor.col > 0) {
|
||||
putpad(BS);
|
||||
cursor.col--;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nd()
|
||||
{
|
||||
putpad(ND);
|
||||
cursor.col++;
|
||||
if (cursor.col == COLUMNS + 1) {
|
||||
cursor.line++;
|
||||
cursor.col = 0;
|
||||
if (cursor.line >= LINES)
|
||||
cursor.line = LINES - 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pch(c)
|
||||
int 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);
|
||||
}
|
||||
|
||||
void
|
||||
pstring(s)
|
||||
const 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++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
outch(c)
|
||||
int c;
|
||||
{
|
||||
return putchar(c);
|
||||
}
|
||||
|
||||
void
|
||||
putpad(str)
|
||||
char *str;
|
||||
{
|
||||
if (str)
|
||||
tputs(str, 1, outch);
|
||||
}
|
||||
|
||||
void
|
||||
delay(t)
|
||||
int t;
|
||||
{
|
||||
int k, j;
|
||||
|
||||
k = (ospeed * t + 100) / 200;
|
||||
for (j = 0; j < k; j++) {
|
||||
putchar(PC);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
done()
|
||||
{
|
||||
cook();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
cook()
|
||||
{
|
||||
delay(1);
|
||||
putpad(TE);
|
||||
putpad(KE);
|
||||
fflush(stdout);
|
||||
tcsetattr(0, TCSADRAIN, &orig);
|
||||
}
|
||||
|
||||
void
|
||||
my_raw()
|
||||
{
|
||||
tcsetattr(0, TCSADRAIN, &new);
|
||||
}
|
||||
|
||||
struct point *
|
||||
point(ps, x, y)
|
||||
struct point *ps;
|
||||
int x, y;
|
||||
{
|
||||
ps->col = x;
|
||||
ps->line = y;
|
||||
return (ps);
|
||||
}
|
||||
|
||||
char *ap;
|
||||
|
||||
void
|
||||
getcap()
|
||||
{
|
||||
char *term;
|
||||
char *xPC;
|
||||
#ifdef TIOCGWINSZ
|
||||
struct winsize win;
|
||||
#endif
|
||||
|
||||
term = getenv("TERM");
|
||||
if (term == 0)
|
||||
errx(1, "No TERM in environment");
|
||||
switch (tgetent(tbuf, term)) {
|
||||
case -1:
|
||||
errx(2, "Cannot open termcap file");
|
||||
case 0:
|
||||
errx(3, "unknown terminal `%s'", term);
|
||||
}
|
||||
|
||||
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("le", &ap);
|
||||
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";
|
||||
|
||||
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);
|
||||
if (KL && KR && KU && KD)
|
||||
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. */
|
||||
|
||||
TI = tgetstr("ti", &ap);
|
||||
TE = tgetstr("te", &ap);
|
||||
KS = tgetstr("ks", &ap);
|
||||
KE = tgetstr("ke", &ap);
|
||||
|
||||
xPC = tgetstr("pc", &ap);
|
||||
if (xPC)
|
||||
PC = *xPC;
|
||||
|
||||
if ((CM == 0) &&
|
||||
(HO == 0 || UP == 0 || BS == 0 || ND == 0))
|
||||
errx(5, "Terminal must have addressible cursor or home + 4 local motions");
|
||||
if (ND == 0)
|
||||
errx(5, "Terminal must have `nd' capability");
|
||||
NDlength = strlen(ND);
|
||||
if (BS == 0)
|
||||
errx(5, "Terminal must have 'le' or `bs' or `bc' capability");
|
||||
BSlength = strlen(BS);
|
||||
|
||||
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);
|
||||
ospeed = cfgetospeed(&orig);
|
||||
new.c_cc[VSUSP] = _POSIX_VDISABLE;
|
||||
#ifdef VDSUSP
|
||||
new.c_cc[VDSUSP] = _POSIX_VDISABLE;
|
||||
#endif
|
||||
my_raw();
|
||||
|
||||
if (orig.c_oflag & OXTABS)
|
||||
TA = 0;
|
||||
putpad(KS);
|
||||
putpad(TI);
|
||||
point(&cursor, 0, LINES - 1);
|
||||
}
|
||||
39
snake/snake/pathnames.h.in
Normal file
39
snake/snake/pathnames.h.in
Normal file
@@ -0,0 +1,39 @@
|
||||
/* $NetBSD: pathnames.h,v 1.3 1995/04/22 08:34:33 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* 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 "@snake_rawscorefile@"
|
||||
#define _PATH_LOGFILE "@snake_scorefile@"
|
||||
124
snake/snake/snake.6.in
Normal file
124
snake/snake/snake.6.in
Normal file
@@ -0,0 +1,124 @@
|
||||
.\" $NetBSD: snake.6,v 1.6 1997/10/12 01:49:26 lukem Exp $
|
||||
.\"
|
||||
.\" 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
|
||||
.\"
|
||||
.Dd May 31, 1993
|
||||
.Dt SNAKE 6
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm snake ,
|
||||
.Nm snscore
|
||||
.Nd display chase game
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl w Ar width
|
||||
.Op Fl l Ar length
|
||||
.br
|
||||
.Nm snscore
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
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
|
||||
.Fl l
|
||||
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.
|
||||
.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
|
||||
.Xr vi 1 ,
|
||||
the
|
||||
.Ic h ,
|
||||
.Ic j ,
|
||||
.Ic k ,
|
||||
and
|
||||
.Ic l
|
||||
keys work, as do the arrow keys.
|
||||
Other possibilities include:
|
||||
.Bl -tag -width indent
|
||||
.It Ic sefc
|
||||
These keys are like hjkl but form a directed pad around the d key.
|
||||
.It Ic HJKL
|
||||
These keys move you all the way in the indicated direction to the
|
||||
same row or column as the money. This does
|
||||
.Em 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.
|
||||
.It Ic SEFC
|
||||
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.
|
||||
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.
|
||||
.It Ic w
|
||||
Space warp to get out of tight squeezes, at a price.
|
||||
.El
|
||||
.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
|
||||
.Nm snscore .
|
||||
.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
|
||||
.El
|
||||
.Sh BUGS
|
||||
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.
|
||||
967
snake/snake/snake.c
Normal file
967
snake/snake/snake.c
Normal file
@@ -0,0 +1,967 @@
|
||||
/* $NetBSD: snake.c,v 1.9 1997/10/12 01:49:28 lukem Exp $ */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1980, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)snake.c 8.2 (Berkeley) 1/7/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: snake.c,v 1.9 1997/10/12 01:49:28 lukem Exp $");
|
||||
#endif
|
||||
#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 <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
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
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 rawscores;
|
||||
FILE *logfile;
|
||||
|
||||
int main __P((int, char **));
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
int ch, i;
|
||||
|
||||
/* Open score files then revoke setgid privileges */
|
||||
rawscores = open(_PATH_RAWSCORES, O_RDWR|O_CREAT, 0664);
|
||||
if (rawscores < 0) {
|
||||
warn("open %s", _PATH_RAWSCORES);
|
||||
sleep(2);
|
||||
}
|
||||
logfile = fopen(_PATH_LOGFILE, "a");
|
||||
if (logfile == NULL) {
|
||||
warn("fopen %s", _PATH_LOGFILE);
|
||||
sleep(2);
|
||||
}
|
||||
setregid(getgid(), getgid());
|
||||
|
||||
(void) time(&tv);
|
||||
srandom((int) tv);
|
||||
|
||||
while ((ch = getopt(argc, argv, "l:w:")) != -1)
|
||||
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 (ospeed < 9600 || ((!CM) && (!TA)))
|
||||
fast = 0;
|
||||
for (i = 1; i < 6; i++)
|
||||
chase(&snake[i], &snake[i - 1]);
|
||||
setup();
|
||||
mainloop();
|
||||
/* NOTREACHED */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Main command loop */
|
||||
void
|
||||
mainloop()
|
||||
{
|
||||
int j, k;
|
||||
|
||||
for (;;) {
|
||||
int c, lastc, match;
|
||||
struct point tmp;
|
||||
|
||||
lastc = 0;
|
||||
tmp.col = you.col + 1;
|
||||
tmp.line = you.line + 1; /* Highlight you, not left & above */
|
||||
move(&tmp);
|
||||
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)) {
|
||||
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 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(&snake[0], SNAKEHEAD);
|
||||
drawbox();
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void
|
||||
drawbox()
|
||||
{
|
||||
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, '-');
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
snrand(sp)
|
||||
struct point *sp;
|
||||
{
|
||||
struct point p;
|
||||
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;
|
||||
}
|
||||
|
||||
int
|
||||
post(iscore, flag)
|
||||
int iscore, flag;
|
||||
{
|
||||
short score = iscore;
|
||||
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 < 0) {
|
||||
/* Error reported earlier */
|
||||
return (1);
|
||||
}
|
||||
/* Figure out what happened in the past */
|
||||
read(rawscores, &allbscore, sizeof(short));
|
||||
read(rawscores, &allbwho, sizeof(short));
|
||||
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), SEEK_SET);
|
||||
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, 0, SEEK_SET);
|
||||
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);
|
||||
lseek(rawscores, 0, SEEK_SET);
|
||||
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.
|
||||
*/
|
||||
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;
|
||||
|
||||
void
|
||||
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]);
|
||||
}
|
||||
|
||||
void
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
snap()
|
||||
{
|
||||
struct point p;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
int
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
surround(ps)
|
||||
struct point *ps;
|
||||
{
|
||||
struct point x;
|
||||
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, '@');
|
||||
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\\_/");
|
||||
}
|
||||
|
||||
void
|
||||
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);
|
||||
}
|
||||
|
||||
int
|
||||
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);
|
||||
}
|
||||
|
||||
int
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
winnings(won)
|
||||
int won;
|
||||
{
|
||||
struct point p;
|
||||
|
||||
p.line = p.col = 1;
|
||||
if (won > 0) {
|
||||
move(&p);
|
||||
pr("$%d", won);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
stop(dummy)
|
||||
int dummy __attribute__((unused));
|
||||
{
|
||||
signal(SIGINT, SIG_IGN);
|
||||
ll();
|
||||
length(moves);
|
||||
done();
|
||||
}
|
||||
|
||||
void
|
||||
suspend()
|
||||
{
|
||||
ll();
|
||||
cook();
|
||||
kill(getpid(), SIGTSTP);
|
||||
my_raw();
|
||||
setup();
|
||||
winnings(cashvalue);
|
||||
}
|
||||
|
||||
void
|
||||
length(num)
|
||||
int num;
|
||||
{
|
||||
pr("You made %d moves.\n", num);
|
||||
}
|
||||
|
||||
void
|
||||
logit(msg)
|
||||
const char *msg;
|
||||
{
|
||||
time_t t;
|
||||
|
||||
if (logfile != NULL) {
|
||||
time(&t);
|
||||
fprintf(logfile, "%s $%d %dx%d %s %s",
|
||||
getlogin(), cashvalue, lcnt, ccnt, msg, ctime(&t));
|
||||
fflush(logfile);
|
||||
}
|
||||
}
|
||||
130
snake/snake/snake.h
Normal file
130
snake/snake/snake.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/* $NetBSD: snake.h,v 1.10 1998/09/13 15:27:30 hubertf Exp $ */
|
||||
|
||||
/*
|
||||
* 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 <sys/types.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <assert.h>
|
||||
# include <err.h>
|
||||
# include <math.h>
|
||||
# include <signal.h>
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <termcap.h>
|
||||
# include <termios.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 PC;
|
||||
int AM, BW;
|
||||
char tbuf[1024], tcapbuf[128];
|
||||
int Klength; /* length of KX strings */
|
||||
int chunk; /* amount of money given at a time */
|
||||
#ifndef NCURSES_VERSION
|
||||
speed_t ospeed;
|
||||
#endif
|
||||
#ifdef debug
|
||||
#define cashvalue (loot-penalty)/25
|
||||
#else
|
||||
#define cashvalue chunk*(loot-penalty)/25
|
||||
#endif
|
||||
|
||||
struct point {
|
||||
int col, line;
|
||||
};
|
||||
struct point cursor;
|
||||
struct termios orig, new;
|
||||
|
||||
#define same(s1, s2) ((s1)->line == (s2)->line && (s1)->col == (s2)->col)
|
||||
|
||||
|
||||
void apr __P((struct point *, const char *, ...));
|
||||
void bs __P((void));
|
||||
void chase __P((struct point *, struct point *));
|
||||
int chk __P((struct point *));
|
||||
void clear __P((void));
|
||||
void cook __P((void));
|
||||
void cr __P((void));
|
||||
void delay __P((int));
|
||||
void done __P((void)) __attribute__((__noreturn__));
|
||||
void down __P((void));
|
||||
void drawbox __P((void));
|
||||
void flushi __P((void));
|
||||
void getcap __P((void));
|
||||
void gto __P((struct point *));
|
||||
void home __P((void));
|
||||
void length __P((int));
|
||||
void ll __P((void));
|
||||
void logit __P((const char *));
|
||||
void mainloop __P((void));
|
||||
void move __P((struct point *));
|
||||
void nd __P((void));
|
||||
int outch __P((int));
|
||||
void pch __P((int));
|
||||
void pchar __P((struct point *, char));
|
||||
struct point *point __P((struct point *, int, int));
|
||||
int post __P((int, int));
|
||||
void pr __P((const char *, ...));
|
||||
void pstring __P((const char *));
|
||||
int pushsnake __P((void));
|
||||
void putpad __P((char *));
|
||||
void my_raw __P((void));
|
||||
void right __P((struct point *));
|
||||
void setup __P((void));
|
||||
void snap __P((void));
|
||||
void snap __P((void));
|
||||
void snrand __P((struct point *));
|
||||
void spacewarp __P((int));
|
||||
void stop __P((int)) __attribute__((__noreturn__));
|
||||
int stretch __P((struct point *));
|
||||
int stretch __P((struct point *));
|
||||
void surround __P((struct point *));
|
||||
void suspend __P((void));
|
||||
void up __P((void));
|
||||
void win __P((struct point *));
|
||||
void winnings __P((int));
|
||||
10
snake/snscore/Makefile.bsd
Normal file
10
snake/snscore/Makefile.bsd
Normal file
@@ -0,0 +1,10 @@
|
||||
# $NetBSD: Makefile,v 1.4 1997/10/22 05:26:25 lukem Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||
|
||||
PROG= snscore
|
||||
CPPFLAGS+=-I${.CURDIR}/../snake
|
||||
NOMAN= noman
|
||||
HIDEGAME=hidegame
|
||||
|
||||
.include "../../Makefile.inc"
|
||||
.include <bsd.prog.mk>
|
||||
11
snake/snscore/Makefrag
Normal file
11
snake/snscore/Makefrag
Normal file
@@ -0,0 +1,11 @@
|
||||
# Makefrag - makefile fragment for snake/snscore
|
||||
|
||||
snake_snscore_DIRS := $(GAMESDIR) $(MAN6DIR)
|
||||
snake_snscore_INCS := -Isnake/snake
|
||||
|
||||
snake_snscore_all: snake/snscore/snscore
|
||||
|
||||
snake_snscore_install: snake_snscore_all
|
||||
$(INSTALL_BINARY) snake/snscore/snscore $(INSTALL_PREFIX)$(GAMESDIR)/snscore
|
||||
$(HIDE_GAME) snscore
|
||||
$(INSTALL_MANUAL) snake.6 snscore.6
|
||||
133
snake/snscore/snscore.c
Normal file
133
snake/snscore/snscore.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/* $NetBSD: snscore.c,v 1.8 1998/09/11 14:25:22 hubertf Exp $ */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1980, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)snscore.c 8.1 (Berkeley) 7/19/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: snscore.c,v 1.8 1998/09/11 14:25:22 hubertf Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <err.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "pathnames.h"
|
||||
|
||||
char *recfile = _PATH_RAWSCORES;
|
||||
#define MAXPLAYERS 65534
|
||||
|
||||
struct player {
|
||||
short uids;
|
||||
short scores;
|
||||
char *name;
|
||||
} players[MAXPLAYERS], temp;
|
||||
|
||||
int main __P((void));
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
short uid, score;
|
||||
FILE *fd;
|
||||
int noplayers;
|
||||
int i, j, notsorted;
|
||||
short whoallbest, allbest;
|
||||
const char *q;
|
||||
struct passwd *p;
|
||||
|
||||
/* Revoke setgid privileges */
|
||||
setregid(getgid(), getgid());
|
||||
|
||||
fd = fopen(recfile, "r");
|
||||
if (fd == NULL)
|
||||
err(1, "opening `%s'", recfile);
|
||||
printf("Snake players scores to date\n");
|
||||
if (fread(&whoallbest, sizeof(short), 1, fd) == 0) {
|
||||
printf("No scores recorded yet!\n");
|
||||
exit(0);
|
||||
}
|
||||
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: %d\n", noplayers);
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user