[comp.sources.games] v01i071: cent - centipede video game

games-request@tekred.TEK.COM (07/01/87)

Submitted by: Nathan Glasser <nathan@eddie.mit.edu>
Comp.sources.games: Volume 1, Issue 71
Archive-name: cent

	[I compiled and ran this - works pretty neat (as long as the
	 system is lightly loaded and thebaud rate is fairly high). -br]

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README Makefile cent.c cent.doc cent.h extern.c input.c
#   install.doc interrupts.c la.c move.c options.c rand.c save.c
#   score.c shoot.c stuff.c sys_dep.c sys_dep.h
# Wrapped by billr@tekred on Wed Jul  1 09:24:37 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(1049 characters\)
sed "s/^X//" >README <<'END_OF_README'
XCentipede is based on the video game by the same name which has been
Xaround for many years. It is a real-time 'video' game for standard
Xcharacter terminals on Unix machines.
X
XThe game was written for 4.1bsd Unix, and has recently been tested
Xon 4.2. No guarantees are made for any other versions, though I'd
Xbe interested in hearing about what happens.
X
XAmong other features, the game allows for saving/restoring, has load
Xaverage restrictions, and keeps a high score list. 
X
XSorry, there is no 'man page' available. A help file is available from
Xwithin the game.
X
XEdit the file 'sys_dep.c' to adjust pathnames for your particular system.
X
XI wrote this game about four years ago, and (after a couple of recent
Xmodifications) decided it was time that I share it with other Usenet
Xgame players. I'm not too keen on keeping track of tons of bugs, but
Xfor the time, feel free to report whatever you want to me at one of
Xthe mail addresses below.
X
X				Have Fun,
X
X				Nathan Glasser
X				nathan@mit-eddie.uucp (usenet)
X				nathan@xx.lcs.mit.edu (internet)
END_OF_README
if test 1049 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile\"
else
echo shar: Extracting \"Makefile\" \(388 characters\)
sed "s/^X//" >Makefile <<'END_OF_Makefile'
X# makefile for centipede
X# edit sys_dep.c to adjust pathnames for your system
X#
XCFLAGS = -O
X
XOBJECTS = cent.o stuff.o input.o interrupts.o score.o move.o rand.o \
X		save.o shoot.o la.o extern.o options.o sys_dep.o
X
Xcent:   $(OBJECTS)
X	cc -s -x -o cent $(OBJECTS) -lcurses -ltermcap -lm
X
Xcent.o stuff.o input.o move.o shoot.o save.o extern.o options.o: cent.h
Xinput.o options.o: sys_dep.h
END_OF_Makefile
if test 388 -ne `wc -c <Makefile`; then
    echo shar: \"Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f cent.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"cent.c\"
else
echo shar: Extracting \"cent.c\" \(5410 characters\)
sed "s/^X//" >cent.c <<'END_OF_cent.c'
X/* Centipede
X   Copyright 1987 by Nathan Glasser
X   Do not redistribute this source code without including this
X   copyright notice.
X*/
X
X
X#include "cent.h"
X
Xmain(argc,argv)
Xint argc;
Xchar **argv;
X{
X    int rest = 0;
X
X    if (argc > 2)
X    {
X	printf("Usage: cent [-s] [savefile]\n");
X	exit(0);
X    }
X    signal(SIGTSTP,SIG_IGN);
X    signal(SIGQUIT,quit);
X    signal(SIGINT,SIG_IGN);
X    if (argc == 2 && !strcmp(argv[1],"-s"))
X	showscores();
X    dooptions();
X    strcpy(name,getlogin());
X#ifdef WIZARD
X    author = !strcmp(name,"nathan");
X    if (author && getenv("CENTNAME") != NULL)
X	strcpy(name,getenv("CENTNAME"));
X#endif
X    if (toohigh())
X    {
X	printf("Sorry, the load average is too high to play now.\n");
X	exit(0);
X    }
X    ioctl(0,TIOCGETP,&origterm);
X    initscr();
X    if (LINES < 24 || COLS < 80)
X    {
X	printf("Screen size too small. Size must be at least 24 X 80.\n");
X	exit(0);
X    }
X    rninit();
X    if (argc > 1)
X    {
X	dorest(argv[1]);
X	showla();
X	gamestarted = rest = 1;
X    }
X    else
X	instructions();
X    signal(SIGINT,catchint);
X    signal(SIGTSTP,catchstop);
X    signal(SIGALRM,catchalarm);
X    noecho();
X    crmode();
X    nonl();
X    if (rest)
X    {
X	waitboard();
X	if (dead)
X	{
X	    contdeath();
X	    rest = 0;
X	}
X    }
X    else
X	make_screen();
X    gamestarted = 1;
X    nice(niceness);
X    while (1)
X    {
X	fleafreq = 4 - ((board + 2) % 4);
X	if (rest)
X	    rest = 0;
X	else
X	{
X	    make_cent((board - 1) % CENTLENGTH);
X	    put_pede();
X	    refresh();
X	}
X	movestuff();
X	if (dead)
X	   death();
X    }
X}
X
Xmake_screen()
X{
X    register int i,y,x;
X
X    clear();
X    for (y = 0; y <= 22; y++)
X	for (x = 1; x <= 55; x++)
X	    mushw[y][x] = ' ';
X    for (i = 0; i <= 22; i++)
X    {
X	mvaddch(i,0,'|');
X	mushw[i][0] = '|';
X	mvaddch(i,56,'|');
X	mushw[i][56] = '|';
X    }
X    mvaddch(17,0,'-');
X    mushw[17][0] = '-';
X    mvaddch(17,56,'-');
X    mushw[17][56] = '-';
X    move(23,0);
X    for (i = 0; i <= 56; i++)
X    {
X	addch('-');
X	mushw[23][i] = '-';
X    }
X    nummushrooms = 0;
X    for (i = 45 + rnd(15); i; i--)
X    {
X	do
X	{
X	    y = rnd(22);        /* not on bottom row */
X	    x = rnd(55) + 1;
X	}
X	while (mvinch(y,x) != ' ');
X	addshroom(y,x);
X    }
X    mvaddstr(0,60,"La:");
X    showla();
X    mvprintw(1,60,"Board: %d",board);
X    mvprintw(2,60,"Score: %d",score);
X    mvaddstr(20,60,"Next free man:");
X    mvprintw(21,67,"%s",addcommas(nextman));
X    displaymen();
X    if (strcmp(name,getlogin()))
X	mvaddstr(3,60,name);
X    waitboard();
X    extramen--;
X    displaymen();
X}
X
Xmake_cent(num_free)
Xint num_free;
X{
X    register int i;
X    int vel = 2 * rnd(2) - 1;
X    register PEDE **piece = &centipede, *prev = NULL;
X
X    for (i = 0; i < CENTLENGTH; i++)
X    {
X	*piece = (PEDE *)malloc(sizeof(PEDE));
X	(*piece)->prev = prev;
X	(*piece)->pos.y = 0;
X	(*piece)->speed.y = 1;
X	(*piece)->overlap = 0;
X	(*piece)->poisoned = 0;
X	(*piece)->speed.x = (i < CENTLENGTH - num_free) ? vel : 2 * rnd(2) - 1;
X	(*piece)->type = (i == 0 || i >= CENTLENGTH - num_free) ? HEAD : BODY;
X	prev = *piece;
X	piece = &(*piece)->next;
X    }
X    lastpede = prev;
X    *piece = NULL;
X}
X
Xput_pede()
X{
X    register PEDE *piece = centipede;
X    register int x;
X
X    finished = breeding = scorpthisboard = 0;
X    numpedes = CENTLENGTH;
X    mvaddch(guy.y,guy.x,YOU);
X    piece->pos.x = 22 + rnd(12);
X    ADDPIECE(piece);
X    while ((piece = piece->next) != NULL)
X    {
X	if (piece->type == BODY)
X	    piece->pos.x = piece->prev->pos.x - piece->prev->speed.x;
X	else
X	{
X	    while (mvinch(0,x = rnd(55) + 1) == HEAD || inch() == BODY);
X	    piece->pos.x = x;
X	}
X	ADDPIECE(piece);
X    }
X}
X
Xdeath()
X{
X    static char *ouch[] = {
X	"\\|/",
X	"-*-",
X	"/|\\"};
X
X    mvaddch(guy.y,guy.x,'*');
X    refresh();
X    mvaddstr(guy.y,guy.x - 1,"-*-");
X    refresh();
X    printpic(ouch,3,guy.y - 1,guy.x - 1);
X    refresh();
X    countmushrooms();
X    if (!extramen--)
X	endgame();
X    waitboard();
X    contdeath();
X}
X
Xcontdeath()
X{
X    register PEDE *piece;
X    register int y,x;
X
X    if (fleahere)       /* erase flea */
X    {
X	ERASE(flea.y,flea.x);
X	fleahere = 0;
X    }
X    if (fired)          /* erase shot */
X    {
X	ERASE(shot.y,shot.x);
X	fired = 0;
X    }
X    if (scorphere)      /* erase scorpion */
X    {
X	erasepic(1,7,scorp.y,scorp.x);
X	scorphere = 0;
X    }
X    spidcount = 0;
X    if (spiderhere)     /* erase spider */
X    {
X	erasepic(2,6,spider.y,spider.x);
X	spiderhere = 0;
X    }
X    for (piece = centipede; piece != NULL; piece = piece->next)
X    {
X	ERASE(piece->pos.y,piece->pos.x);
X	free(piece);
X    }
X    for (y = guy.y - 1; y <= guy.y + 1; y++)
X	for (x = guy.x - 1; x <= guy.x + 1; x++)
X	    ERASE(y,x);
X    guy.y = 22;
X    guy.x = 28;
X    displaymen();
X    dead = 0;
X}
X
Xcountmushrooms()
X{
X    register int y,x,y2,x2,flag,i,j;
X    char cu,cd,cl,cr,cm;        /* Characters on screen being overwritten */
X
X    for (x = 1; x <= 55; x++)
X	for (y = 22; y >= 0; y--)
X	    if (mushw[y][x] != ' ' && mushw[y][x] != UNSHOTMUSHROOM)
X	    {
X		flag = mushw[y][x] != (cm = mvinch(y,x));
X		mushw[y][x] = UNSHOTMUSHROOM;
X		if (y > 0)
X		{
X		    cu = mvinch(y - 1,x);
X		    mvaddch(y - 1,x,'|');
X		}
X		cd = mvinch(y + 1,x);
X		mvaddch(y + 1,x,'|');
X		cl = mvinch(y,x - 1);
X		mvaddch(y,x - 1,'-');
X		cr = mvinch(y,x + 1);
X		mvaddch(y,x + 1,'-');
X		refresh();
X		if (y > 0)
X		    mvaddch(y - 1,x,cu);
X		mvaddch(y + 1,x,cd);
X		mvaddch(y,x - 1,cl);
X		mvaddch(y,x + 1,cr);
X		mvaddch(y,x,((flag) ? cm : UNSHOTMUSHROOM));
X		addscore(5);
X		refresh();
X	    }
X}
END_OF_cent.c
if test 5410 -ne `wc -c <cent.c`; then
    echo shar: \"cent.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f cent.doc -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"cent.doc\"
else
echo shar: Extracting \"cent.doc\" \(4679 characters\)
sed "s/^X//" >cent.doc <<'END_OF_cent.doc'
X
X
X			 Welcome to Centipede!
X
X    The object of this game is to survive as long as you can and get as many
Xpoints as possible. You are situated in a strange garden, and there are
Xdifferent forms of life there. The main part of the game is the centipede,
Xwhich starts up on the top of the screen, and moves across, coming down when it
Xhits something. There are many mushrooms scattered about, blocking your way.
XYou can shoot these 3 times to destroy them. There are other creatures such
Xas fleas, scorpions, and spiders. You have to hit fleas twice to destroy them.
X    You get 1 shot. You can fire again as soon as hits something, or after it
Xgoes off the top of the screen. You are represented on the screen by an
Xexclamation point (!), and your shot by an asterisk (*). Anything that moves
Xon the screen can kill you, so be careful. You start off with 3 men (lives),
Xand get a free man for every 12,000 points that you score. You can move within
Xthe region on the bottom of the screen below the horizontal dashes.
X    If you just want to see the high score list, start the game with the -s
Xflag, i.e. cent -s. You can save your game at any time by pausing with the
X<tab> key, and then typing s. To restore a saved game, start the game with the
Xsavefile as an argument, i.e. cent savefile. Warning: do not do anything to a
Xsaved game file, or you will not be able to restore the game. When the game
Xis paused, you can save your game as described earlier, or redraw the
Xscreen by typing ^L.
X    Other details of the game you will find out by playing.
X
X	Controls: (default)
X	<space>                 fire                           On an H19,
X	   1                    move left                 the movement commands
X	   3                    move right                can be made using the
X	   .                    move down                 lower 12 keys of the
X	   5                    move up                   numeric keypad.
X	   4                    move up and left
X	   6                    move up and right
X	   0                    move down and left
X	<enter>                 move down and right
X	   7                    move 8 spaces to the left
X	   9                    move 8 spaces to the right
X	 <tab>                  make the game pause
X	   ^L                   redraw the screen (only while paused)
X	   s                    save the game (only while paused)
X	   ^C                   quit
X	   ^Z                   stop the game temporarily
X	   ^\                   emergency quit (if all else fails)
X
X	To satisfy your own idea of what the controls for this game should be,
X	you can define your own characters to represent the movement commands
X	by using the environment variable CENTOPTS. This variable should contain
X	a string of the form "opt1,opt2,...,optn", where each opti is a string
X	of the form "cmdname=char", where cmdname is the name of the command
X	whose character you are defining, and char is the character you want to
X	associate the named command with. E.g., my CENTOPTS variable might
X	contain "fi=2", to set the character representing the command to fire to
X	'2', and to actually set the variable, I would type
X		% setenv CENTOPTS "fi=2"
X	The names of the characters and the commands they represent are:
X	   up = up        ri = right     dl = downleft   fl = fastleft
X	   do = down      ul = upleft    dr = downright  fr = fastright
X	   le = left      ur = upright   fi = fire       pa = pause
X	It is advisable not to define the same character to be associated
X	with two different commands, for obvious reasons.
X	(Note: you cannot specify space, tab or newline as the character
X	for a command (though carriage return is ok). As mentioned already,
X	space and tab are the default characters for fire and pause, but
X	they cannot be used for any other commands.)
X
X	Scoring:
X	   O                    centipede head          100
X	   o                    centipede body          10
X	   P p . X x ,          mushroom                1
X	   @                    flea                    200
X	`oo'--/                 scorpion                1,000
X
X	 /\  /\                                        /300
X	 /\oo/\                 spider                < 600
X						       \900
X    
X
X	Load average checking is done by the game automatically.
X	Whenever the (five minute) load average rises above the
X	maximum allowed (4.0), you will be informed. At this point
X	you have 2 minutes to quit/save your game before it is
X	forceably ended. If the load drops, you are permitted to
X	continue.
X
X
X			Good luck!
X
XPlease mail any bugs, comments, or suggestions to Nathan Glasser
X(nathan@mit-eddie.uucp or nathan@xx.lcs.mit.edu)
X								
XCentipede is a trademark of Atari Corporation.
END_OF_cent.doc
if test 4679 -ne `wc -c <cent.doc`; then
    echo shar: \"cent.doc\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f cent.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"cent.h\"
else
echo shar: Extracting \"cent.h\" \(2109 characters\)
sed "s/^X//" >cent.h <<'END_OF_cent.h'
X#include <curses.h>
X#include <signal.h>
X#include <pwd.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X       /* stdio.h and sgtty.h are included by curses.h */
X
X#define FREEMAN 12000
X#define CENTLENGTH 20
X
X/* Things appearing on the screen */
X#define HEAD 'O'
X#define BODY 'o'
X#define UNSHOTMUSHROOM 'P'
X#define ONCESHOTMUSHROOM 'p'
X#define TWICESHOTMUSHROOM '.'
X#define UNSHOTPOISON 'X'
X#define ONCESHOTPOISON 'x'
X#define TWICESHOTPOISON ','
X#define YOU '!'
X#define SHOT '*'
X#define FLEA '@'
X
X#define UNPOISONED 0
X#define POISONED 1
X#define WASPOISONED 2
X
X
Xtypedef struct {
X    int y;
X    int x;
X    } COORD;
X
Xtypedef struct pede {
X    struct pede *next;  /* next pede in linked list of creatures */
X    struct pede *prev;  /* previous pede in list */
X    char type;          /* head or body */
X    COORD pos;
X    COORD oldpos;
X    COORD speed;
X    int overlap;        /* Did the piece overlap another last time? */
X    int poisoned;       /* state of being poisoned */
X    } PEDE;
X
Xextern PEDE *centipede, *lastpede;
Xextern char mushw[24][57];
Xextern int inter,stopped,dead,fired,finished,board,fleahere,
X	fleashot,extramen,breeding,breedtime,moves,nummushrooms,
X	scorphere,scorpthisboard,scorpvel,gameover,spiderhere,spiderdir,
X	spidcount,gameover,author,gamestarted,numpedes,fleafreq,niceness;
X#ifdef WIZARD
Xextern int author;
X#endif
Xextern long score,nextman;
Xextern COORD guy,shot,flea,scorp,spider,spidervel;
Xextern char name[],rscorpion[],lscorpion[],*scorppic,*spiderpic[];
Xextern char in_map[];
X#ifdef old_input
Xextern char fichar,upchar,dochar,lechar,richar,ulchar,urchar,dlchar,drchar,
X	flchar,frchar,pachar;
X#endif
Xextern char scorefile[],lockfile[],helpfile[];
Xextern struct sgttyb origterm;
Xextern float version;
Xextern double maxload;
X
Xextern PEDE *getpede();
Xextern char *addcommas(),*getlogin(),*getenv(),*index();
Xextern int catchint(),catchstop(),stopawhile(),quit(),catchalarm();
Xextern FILE *popen();
X
X#define COMPSPOTS(s1,s2) ((s1).y == (s2).y && (s1).x == (s2).x)
X#define ADDPIECE(piece) mvaddch((piece)->pos.y,(piece)->pos.x,(piece)->type)
X#define ERASE(y,x) mvaddch(y,x,mushw[y][x])
END_OF_cent.h
if test 2109 -ne `wc -c <cent.h`; then
    echo shar: \"cent.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f extern.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"extern.c\"
else
echo shar: Extracting \"extern.c\" \(1912 characters\)
sed "s/^X//" >extern.c <<'END_OF_extern.c'
X#include "cent.h"
X
Xfloat version = 1.7;
XPEDE *centipede;                /* head of the list */
XPEDE *lastpede;                 /* last pede in list */
Xint numpedes;
Xchar mushw[24][57];             /* Array to store mushrooms */
Xstruct sgttyb origterm;         /* the terminal before */
Xint inter = 0;
Xint stopped = 0;
Xchar name[10];
X#ifdef WIZARD
Xint author;
X#endif
Xint gamestarted = 0;
Xint gameover = 0;
Xint dead = 0;
XCOORD guy = {22,28};            /* your coordinates */
XCOORD shot;                     /* the shot's coordinates */
Xint fired = 0;                  /* a shot has been fired */
Xlong score = 0;
Xint board = 1;
Xint extramen = 3;
Xlong nextman = FREEMAN;
Xint finished;                   /* time since board ended */
Xint breeding;                   /* are they breeding */
Xint breedtime = 300;            /* moves between breeds */
Xint moves = 0;
Xint fleahere = 0;               /* a flea is on the screen */
XCOORD flea;
Xint fleashot;                   /* was it shot once */
Xint fleafreq;                   /* a figure which helps determine the
X				   frequency of fleas on a board */
Xint nummushrooms;               /* number of mushrooms in player area */
Xchar lscorpion[] = "\`oo'--/";
Xchar rscorpion[] = "\\--\`oo'";
Xchar *scorppic;
Xint scorphere = 0;              /* is there a scorpion on the screen */
Xint scorpthisboard;
Xint scorpvel;
XCOORD scorp;
Xchar *spiderpic[] = {
X    "/\\  /\\",
X    "/\\oo/\\"};
Xint spiderhere = 0;
XCOORD spider;
XCOORD spidervel;
Xint spiderdir;
Xint spidcount;
Xchar in_map[128];
X#ifdef old_input
Xchar fichar = FIRE,             /* Characters used for movement */
X     upchar = UPWARD,           /* commands by the user (settable) */
X     dochar = DOWN,
X     lechar = LEFT,
X     richar = RIGHT,
X     ulchar = UPLEFT,
X     urchar = UPRIGHT,
X     dlchar = DOWNLEFT,
X     drchar = DOWNRIGHT,
X     flchar = FASTLEFT,
X     frchar = FASTRIGHT,
X     pachar = PAUSEKEY;
X#endif
END_OF_extern.c
if test 1912 -ne `wc -c <extern.c`; then
    echo shar: \"extern.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f input.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"input.c\"
else
echo shar: Extracting \"input.c\" \(1772 characters\)
sed "s/^X//" >input.c <<'END_OF_input.c'
X#include "cent.h"
X#include "sys_dep.h"
X
Xmove_guy()
X{
X    register int y, x, changed = 0;
X    int count,repeat = 0;
X    char ch;
X
X    ioctl(0,FIONREAD,&count);
X    while (repeat || count--)
X    {
X	if (repeat)
X	    repeat--;
X	else
X	    ch = in_map[getchar()];
X	if (dead)
X	   continue;
X	y = guy.y;
X	x = guy.x;
X	switch(ch)
X	{
X	    case LEFT:
X	        x--;
X		break;
X	    case RIGHT:
X		x++;
X		break;
X	    case UPWARD:
X		y--;
X		break;
X	    case DOWN:
X		y++;
X		break;
X	    case UPRIGHT:
X		x++;
X		y--;
X		break;
X	    case UPLEFT:
X		x--;
X		y--;
X		break;
X	    case DOWNRIGHT:
X		x++;
X		y++;
X		break;
X	    case DOWNLEFT:
X		x--;
X		y++;
X		break;
X	    case FIRE:
X		if (!fired)
X		{
X		    fired = 1;
X		    shot.y = guy.y - 1;
X		    shot.x = guy.x;
X		    checkhit();
X		    changed = 1;
X		    if (fired)
X			mvaddch(shot.y,shot.x,SHOT);
X		}
X		continue;
X	    case PAUSEKEY:
X		waitboard();
X		continue;
X	    case FASTLEFT:
X		repeat = 8;
X		ch = LEFT;
X		continue;
X	    case FASTRIGHT:
X		repeat = 8;
X		ch = RIGHT;
X		continue;
X	    default:
X		continue;
X	}
X
X	if (ch == UPRIGHT || ch == UPLEFT || ch == DOWNRIGHT || ch == DOWNLEFT)
X	{
X	    if (y < 18)
X		y = 18;
X	    else if (y > 22)
X		y = 22;
X	    if (x < 1)
X		x = 1;
X	    else if (x > 55)
X		x = 55;
X	    if (y == guy.y && x == guy.x)
X		continue;
X	}
X	if (x >= 1 && x <= 55 && y >= 18 && y <= 22)
X	{
X	    if (getpede(y,x) != NULL || fleahere && y == flea.y && x == flea.x
X	      || spiderhere && (y == spider.y || y == spider.y + 1)
X	      && spider.x <= x && x <= spider.x + 5)
X	    {
X		dead = 1;
X		mvaddch(y,x,YOU);
X		ERASE(guy.y,guy.x);
X		guy.y = y;
X		guy.x = x;
X		changed = 1;
X	    }
X	    else if (mvinch(y,x) == ' ')
X	    {
X		addch(YOU);
X		ERASE(guy.y,guy.x);
X		guy.y = y;
X		guy.x = x;
X		changed = 1;
X	    }
X	}
X    }
X    if (changed)
X	refresh();
X}
END_OF_input.c
if test 1772 -ne `wc -c <input.c`; then
    echo shar: \"input.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f install.doc -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"install.doc\"
else
echo shar: Extracting \"install.doc\" \(1320 characters\)
sed "s/^X//" >install.doc <<'END_OF_install.doc'
XYou should have the files:
Xinstall.doc - This file
Xcent.doc - A file describing how to play.
Xsys_dep.c - A C file with system dependent constants.
Xsys_dep.h - A C header file with definitions of default movement commands
Xmakefile - The makefile for compilation
X
XOther source files:
Xcent.h cent.c extern.c input.c interrupts.c la.c move.c options.c 
Xsave.c score.c shoot.c stuff.c
X
X
XYou should look at sys_dep.{c,h} and modify the constants there to suit
Xyour system. Then just run make to compile the program.
X
XNote: the score file should be protected 666, and it is assumed that
Xthe file exists when the program is run. Hence you should create an empty
Xfile under the name given in sys_dep.c initially.
X
XOne way to insure that there will be no tampering with the score file
Xis to make a directory which is protected 711, giving only execute access.
XWithin this directory make another subdirectory with protection 777, and in
Xhere put the score file, and define (in sys_dep.c) the lockfile to be a file
Xin here. The lockfile is assumed not to exist at the beginning. The purpose
Xof the lockfile is to ensure exclusive access to the scorefile. (E.g.,
X/usr/games/lib/cdir is protected 711, and contains other subdirectories,
Xone containing a score file, one for the lockfiles. This directory could
Xalso contain cent.doc.)
END_OF_install.doc
if test 1320 -ne `wc -c <install.doc`; then
    echo shar: \"install.doc\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f interrupts.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"interrupts.c\"
else
echo shar: Extracting \"interrupts.c\" \(2044 characters\)
sed "s/^X//" >interrupts.c <<'END_OF_interrupts.c'
X#include "cent.h"
X
Xendgame()
X{
X    signal(SIGINT,SIG_IGN);
X    mvaddstr(22,60,"[Press return");
X    mvaddstr(23,60," to continue]");
X    refresh();
X    nocrmode();
X    nl();
X    while (getchar() != '\n');
X    echo();
X    endwin();
X    printf("\n\n");
X    doscores();
X    exit(0);
X}
X
Xcatchint()
X{
X    signal(SIGINT,SIG_IGN);
X    signal(SIGTSTP,SIG_IGN);
X    inter = 1;
X}
X
Xcatchstop()
X{
X    signal(SIGTSTP,SIG_IGN);
X    signal(SIGINT,SIG_IGN);
X    stopped = 1;
X}
X
Xstopawhile()
X{
X    struct sgttyb curseterm;
X
X    move(23,0);
X    refresh();
X    putchar('\n');
X    fflush(stdout);
X    ioctl(0,TIOCGETP,&curseterm);
X    ioctl(0,TIOCSETP,&origterm);
X    signal(SIGTSTP,SIG_DFL);
X    kill(getpid(),SIGTSTP);
X    signal(SIGTSTP,SIG_IGN);
X    stopped = 0;
X    ioctl(0,TIOCSETP,&curseterm);
X    redrawscr();
X    ioctl(0,TIOCSETP,&curseterm);       /* Just to make sure... */
X    waitboard();
X    signal(SIGTSTP,catchstop);
X    signal(SIGINT,catchint);
X}
X
Xquit()
X{
X    char ch;
X
X    signal(SIGQUIT,SIG_IGN);
X    mvaddstr(12,60,"Really quit?");
X    refresh();
X    ch = getchar();
X    move(12,60);
X    clrtoeol();
X    refresh();
X    if (ch == 'y' || ch == 'Y')
X	endgame();
X    inter = 0;
X    signal(SIGINT,catchint);
X    signal(SIGTSTP,catchstop);
X    signal(SIGQUIT,quit);
X}
X
Xwaitboard()
X{
X    char ch;
X
X    signal(SIGTSTP,SIG_IGN);
X    signal(SIGINT,SIG_IGN);
X    mvaddstr(12,60,"Press return");
X    mvaddstr(13,60,"when ready");
X    refresh();
X    while ((ch = getchar()) != '\r')
X    {
X#ifdef WIZARD
X	if (ch == '\020')
X	    setname();
X	else if (ch == '\014')
X#else
X	 if (ch == '\014')
X#endif
X	    redrawscr();
X	else if (ch == 's' || ch == 'S')
X	    savegame();
X    }
X    move(12,60);
X    clrtoeol();
X    move(13,60);
X    clrtoeol();
X    move(15,60);
X    clrtoeol();
X    signal(SIGINT,catchint);
X    signal(SIGTSTP,catchstop);
X}
X
Xcatchalarm()
X{
X   gameover = 1;
X}
X
Xladie()
X{
X    mvaddstr(10,60,"Your game is over");
X    mvaddstr(11,60,"due to the load av.");
X    endgame();
X}
X
Xredrawscr()
X{
X    curscr->_clear = 1;
X    touchwin(stdscr);
X    refresh();
X}
END_OF_interrupts.c
if test 2044 -ne `wc -c <interrupts.c`; then
    echo shar: \"interrupts.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f la.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"la.c\"
else
echo shar: Extracting \"la.c\" \(695 characters\)
sed "s/^X//" >la.c <<'END_OF_la.c'
X#include <nlist.h>
X
Xloadav(avenrun)         /* Function storing 1,5,15 minute load averages in */
Xdouble *avenrun;        /* avenrun; should be declared double avenrun[3];  */
X{                       /* Returns -1 if error, 0 otherwise.               */
X    static struct nlist nl[] = {
X	{"_avenrun"},
X	{0},
X    };
X    static kmem = -17;
X
X    if (kmem < 0)          /* Open necessary files. */
X    {
X	if ((kmem = open("/dev/kmem",0)) == -1)
X	    return(-1);                         /* Cannot open. */
X	nlist("/vmunix", nl);
X    }
X    if (lseek(kmem,(long)nl[0].n_value, 0) == -1 || 
X      read(kmem,avenrun,3 * sizeof(double)) == -1)
X	return(-1);    /* sizeof avenrun is 24. */
X    return(0);
X}
END_OF_la.c
if test 695 -ne `wc -c <la.c`; then
    echo shar: \"la.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f move.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"move.c\"
else
echo shar: Extracting \"move.c\" \(8454 characters\)
sed "s/^X//" >move.c <<'END_OF_move.c'
X#include "cent.h"
X
Xmovestuff()
X{
X    register int y,x;
X    int count;
X
X    while (!dead && finished < 40)
X    {
X	if (spidcount % 20 == 0)
X	    showla();
X	if (inter)
X	    quit();
X	if (stopped)
X	    stopawhile();
X	if (gameover)
X	    ladie();
X	if (finished)
X	{
X	    putnull(24);
X	    finished++;
X	}
X	else
X	{
X	    if (numpedes < 6 && !spiderhere)
X		putnull(4 * (6 - numpedes));
X	    movepedes();
X	    if (breeding)
X		dobreed();
X	}
X	if (fleahere)
X	    moveflea();
X	if (board >= 2 && !fleahere && !scorphere &&
X	  (rnd(3400) < (board - 1) * fleafreq ||
X	  nummushrooms < 5 && rnd(600) < (board - 1) * fleafreq))
X	    startflea();
X	if (scorphere)
X	    movescorp();
X	if (board >= 3 && !scorphere && !fleahere &&
X	  (!scorpthisboard  && rnd(2000) < board - 1 ||
X	  scorpthisboard && rnd(4000) < board - 1))
X	    startscorp();
X	if (spiderhere)
X	    movespider();
X	spidcount++;
X	if (!spiderhere && spidcount % 90 == 0 && rnd (7) < 6)
X	    startspider();
X	if (fired)
X	    dofire();
X	getyx(stdscr,y,x);                      /* make sure he's not */
X	if (mvinch(guy.y,guy.x) != YOU)         /* invisible, but don't */
X	    addch(YOU);                         /* waste cursor movement */
X	move(y,x);
X	refresh();
X	fflush(stdout);
X	do
X	    ioctl(1,TIOCOUTQ,&count);
X	while (count > spiderhere * 40);
X	move_guy();
X    }
X}
X
Xmovepedes()
X{
X    register PEDE *piece;
X    register int x;
X    register char thing;
X
X    for (piece = lastpede; piece != NULL; piece = piece->prev)
X    {                                     /* move the 'pedes (rev order) */
X	piece->oldpos.x = piece->pos.x;
X	piece->oldpos.y = piece->pos.y;
X	if (piece->type == BODY && (piece == lastpede ||
X	  piece->next->type == HEAD) && piece->pos.y == 22 &&
X	  piece->prev->pos.y == 21 && piece->poisoned == UNPOISONED)
X	{
X	    piece->type = HEAD;
X	    piece->speed.x = -piece->speed.x;
X	    if (1 <= piece->pos.x + piece->speed.x &&
X	      piece->pos.x + piece->speed.x <= 55)
X	    {
X		piece->pos.x += piece->speed.x;
X		if (COMPSPOTS(piece->pos,guy))
X		    dead = 1;
X	    }
X	}
X	if (piece->type == BODY)
X	{
X	    piece->pos.x = piece->prev->pos.x;
X	    piece->pos.y = piece->prev->pos.y;
X	    piece->speed.x = piece->prev->speed.x;
X	    piece->speed.y = piece->prev->speed.y;
X	    if (piece->poisoned == WASPOISONED &&
X	      piece->prev->poisoned == UNPOISONED)
X		piece->poisoned = UNPOISONED;
X	}
X	else
X	{
X	    x = piece->pos.x + piece->speed.x;
X	    if (x < 1 || x > 55 || (thing = mvinch(piece->pos.y,x)) != ' ' &&
X	      thing != YOU && thing != SHOT || piece->overlap ||
X	      piece->poisoned != UNPOISONED)
X	    {
X		if (1 <= x && x <= 55 && (thing == UNSHOTPOISON ||
X		  thing == ONCESHOTPOISON || thing == TWICESHOTPOISON))
X		    poison(piece);
X		piece->speed.x = -piece->speed.x;
X		if (piece->pos.y == 22 || piece->pos.y == 18
X		  && piece->speed.y == -1)
X		    piece->speed.y = -piece->speed.y;
X		piece->pos.y += piece->speed.y;
X		piece->overlap = 0;
X		if (piece->poisoned == WASPOISONED)
X		    piece->poisoned = UNPOISONED;
X	    }
X	    else
X		piece->pos.x = x;
X	    if (piece->pos.y == 22 && piece->poisoned == UNPOISONED
X	      && !breeding)
X	    {
X		breeding = 1;
X		if (breedtime > 25)
X		    breedtime--;
X	    }
X	}
X	if (COMPSPOTS(piece->pos,guy))
X	    dead = 1;
X	if (piece->poisoned == POISONED && piece->oldpos.y == 22)
X	    piece->poisoned = UNPOISONED;
X    }
X    for (piece = centipede; piece != NULL; piece = piece->next)
X	ERASE(piece->oldpos.y,piece->oldpos.x);
X    for (piece = centipede; piece != NULL; piece = piece->next)
X    {
X	if (mvinch(piece->pos.y,piece->pos.x) == HEAD && piece->type == HEAD)
X	    piece->overlap = 1;
X	if ((thing = mushw[piece->pos.y][piece->pos.x]) == UNSHOTPOISON
X	  || thing == ONCESHOTPOISON || thing == TWICESHOTPOISON)
X	    poison(piece);
X	ADDPIECE(piece);
X    }
X}
X
Xdobreed()                      /* bring on the reinforcements! */
X{
X    if (++moves >= breedtime && rnd(10) < 9)
X    {
X	if (breedtime > 125)
X	    breedtime -= 10;
X	else if (breedtime > 55)
X	    breedtime -= 5;
X	if (breedtime > 25)
X	    breedtime--;
X	moves = 0;
X	lastpede->next = (PEDE *)malloc(sizeof(PEDE));
X	lastpede->next->prev = lastpede;
X	lastpede = lastpede->next;
X	lastpede->next = NULL;
X	lastpede->overlap = 0;
X	lastpede->poisoned = UNPOISONED;
X	lastpede->type = HEAD;
X	lastpede->pos.y = 18;
X	lastpede->speed.y = 1;
X	if (rnd(2) == 0)
X	{
X	    lastpede->pos.x = 1;
X	    lastpede->speed.x = 1;
X	}
X	else
X	{
X	    lastpede->pos.x = 55;
X	    lastpede->speed.x = -1;
X	}
X	ADDPIECE(lastpede);
X	numpedes++;
X	if (COMPSPOTS(lastpede->pos,guy))
X	    dead = 1;
X    }
X}
X
Xstartflea()
X{
X    fleahere = 1;
X    fleashot = 0;
X    flea.y = 0;
X    flea.x = rnd(55) + 1;
X    mvaddch(flea.y,flea.x,FLEA);
X}
X
Xmoveflea()                      /* move a flea */
X{
X    ERASE(flea.y,flea.x);
X    if (flea.y == 22)
X	fleahere = 0;
X    else
X    {
X	if (mushw[flea.y][flea.x] == ' ' && rnd(5) < 2)
X	    addshroom(flea.y,flea.x);
X	flea.y++;
X	mvaddch(flea.y,flea.x,FLEA);
X	if (COMPSPOTS(flea,guy))
X	    dead = 1;
X
X    }
X}
X
Xstartscorp()        /* start a scorpion */
X{
X    if ((scorpvel = rnd(6) - 2) < 1)
X	scorpvel--;
X    scorppic = (scorpvel > 0) ? rscorpion : lscorpion;
X    scorp.x = (scorpvel > 0) ? -5 : 55;
X    scorp.y = rnd(12) + 2;
X    scorpthisboard = 1;
X    scorphere = 1;
X    drawpic(&scorppic,1,7,scorp.y,scorp.x);
X}
X
Xmovescorp()                     /* move a scorpion */
X{
X    register int dir,i;
X
X    if (scorpvel > 0)
X    {
X	dir = 1;
X	i = scorpvel;
X    }
X    else
X    {
X	dir = -1;
X	i = -scorpvel;
X    }
X    erasepic(1,7,scorp.y,scorp.x);
X    while (i-- && scorphere)
X    {
X	if (1 <= scorp.x && scorp.x <= 55)
X	    switch (mushw[scorp.y][scorp.x])        /* poison a mushroom */
X	    {
X		case UNSHOTMUSHROOM:
X		    mvaddch(scorp.y,scorp.x,UNSHOTPOISON);
X		    mushw[scorp.y][scorp.x] = UNSHOTPOISON;
X		    break;
X		case ONCESHOTMUSHROOM:
X		    mvaddch(scorp.y,scorp.x,ONCESHOTPOISON);
X		    mushw[scorp.y][scorp.x] = ONCESHOTPOISON;
X		    break;
X		case TWICESHOTMUSHROOM:
X		    mvaddch(scorp.y,scorp.x,TWICESHOTPOISON);
X		    mushw[scorp.y][scorp.x] = TWICESHOTPOISON;
X		    break;
X	    }
X	scorp.x += dir;
X	if (scorp.x < -5 || scorp.x > 55)
X	    scorphere = 0;
X    }
X    if (scorphere)
X	drawpic(&scorppic,1,7,scorp.y,scorp.x);
X}
X
Xpoison(piece)
XPEDE *piece;
X{
X    do
X	piece->poisoned = POISONED;
X    while ((piece = piece->next) != NULL && piece->type != HEAD);
X}
X
Xputnull(n)
Xint n;
X{
X    while (n--)
X	putchar(0);
X}
X
Xstartspider()
X{
X    spiderhere = 1;
X    spiderdir = 2 * rnd(2) - 1;
X    spider.y = 14;
X    spidervel.y = 1;
X    if (spiderdir > 0)
X    {
X	spider.x = -4;
X	spidervel.x = 1;
X    }
X    else
X    {
X	spider.x = 55;
X	spidervel.x = -1;
X    }
X    drawpic(spiderpic,2,6,spider.y,spider.x);
X}
X
Xmovespider()
X{
X    register int y,x,count = 0,dx,dy;
X
X    erasepic(2,6,spider.y,spider.x);
X    while (count++ < 10)
X    {
X	y = spider.y + spidervel.y;
X	x = spider.x + spidervel.x;
X	if (!spidcango(y,x))
X	{
X	    spidervel.y = -spidervel.y;
X	    if (rnd(4) < 1)
X		spidervel.x = spiderdir - spidervel.x;
X	    continue;
X	}
X	else
X	{
X	    dy = spider.y + 1 - guy.y;
X	    dx = spider.x - guy.x;
X	    if (dx / spiderdir < 0 && dy && 0 <= (dx + dy) * spiderdir &&
X		(dx + dy) * spiderdir <= 5 && rnd(3) < 2)
X	    {
X		spidervel.x = spiderdir;
X		spidervel.y = (dy < 0) ? 1 : -1;
X		continue;
X	    }
X	    if (dx / spiderdir < 0 && rnd(6) < 1)
X	    {
X		spidervel.x = spiderdir;
X		continue;
X	    }
X	    else if (spidervel.x && rnd(8) < 1 || !spidervel.x && rnd(12) < 1)
X	    {
X		spidervel.x = spiderdir - spidervel.x;
X		continue;
X	    }
X	    else if (rnd(12) < 1)
X	    {
X		spidervel.y = -spidervel.y;
X		continue;
X	    }
X	}
X	break;
X    }
X    if (count != 11)
X    {
X	spider.y = y;
X	spider.x = x;
X    }
X    else
X    {
X	if (spidcango(spider.y,spider.x + spiderdir) && rnd(12) < 11)
X	    spider.x += spiderdir;
X	x = spider.x;
X	y = spider.y;
X    }
X    if (x < -4 || x > 55)
X	spiderhere = spidcount = 0;
X    else
X    {
X	int xx;
X     
X	for (xx = x + 2; xx <= x + 3; xx++)
X	    if (1 <= xx && xx <= 55)
X		if (mushw[y + 1][xx] != ' ')
X		{
X		    mushw[y + 1][xx] = ' ';
X		    if (y >= 17)
X			nummushrooms--;
X		 }
X	drawpic(spiderpic,2,6,spider.y,spider.x);
X	if ((guy.y == spider.y || guy.y == spider.y + 1) &&
X	  spider.x <= guy.x && guy.x <= spider.x + 5)
X	    dead = 1;
X    }
X}
X
Xspidcango(y,x)
Xint y,x;
X{
X    int yy,xx;
X
X    if (y == 13 || y ==22)
X	return(0);
X    for (yy = y; yy < y + 2; yy++)
X	for (xx = x; xx < x + 6; xx++)
X	    if (1 <= xx && xx <= 55 && (mvinch(yy,xx) == HEAD ||
X	      inch() == BODY))
X		return(0);
X    return(1);
X}
END_OF_move.c
if test 8454 -ne `wc -c <move.c`; then
    echo shar: \"move.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f options.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"options.c\"
else
echo shar: Extracting \"options.c\" \(1210 characters\)
sed "s/^X//" >options.c <<'END_OF_options.c'
X#include "cent.h"
X#include "sys_dep.h"
X
X#define INITOPT(x) in_map[x] = x
X#define SETOPT(optstring,var) else if (!strcmp(s1,optstring)) in_map[*s3] = var
X
X/* Initialize movement characters, possibly from options variable */
Xdooptions()
X{
X    char *optline,*tmp;
X    char s1[100], s2[100], s3[100];
X
X    INITOPT(LEFT);
X    INITOPT(RIGHT);
X    INITOPT(UPWARD);
X    INITOPT(DOWN);
X    INITOPT(FIRE);
X    INITOPT(UPRIGHT);
X    INITOPT(UPLEFT);
X    INITOPT(DOWNRIGHT);
X    INITOPT(DOWNLEFT);
X    INITOPT(FASTLEFT);
X    INITOPT(FASTRIGHT);
X    INITOPT(PAUSEKEY);
X
X    if ((optline = getenv("CENTOPTS")) == NULL)
X	return;
X    while (1)
X    {
X	sscanf(optline," %[^ =] %[=] %[^ ,]",s1,s2,s3);
X	if (strcmp(s2,"=") || strlen(s3) != 1)
X	    badopts();
X	if (0)
X	    ;
X	SETOPT("fi",FIRE);
X	SETOPT("up",UPWARD);
X	SETOPT("do",DOWN);
X	SETOPT("le",LEFT);
X	SETOPT("ri",RIGHT);
X	SETOPT("ul",UPLEFT);
X	SETOPT("ur",UPRIGHT);
X	SETOPT("dl",DOWNLEFT);
X	SETOPT("dr",DOWNRIGHT);
X	SETOPT("fl",FASTLEFT);
X	SETOPT("fr",FASTRIGHT);
X	SETOPT("pa",PAUSEKEY);
X	else
X	    badopts();
X	if ((tmp = index(optline,',')) == NULL)
X	    break;
X	optline = tmp + 1;
X    }
X}
X
Xbadopts()
X{
X    printf("Bad options specification in CENTOPTS\n");
X    exit(1);
X}
END_OF_options.c
if test 1210 -ne `wc -c <options.c`; then
    echo shar: \"options.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f rand.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"rand.c\"
else
echo shar: Extracting \"rand.c\" \(695 characters\)
sed "s/^X//" >rand.c <<'END_OF_rand.c'
X/*  Selected parts from Wagar's rand.c
X    Copyright (c) 1982 Steven L. Wagar.  All rights reserved. */
X#include <stdio.h>
X#include <ctype.h>
X#include <math.h>
X#include <sys/types.h>
X#include <sys/timeb.h>
X
Xdouble  RandSeed,floor(),pow();
X
Xdouble frac(d)          /* returns the fractional part of a double */
Xdouble d;
X{
X        return (d-floor(d));
X}
X
Xrninit()                /* seed is of form .mmmsss (m = millisecs, s = secs) */
X{
X        struct timeb tbuf;
X
X        ftime(&tbuf);
X        RandSeed = tbuf.millitm/1000.0 + frac(tbuf.time/1000.0) / 1000.0;
X}
X
Xdouble rn()             /* remainder of hairy exponential */
X{
X        return (RandSeed = frac(pow(RandSeed*4.32 + 3.52, 3.64)));
X}
END_OF_rand.c
if test 695 -ne `wc -c <rand.c`; then
    echo shar: \"rand.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f save.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"save.c\"
else
echo shar: Extracting \"save.c\" \(4101 characters\)
sed "s/^X//" >save.c <<'END_OF_save.c'
X#include "cent.h"
X
X#define MAGICNUM 15
X#define GOOD 1
X#define BAD 0
X
Xextern struct passwd *getpwnam();
X
Xsavegame()
X{
X    char fil[100];
X
X    if (!gamestarted)
X    {
X	mvaddstr(15,60,"Too early to save");
X	refresh();
X	return;
X    }
X    printf("%s",CL);
X    nocrmode();
X    echo();
X    nl();
X    printf("File name: ");
X    scanf("%s",fil);
X    noecho();
X    crmode();
X    printf("Saving... ");
X    fflush(stdout);
X    if (dosave(fil) == GOOD)
X    {
X	printf("Done.\n");
X	endwin();
X	exit(0);
X    }
X    nonl();
X    printf("[Press return to continue game]");
X    getchar();
X    while (getchar() != '\r');
X    redrawscr();
X}
X
Xdosave(fil)
Xchar *fil;
X{
X    long tim;
X    int fd,y,x;
X    char ch;
X    PEDE *piece;
X    
X    if ((fd = creat(fil,0600)) == -1)
X    {
X	perror("Error opening file");
X	return(BAD);
X    }
X    ch = MAGICNUM;
X    write(fd,&ch,1);
X    write(fd,&version,sizeof(float));
X    for (y = 0; y < 24; y++)
X	write(fd,(stdscr->_y)[y],80);
X    write(fd,mushw,24 * 57);
X
X#define wint(i) write(fd,&i,sizeof(int))
X#define wlong(i) write(fd,&i,sizeof(long))
X
X    wint(numpedes);
X    wint(fired);
X    wlong(score);
X    wint(board);
X    wint(extramen);
X    wlong(nextman);
X    wint(dead);
X    wint(finished);
X    wint(breeding);
X    wint(breedtime);
X    wint(moves);
X    wint(fleahere);
X    wint(fleashot);
X    wint(nummushrooms);
X    wint(scorphere);
X    wint(scorpthisboard);
X    wint(scorpvel);
X    wint(spiderhere);
X    wint(spiderdir);
X    wint(spidcount);
X
X#define wc(cd) write(fd,&cd,sizeof(COORD))
X
X    wc(guy);
X    wc(shot);
X    wc(flea);
X    wc(scorp);
X    wc(spider);
X    wc(spidervel);
X    write(fd,name,10);
X    for (piece = centipede; piece != NULL; piece = piece->next)
X	write(fd,piece,sizeof(PEDE));
X    tim = time(0);
X    wlong(tim);
X    close(fd);
X    chmod(fil,0);
X    return(GOOD);
X}
X
X#define BADF(m) {perror(m); chmod(fil,sbuf.st_mode & 07777); exit(0);}
X
Xdorest(fil)
X{
X    int fd,n,count,tim;
X    register char ch;
X    register int y,x;
X    char buf[512];
X    PEDE **piece = &centipede, *prev = NULL;
X    struct stat sbuf;
X    float vers;
X
X    printf("Reading file... ");
X    fflush(stdout);
X    stat(fil,&sbuf);
X    chmod(fil,0400);
X    if ((fd = open(fil,0)) == -1)
X	BADF("Error opening file");
X    if (getpwnam(getlogin())->pw_uid != sbuf.st_uid)
X	BADF("That's not your game!\n");
X    if (sbuf.st_nlink > 1)
X	BADF("Cannot restore from linked file.\n");
X    lseek(fd,-4,2);
X
X#define rint(i) read(fd,&i,sizeof(int));
X#define rlong(i) read(fd,&i,sizeof(long));
X
X    rlong(tim);
X    lseek(fd,0,0);
X    read(fd,&ch,1);
X    if (sbuf.st_mtime > tim + 2 || sbuf.st_ctime > tim + 2 ||
X      ch != MAGICNUM)
X	BADF("Sorry, but the file has been touched.\n");
X    read(fd,&vers,sizeof(float));
X    if (version != vers)
X	BADF("Saved game is for the wrong version.\n");
X    for (y = 0; y < 24; y++)
X	read(fd,(stdscr->_y)[y],80);
X    read(fd,mushw,24 * 57);
X
X#define rint(i) read(fd,&i,sizeof(int));
X#define rlong(i) read(fd,&i,sizeof(long));
X
X    rint(numpedes);
X    rint(fired);
X    rlong(score);
X    rint(board);
X    rint(extramen);
X    rlong(nextman);
X    rint(dead);
X    rint(finished);
X    rint(breeding);
X    rint(breedtime);
X    rint(moves);
X    rint(fleahere);
X    rint(fleashot);
X    rint(nummushrooms);
X    rint(scorphere);
X    rint(scorpthisboard);
X    rint(scorpvel);
X    rint(spiderhere);
X    rint(spiderdir);
X    rint(spidcount);
X
X#define rc(cd) read(fd,&cd,sizeof(COORD))
X
X    rc(guy);
X    rc(shot);
X    rc(flea);
X    rc(scorp);
X    rc(spider);
X    rc(spidervel);
X    read(fd,name,10);
X    for (n = 0; n < numpedes; n++)
X    {
X	*piece = (PEDE *)malloc(sizeof(PEDE));
X	read(fd,*piece,sizeof(PEDE));
X	(*piece)->prev = prev;
X	prev = *piece;
X	piece = &(*piece)->next;
X    }
X    lastpede = prev;
X    *piece = NULL;
X    close(fd);
X    unlink(fil);
X    printf("Done\n");
X    if (scorphere)
X	scorppic = (scorpvel > 0) ? rscorpion : lscorpion;
X    move(10,60);
X    clrtoeol();
X    move(11,60);
X    clrtoeol();
X    move(13,70);        /* Put the cursor in the right spot */
X    redrawscr();        /* Redraw screen (necessary because of the way
X			   the screen was put back together) */
X}
END_OF_save.c
if test 4101 -ne `wc -c <save.c`; then
    echo shar: \"save.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f score.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"score.c\"
else
echo shar: Extracting \"score.c\" \(2999 characters\)
sed "s/^X//" >score.c <<'END_OF_score.c'
X#include "cent.h"
X
Xstruct score {
X    char name[10];
X    long score;
X    int board;
X    };
X
Xerr()
X{
X    perror("bad score file");
X    exit(-1);
X}
X
Xdoscores()
X{
X    register int fd,wr,numscores,i,putin = 0,rank = 0;
X    struct stat buf;
X    struct score *scores, myscore;
X    FILE *morefp;
X
X    if (stat(scorefile,&buf) == -1)
X	err();
X    lockscore();
X    if (buf.st_size % sizeof(struct score) != 0)
X    {
X	printf("Bad score file format\n");
X	exit(-1);
X    }
X    numscores = buf.st_size / sizeof(struct score);
X    scores = (struct score *)malloc(buf.st_size);
X    strcpy(myscore.name,name);
X    myscore.score = score;
X    myscore.board = board;
X    if ((fd = open(scorefile,0)) == -1)
X	err();
X    if (read(fd,scores,buf.st_size) == -1)
X	err();
X    close(fd);
X    if (wr = needtowrite(scores,numscores,&myscore))
X	if ((fd = creat(scorefile,0600)) == -1)
X	    err();
X    if ((morefp = popen("/usr/ucb/more","w")) == NULL)
X    {
X	perror("Error popen'ing more");
X	exit(1);
X    }
X    printf("Centipede Hall of Fame\n");
X    signal(SIGPIPE,SIG_IGN);
X    fprintf(morefp,"Rank Score      Board Name\n");
X    for (i = 0; i < numscores; i++)
X    {
X	if (!putin && score > scores[i].score)
X	{
X	    putin = 1;
X	    prscore(&myscore,++rank,wr,fd,morefp);
X	}
X	if (!putin || strcmp(scores[i].name,myscore.name))
X	{
X	    prscore(&scores[i],++rank,wr,fd,morefp);
X	    if (!strcmp(scores[i].name,myscore.name))
X		putin = 1;
X	}
X    }
X    if (!putin)
X	prscore(&myscore,++rank,wr,fd,morefp);
X    close(fd);
X    pclose(morefp);
X    signal(SIGPIPE,SIG_DFL);
X    unlockscore();
X}
X
Xprscore(sc,rank,wr,fd,morefp)
Xstruct score *sc;
Xint rank,wr,fd;
XFILE *morefp;
X{
X    if (wr)
X	write(fd,sc,sizeof(struct score));
X    fprintf(morefp,"%-4d %-10s %-5d %-s\n",rank,addcommas(sc->score),sc->board,
X      sc->name);
X}
X
Xneedtowrite(sc,num,myscore)
Xstruct score *sc, *myscore;
Xint num;
X{
X    for (; num--; sc++)
X	if (!strcmp(sc->name,myscore->name))
X	    return(score > sc->score);
X    return(1);
X}
X
Xshowscores()
X{
X    struct score sc;
X    register int fd,rank = 0;
X    FILE *morefp;
X
X    lockscore();
X    if ((fd = open(scorefile,0)) == -1)
X	err();
X    if ((morefp = popen("/usr/ucb/more","w")) == NULL)
X    {
X	perror("Error popen'ing more");
X	exit(1);
X    }
X    printf("Centipede Hall of Fame\n");
X    fprintf(morefp,"Rank Score      Board Name\n");
X    while (read(fd,&sc,sizeof(struct score)))
X	prscore(&sc,++rank,0,0,morefp);
X    close(fd);
X    pclose(morefp);
X    unlockscore();
X    exit(0);
X}
X
X/* lockscore and unlockscore: routines for controlling access to score file */
Xint lockfd;
X
Xlockscore()
X{
X    struct stat buf;
X
X    while (stat(lockfile,&buf) != -1)
X    {
X	char ch;
X
X	printf("Score file busy. Wait? ");
X	scanf("%c",&ch);
X	if (ch == 'n' || ch == 'N')
X	    exit(-1);
X	sleep(1);
X    }
X    if ((lockfd = creat(lockfile,0444)) == -1)
X    {
X	perror("Error opening lockfile");
X	exit(-1);
X    }
X}
X
Xunlockscore()
X{
X    close(lockfd);
X    if (unlink(lockfile) == -1)
X    {
X	perror("Error removing lockfile");
X	exit(-1);
X    }
X}
END_OF_score.c
if test 2999 -ne `wc -c <score.c`; then
    echo shar: \"score.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f shoot.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"shoot.c\"
else
echo shar: Extracting \"shoot.c\" \(3115 characters\)
sed "s/^X//" >shoot.c <<'END_OF_shoot.c'
X#include "cent.h"
X
Xdofire()                   /* move the guy's shot */
X{
X    register int i;
X    register char thing;
X
X    checkhit();            /* something walked into the shot */
X    if (!fired)
X	return;
X    if (!COMPSPOTS(shot,guy))
X	ERASE(shot.y,shot.x);
X    for (i = 0; i < 4 && fired; i++)
X    {
X	if (!shot.y--)          /* Shot went off the screen */
X	{
X	    fired = 0;
X	    return;
X	}
X	checkhit();
X    }
X    if (fired)
X    {
X       mvaddch(shot.y,shot.x,SHOT);
X       refresh();
X    }
X}
X
Xcheckhit()
X{
X    register char thing;
X
X    if ((thing = mvinch(shot.y,shot.x)) != ' ' && inch() != SHOT
X      && inch() != YOU)
X    {                                             /* he hit something */
X	fired = 0;
X	mvaddch(shot.y,shot.x,SHOT);
X	refresh();
X	switch (thing)
X	{
X	    case UNSHOTMUSHROOM:
X		mvaddch(shot.y,shot.x,ONCESHOTMUSHROOM);
X		mushw[shot.y][shot.x] = ONCESHOTMUSHROOM;
X		break;
X	    case ONCESHOTMUSHROOM:
X		mvaddch(shot.y,shot.x,TWICESHOTMUSHROOM);
X		mushw[shot.y][shot.x] = TWICESHOTMUSHROOM;
X		break;
X	    case TWICESHOTMUSHROOM:
X	    case TWICESHOTPOISON:
X		mvaddch(shot.y,shot.x,' ');
X		mushw[shot.y][shot.x] = ' ';
X		addscore(1);
X		if (shot.y >= 18)
X		    nummushrooms--;
X		break;
X	    case UNSHOTPOISON:
X		mvaddch(shot.y,shot.x,ONCESHOTPOISON);
X		mushw[shot.y][shot.x] = ONCESHOTPOISON;
X		break;
X	    case ONCESHOTPOISON:
X		mvaddch(shot.y,shot.x,TWICESHOTPOISON);
X		mushw[shot.y][shot.x] = TWICESHOTPOISON;
X		break;
X	    default:
X		if (getpede(shot.y,shot.x) != NULL)
X		    shootpede();
X		else if (fleahere && COMPSPOTS(shot,flea))
X		    shootflea();
X		else if (spiderhere &&
X		  (shot.y == spider.y || shot.y == spider.y + 1)
X		  && spider.x <= shot.x && shot.x <= spider.x + 5)
X		    shootspider();
X		else if (scorphere && shot.y == scorp.y &&
X		  scorp.x <= shot.x && shot.x <= scorp.x + 6)
X		{
X		    scorphere = 0;
X		    erasepic(1,7,scorp.y,scorp.x);
X		    addscore(1000);
X		}
X		else
X		{
X		    mvprintw(15,60,"Unknown char: %c",thing);
X		    ERASE(shot.y,shot.x);
X		    refresh();
X		}
X	}
X    }
X}
X
Xshootpede()
X{
X    register PEDE *piece;
X
X    piece = getpede(shot.y,shot.x);
X    if (piece->type == HEAD)
X	addscore(100);
X    else
X	addscore(10);
X    if (piece != centipede)
X	piece->prev->next = piece->next;
X    else if ((centipede = centipede->next) == NULL)
X    {
X	finished = 1;
X	breeding = 0;
X	move(1,67);
X	clrtoeol();
X	printw("%s",addcommas(++board));
X    }
X    if (piece->next != NULL)
X    {
X	PEDE *pp = piece->next;
X
X	pp->type = HEAD;
X	pp->prev = piece->prev;
X	if (piece->poisoned)
X	    do
X		pp->poisoned = WASPOISONED;
X	    while ((pp = pp->next) != NULL && pp->type != HEAD);
X    }
X    else
X	lastpede = piece->prev;
X    addshroom(shot.y,shot.x);
X    free(piece);
X    numpedes--;
X}
X
Xshootflea()
X{
X    if (!fleashot)
X    {
X	fleashot = 1;
X	mvaddch(flea.y,flea.x,FLEA);
X	return;
X    }
X    fleahere = 0;
X    ERASE(flea.y,flea.x);
X    addscore(200);
X    startflea();
X}
X
Xshootspider()
X{
X    spiderhere = 0;
X    erasepic(2,6,spider.y,spider.x);
X    spidcount = 0;
X    if (guy.y - spider.y == 2)
X	addscore(900);
X    else if (guy.y - spider.y < 4)
X	addscore(600);
X    else
X	addscore(300);
X}
END_OF_shoot.c
if test 3115 -ne `wc -c <shoot.c`; then
    echo shar: \"shoot.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f stuff.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"stuff.c\"
else
echo shar: Extracting \"stuff.c\" \(3901 characters\)
sed "s/^X//" >stuff.c <<'END_OF_stuff.c'
X#include "cent.h"
X
Xrnd(n)
Xregister int n;
X{
X    double rn();
X    register int i;
X
X    i = n * rn();
X    return(i);
X}
X
Xprintpic(pic,len,y,x)
Xchar **pic;
Xint len, y, x;
X{
X    register int i;
X    for (i = 0; i < len; i++)
X	mvaddstr(i + y,x,pic[i]);
X}
X
XPEDE *getpede(y,x)
X{
X    register PEDE *pede;
X
X    for (pede = centipede; pede != NULL; pede = pede->next)
X	if (pede->pos.y == y && pede->pos.x == x)
X	    return(pede);
X    return(NULL);
X}
X
Xaddscore(n)
X{
X    score += n;
X    mvprintw(2,67,"%s",addcommas(score));
X    if (score >= nextman)
X    {
X	mvprintw(21,67,"%s",addcommas(nextman += FREEMAN));
X	extramen++;
X	displaymen();
X	mvaddstr(12,66,"You've won");
X	mvaddstr(13,65,"a free man!!");
X	refresh();
X	sleep(2);
X	move(12,66);
X	clrtoeol();
X	move(13,65);
X	clrtoeol();
X    }
X}
X
Xdisplaymen()
X{
X    static char men[15];
X    register int i;
X
X    for (i = 0; i < 6 && i < extramen; i++)
X	men[i] = YOU;
X    if (extramen > 6)
X	sprintf(men + 6," (%s)",addcommas(extramen));
X    else
X	men[i] = 0;
X    move(23,60);
X    clrtoeol();
X    addstr(men);
X}
X
Xchar *addcommas(num)
Xint num;
X{
X    static char str[14];
X    register char *spot = str;
X    register int p10;
X
X    for (p10 = 1000; num / p10 > 0; p10 *= 1000);
X    p10 /= 1000;
X    sprintf(spot,"%d",num / p10);
X    while (p10 > 1)
X    {
X	num -= (num / p10) * p10;
X	p10 /= 1000;
X	spot += strlen(spot);
X	*spot++ = ',';
X	sprintf(spot,"%03d",num / p10);
X    }
X    return(str);
X}
X
Xdrawpic(pic,len,wid,y,x)
Xchar **pic;
Xint len,wid,y,x;
X{
X   register int yy,xx,start,end,pos;
X	   
X   start = (x < 1) ? 1 - x : 0;
X   end = (x > 56 - wid) ? 56 - x : wid;
X   for (yy = 0; yy < len; yy++)
X       for (pos = start, xx = (x < 1) ? 1 : x; pos < end; pos ++, xx++)
X	   if (pic[yy][pos] != ' ')
X	       mvaddch(y + yy,xx,pic[yy][pos]);
X}
X
Xerasepic(len,wid,y,x)
Xint len,wid,y,x;
X{
X    register int xx,yy,twid,newx;
X     
X    twid = ((x > 56 - wid) ? 56 - x : wid) - ((x < 1) ? 1 - x : 0);
X    newx = (x < 1) ? 1 : x;
X    for (yy = 0; yy < len; yy++)
X	for (xx = newx; xx < newx + twid; xx++)
X	    ERASE(y + yy,xx);
X}
X
Xshowla()
X{
X    register double la[3];
X    static int ol = -1,exceeded = 0;
X    register int l;
X
X    loadav(la);
X    l = la[1] * 100;
X    if (l != ol)
X    {
X	ol = l;
X	mvprintw(0,67,"%.2f",l / 100.0);
X    }
X#ifdef WIZARD
X    if (l > 100 * maxload && !author)
X#else
X    if (l > 100 * maxload)
X#endif
X    {
X	if (!exceeded)
X	{
X	    mvaddstr(10,60,"Load av exceeded.");
X	    mvaddstr(11,60,"You have 2 minutes.");
X	    exceeded = 1;
X	    alarm(120);
X	}
X    }
X    else if (exceeded)
X    {
X	alarm(0);
X	mvaddstr(10,60,"The load av dropped.");
X	mvaddstr(11,60,"You have a repreive.");
X	exceeded = 0;
X    }
X}
X
Xtoohigh()
X{
X    double la[3];
X
X    loadav(la);
X#ifdef WIZARD
X    return(la[1] > maxload && !author);
X#else
X    return(la[1] > maxload);
X#endif
X}
X
Xaddshroom(y,x)
Xint y,x;
X{
X    if (y == 22)
X    {
X	mvaddstr(15,60,"Mushroom on last row");
X	return;
X    }
X    mvaddch(y,x,UNSHOTMUSHROOM);
X    mushw[y][x] = UNSHOTMUSHROOM;
X    if (y >= 18)
X	nummushrooms++;
X}
X
X#ifdef WIZARD
Xsetname()
X{
X    int i = 0;
X    char ch;
X
X    if (!author)
X	return;
X    mvaddstr(15,60,"New name(8 chars):");
X    move(16,60);
X    refresh();
X    while ((ch = getch()) != '\n' && i < 9)
X    {
X	if (ch == '\010' || ch == '\177')
X	{
X	    if (i > 0)
X	    {
X		i--;
X		printw("\010 \010");
X	    }
X	}
X	else
X	    addch(name[i++] = ch);
X	refresh();
X    }
X    name[(i < 8) ? i : 8] = 0;
X    move(16,60);
X    clrtoeol();
X    move(15,60);
X    clrtoeol();
X    addstr("Ok");
X    move(3,60);
X    clrtoeol();
X    addstr(name);
X    refresh();
X}
X#endif
X
Xinstructions()
X{
X    char ch, cmd[90];
X
X    printf("Welcome to Centipede version %.1f!\n",version);
X    printf("Would you like instructions(y/n)?");
X    crmode();
X    if ((ch = getchar()) != 'y' && ch != 'Y')
X	return;
X    sprintf(cmd,"/usr/ucb/more %s",helpfile);
X    system(cmd);
X    printf("[Hit return to start the game]");
X    while (getchar() != '\n');
X}
END_OF_stuff.c
if test 3901 -ne `wc -c <stuff.c`; then
    echo shar: \"stuff.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f sys_dep.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"sys_dep.c\"
else
echo shar: Extracting \"sys_dep.c\" \(567 characters\)
sed "s/^X//" >sys_dep.c <<'END_OF_sys_dep.c'
X/* Sys_dep.c:  System dependent constants */
X
X
X
X/* Scorefile: Where the scorefile should live */
Xchar scorefile[] = "/usr/games/centipede/scores";
X
X
X/* Lockfile: Where to create and look for a lockfile controlling access
X   to the scorefile */
Xchar lockfile[] = "/usr/games/centipede/lockfile";
X
X
X/* Helpfile: Where the help file is located */
Xchar helpfile[] = "/usr/games/centipede/cent.doc";
X
X
X/* Maxload: The maximum allowed load average for playing */
Xdouble maxload = 4.0;
X
X
X/* Niceness: The amount to nice the game by (lower its priority) */
Xint niceness = 4;
END_OF_sys_dep.c
if test 567 -ne `wc -c <sys_dep.c`; then
    echo shar: \"sys_dep.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f sys_dep.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"sys_dep.h\"
else
echo shar: Extracting \"sys_dep.h\" \(256 characters\)
sed "s/^X//" >sys_dep.h <<'END_OF_sys_dep.h'
X/* User commands */
X#define LEFT '1'
X#define RIGHT '3'
X#define UPWARD '5'
X#define DOWN '.'
X#define FIRE ' '
X#define UPRIGHT '6'
X#define UPLEFT '4'
X#define DOWNRIGHT '\r'
X#define DOWNLEFT '0'
X#define FASTLEFT '7'
X#define FASTRIGHT '9'
X#define PAUSEKEY '\t'
END_OF_sys_dep.h
if test 256 -ne `wc -c <sys_dep.h`; then
    echo shar: \"sys_dep.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0