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 = ¢ipede, *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 = ¢ipede, *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