games-request@tekred.UUCP (07/09/87)
Submitted by: Julian Onions <jpo@cs.nott.ac.uk> Comp.sources.games: Volume 1, Issue 80 Archive-name: robots2 [Compiled and ran OK on our 4.3bsdBeta Vax. -br] [[An upgraded version of the robots game. Should work on sys5 as well as 4.2/3 although not test rigorously. The README/manual page describes most of the interesting stuff. I can be reached as either jpo@cs.nott.ac.uk jpo%cs.nott.ac.uk@ucl-cs.arpa ...!seismo!mcvax!ukc!nott-cs!jpo - least preferable. Julian]] ----------------------- #! /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: READ_ME Makefile good.c main.c makelog opt.c robot.c # robots.6 robots.h score.c user.c # Wrapped by billr@tekred on Wed Jul 8 14:40:28 1987 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f READ_ME -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"READ_ME\" else echo shar: Extracting \"READ_ME\" \(1371 characters\) sed "s/^X//" >READ_ME <<'END_OF_READ_ME' XRobots - version 2 X XThis version has several features over the original version but is Xstill very much in the same spirit. Amongst the new features are X X- Fast robots, these are robots that move at twice the speed of X normal robots. X- Option settings in the style of rogue. X- movable scrap heaps. X- random & safe teleports with the ability to choose. X- antimatter X XTo build. XIt should build on most sane systems, XYou may want to play with some of the variables in Makefile, there Xare a couple of version specific things to look for. XIf you are on a BSD4.2 or better system add -DBSD42 to the CFLAGS Xin the Makefile. XSystem 5 may need to remove -ltermcap from the LIBS line in Makefile. XAlso if BSD42 is not defined, the score directory needs to be Xwritable to lock the files. XYou may want to play with the location of the high score files which Xare #defined near the begining of robots.h. X XType make, make install, and enjoy. X XBugs, comments, flames, offers of cash, aston martins to those below X Julian Onions <jpo@cs.nott.ac.uk> X Graeme Lunt <gal@cs.nott.ac.uk> X Allan Black <allan@cs.strath.ac.uk> X XStop Press: X Also available from jpo@cs.nott.ac.uk, a version of robomatic X which does a reasonable job of playing the game of robots. X Current high scores are - X X 1 482538104 Graeme (gal): eaten on level 85. X 6 8476863 Robomatic II (jpo): eaten on level 23. END_OF_READ_ME if test 1371 -ne `wc -c <READ_ME`; then echo shar: \"READ_ME\" 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\" \(979 characters\) sed "s/^X//" >Makefile <<'END_OF_Makefile' X# just -lcurses for SYS V XLIBS = -lcurses -ltermcap X# add -DBSD42 for performance wins on 4.2 or better XIFDEF = -DBSD42 XCFLAGS = $(IFDEF) #-g XLINT = lint XLLFLAGS = -haxbc XSHAR = shar XSHFLGS = -v -c XHEADERS = robots.h XSRC = good.c main.c opt.c robot.c score.c user.c XOBJS = good.o main.o opt.o robot.o score.o user.o XMAN = robots.6 XMISC = READ_ME Makefile XDIST = $(MISC) $(SRC) $(MAN) $(HEADERS) XMANUAL = /usr/man/man6/robots.6 # where the manual page goes XBINARY = /usr/sheriff/jpo/games # Where the binary goes X Xrobots: ${OBJS} X $(CC) $(CFLAGS) -o $@ ${OBJS} $(LIBS) X Xinstall: robots robots.6 X install -s robots $(BINARY) # or strip robots && mv robots $(BINARY) X# install -c robots.6 $(MANUAL) # or cp robots.6 $(MANUAL) X Xtidy: clean Xclean: X rm -f ${OBJS} core a.out lint.out shar.out X Xclobber: clean X rm -f robots X Xlint: ${SRC} $(HEADERS) X $(LINT) $(LLFLAGS) $(IFDEF) ${SRC} $(LIBS) X Xshar: shar.out Xshar.out: $(DIST) X $(SHAR) $(SHFLGS) $(DIST) > $@ X X${OBJS}: ${HEADERS} END_OF_Makefile if test 979 -ne `wc -c <Makefile`; then echo shar: \"Makefile\" unpacked with wrong size! fi # end of overwriting check fi if test -f good.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"good.c\" else echo shar: Extracting \"good.c\" \(2907 characters\) sed "s/^X//" >good.c <<'END_OF_good.c' X# include "robots.h" X X/* X * good.c: Figure out all possible good moves. X * This piece of code use to be trivial - then fast robots came X * and moveable heaps and its now an AI expert system in its own right! X */ X Xgood_moves () X{ X register int test_x, test_y; X register char *m, *a; X static char moves[] = "hjklyubn.a"; X static char ans[sizeof (moves)]; X char savebuf[9], savechar; X int i,j, notsilly; X X a = ans; X for(m = moves; *m != 'a'; m++) { X test_x = my_x+xinc(*m); X test_y = my_y+yinc(*m); X move(test_y,test_x); X switch(inch()) { X case ' ': X case DOT: X case ME: X if( isgood(test_y, test_x) ) X *a++ = *m; X break; X case SCRAP: X if (moveable_heaps) { X int nscrap_x,nscrap_y; X nscrap_x = test_x +xinc(*m); X nscrap_y = test_y +yinc(*m); X move(nscrap_y,nscrap_x); X if (inch() == ' ') { X addch(SCRAP); X if (isgood(test_y,test_x)) X *a++ = *m; X move(nscrap_y,nscrap_x); X addch(' '); X } X } X break; X } X } X /* now lets do the antimatter case */ X if (free_teleports) { X notsilly = 0; /* silly to do it if not get robots */ X for(i= -1;i <= 1; i++) X for(j= -1; j<= 1; j++) { X move(my_y+i,my_x+j); X savechar = inch(); X if (savechar == FROBOT || savechar == ROBOT) { X savebuf[ (i+1)*3 +j +1] = savechar; X addch(' '); X notsilly = 1; X } X else X savebuf[ (i+1)*3 +j +1] = ' '; X } X if( notsilly && isgood(my_y,my_x) ) X *a++ = *m; X X for(i= -1;i <= 1; i++) X for(j= -1; j<= 1; j++) { X move(my_y+i,my_x+j); X savechar = savebuf[ (i+1)*3 +j +1]; X if (savechar == FROBOT || savechar == ROBOT) X addch(savechar); X } X } X *a = 0; X if(ans[0]) { X a = ans; X } else { X a = "Forget it!"; X } X mvprintw(LINES-1,MSGPOS,"%-*.*s",RVPOS-MSGPOS,RVPOS-MSGPOS,a); X} X Xisgood(ty,tx) Xregister int tx, ty; X{ X register int x, y; X X for(x = -2; x <= 2; x++) { X for(y = -2; y <= 2; y++) { X if ( abs(x) > 1 || abs(y) > 1 ) { /* we are 2 steps out */ X if( blocked(ty, tx, y, x)) X continue; X move(ty+y,tx+x); X if ( abs(x) == 2 && abs(y) == 2 X && inch() == FROBOT){ X return FALSE; } X if ( x == -1 && scan(ty+y, tx+x, 0, 1) ) X return FALSE; X if ( y == -1 && scan(ty+y, tx+x, 1, 0) ) X return FALSE; X } /* outer perimeter checked */ X else { X move(ty+y,tx+x); X switch(inch()) { X case FROBOT: X case ROBOT: /* robot next to you */ X return FALSE; X } X } X } X } X return TRUE; X} X Xscan(y, x, yi, xi) /* scan along this line looking for collision conditions */ Xint x, y, xi, yi; X{ X int rcount = 0; X register int ctr; X X for(ctr = 0;ctr<=2;ctr++) { X move(y + (ctr*yi), x + (ctr*xi)); X switch(inch()) { X case FROBOT: X rcount += 4; X break; X case ROBOT: X rcount ++; X break; X } X } X return rcount == 4; X} X Xblocked(my, mx, y, x) Xregister int my, mx, y, x; X{ X if ( x < 0 ) x++; X if ( y < 0 ) y++; X if ( x > 0 ) x--; X if ( y > 0 ) y--; X move(my+y, mx+x); X return inch() == SCRAP; X} END_OF_good.c if test 2907 -ne `wc -c <good.c`; then echo shar: \"good.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f main.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"main.c\" else echo shar: Extracting \"main.c\" \(6448 characters\) sed "s/^X//" >main.c <<'END_OF_main.c' X/* X * R O B O T S X * X * The game of robots. X * History: X * Original Implementation X * Allan Black <allan@cs.strath.ac.uk> X * Updated for fast robots, moveable heaps, ROBOTOPTS X * antimatter, v7/sys5/4.2 portability etc. X * Graeme Lunt <gal@cs.nott.ac.uk> X * Julian Onions <jpo@cs.nott.ac.uk> X * X * Provided free as long as you don't make money from it! X */ X X# include "robots.h" X Xchar whoami[MAXSTR]; Xchar my_user_name[MAXSTR]; Xchar cmd_ch; X Xbool dead = FALSE; Xbool last_stand; Xbool show_highscore = TRUE; Xbool running, adjacent, first_move, bad_move, waiting; Xbool moveable_heaps = TRUE; X Xint my_x, my_y; Xint new_x, new_y; Xint level = 0; Xint free_teleports = 0; Xint old_free; Xint free_per_level = 1; Xint count; Xint dots = 0; Xint robot_value = MIN_VALUE; Xint max_robots = MIN_ROBOTS; Xint nrobots_alive; Xint scrap_heaps = 1; /* to allow for first level */ X Xlong score = 0; Xlong seed; X X# ifdef TIOCSLTC Xstruct ltchars ltc; Xchar dsusp; X# endif TIOCSLTC X Xint interrupt(); X X# define TERM_UNINIT 00 X# define TERM_CURSES 01 X# define TERM_LTC 02 X Xint term_state = TERM_UNINIT; /* cuts out some race conditions */ Xchar *getenv(); Xstruct passwd *getpwuid(); Xchar _obuf[BUFSIZ]; X Xmain(argc,argv) X int argc; X char *argv[]; X{ X register struct passwd *pass; X register char *x; X int i; X X setbuf(stdout, _obuf); X if(argc > 1) { X if(argv[1][0] == '-') { X switch(argv[1][1]) { X case 's': X show_highscore = TRUE; X scoring(FALSE); X exit(0); X } X } X } X if((pass = getpwuid(getuid())) == 0) { X x = "ANON"; X } else { X x = pass->pw_name; X } X (void) strcpy(my_user_name, x); X (void) strcpy(whoami,x); X if((x = getenv(ROBOTOPTS)) != NULL && *x != '\0') X get_robot_opts(x); X seed = time((time_t *)0)+getuid(); X (void) signal(SIGQUIT,interrupt); X (void) signal(SIGINT,interrupt); X if( initscr() == ERR) { X fprintf(stderr, "Curses won't initialise - seek a guru\n"); X quit(FALSE); X } X term_state |= TERM_CURSES; X crmode(); X noecho(); X# ifdef TIOCSLTC X (void) ioctl(1,TIOCGLTC,<c); X dsusp = ltc.t_dsuspc; X ltc.t_dsuspc = ltc.t_suspc; X (void) ioctl(1,TIOCSLTC,<c); X term_state |= TERM_LTC; X# endif TIOCSLTC X for(;;) { X count = 0; X running = FALSE; X adjacent = FALSE; X waiting = FALSE; X last_stand = FALSE; X old_free = -1; X if(rnd(free_per_level) < free_teleports) { X free_per_level++; X if(free_per_level > MAX_FREE) free_per_level = MAX_FREE; X } X free_teleports += free_per_level; X leaveok(stdscr,FALSE); X draw_screen(); X put_robots(); X do { X my_x = rndx(); X my_y = rndy(); X move(my_y,my_x); X } while(inch() != ' '); X addch(ME); X for(;;) { X scorer(); X if(nrobots_alive == 0) break; X command(); X for(i=1;i<=FASTEST;i++) X robots(i); X if(dead) munch(); X } X msg("%d robots are now %d scrap heaps",max_robots, scrap_heaps); X leaveok(stdscr,FALSE); X move(my_y,my_x); X refresh(); X (void) readchar(); X level++; X } X} X Xdraw_screen() X{ X register int x, y; X clear(); X for(y = 1; y < LINES-2; y++) { X mvaddch(y,0,VERT); X mvaddch(y,COLS-1,VERT); X } X for(x = 0; x < COLS; x++) { X mvaddch(0,x,HORIZ); X mvaddch(LINES-2,x,HORIZ); X } X} X Xreadchar() X{ X static char buf[1]; X extern int errno; X X while(read(0,buf,1) != 1) X if( errno != EINTR) X quit(TRUE); X return(buf[0]); X} X Xput_dots() X{ X register int x, y; X for(x = my_x-dots; x <= my_x+dots; x++) { X for(y = my_y-dots; y <= my_y+dots; y++) { X move(y,x); X if(inch() == ' ') addch(DOT); X } X } X} X Xerase_dots() X{ X register int x, y; X for(x = my_x-dots; x <= my_x+dots; x++) { X for(y = my_y-dots; y <= my_y+dots; y++) { X move(y,x); X if(inch() == DOT) addch(' '); X } X } X} X Xxinc(dir) X char dir; X{ X switch(dir) { X case 'h': X case 'y': X case 'b': X return(-1); X case 'l': X case 'u': X case 'n': X return(1); X case 'j': X case 'k': X default: X return(0); X } X} X Xyinc(dir) X char dir; X{ X switch(dir) { X case 'k': X case 'y': X case 'u': X return(-1); X case 'j': X case 'b': X case 'n': X return(1); X case 'h': X case 'l': X default: X return(0); X } X} X Xmunch() X{ X scorer(); X msg("MUNCH! You're robot food"); X leaveok(stdscr,FALSE); X mvaddch(my_y,my_x,MUNCH); X move(my_y,my_x); X refresh(); X (void) readchar(); X quit(TRUE); X} X Xquit(eaten) X bool eaten; X{ X if( term_state & TERM_CURSES ) { X move(LINES-1,0); X refresh(); X endwin(); X term_state &= ~ TERM_CURSES; X } X putchar('\n'); X# ifdef TIOCSLTC X if( term_state & TERM_LTC ) { X ltc.t_dsuspc = dsusp; X (void) ioctl(1,TIOCSLTC,<c); X term_state &= ~ TERM_LTC; X } X# endif TIOCSLTC X (void) signal(SIGINT, SIG_DFL); X scoring(eaten); X exit(0); X} X Xrndx() X{ X return(rnd(COLS-2)+1); X} X Xrndy() X{ X return(rnd(LINES-3)+1); X} X Xrnd(mod) X int mod; X{ X if(mod <= 0) return(0); X return((((seed = seed*11109L+13849L) >> 16) & 0xffffL) % mod); X} X X/* VARARGS 1 */ Xmsg(message,a1, a2, a3, a4, a5, a6, a7) X char *message; X unsigned int a1, a2, a3, a4, a5, a6, a7; X{ X static char msgbuf[1000]; X X (void) sprintf(msgbuf, message, a1, a2, a3, a4, a5, a6, a7); X mvaddstr(LINES-1,MSGPOS,msgbuf); X clrtoeol(); X refresh(); X} X Xinterrupt() X{ X quit(FALSE); X} X X/* X * file locking routines - much nicer under BSD ... X */ X X# ifdef BSD42 Xlk_open(file, mode) /* lock a file using the flock sys call */ Xchar *file; Xint mode; X{ X int fd; X X if( (fd = open(file, mode)) < 0) X return -1; X if( flock(fd, LOCK_EX) < 0) X { X (void) close(fd); X return -1; X } X return fd; X} X Xlk_close( fd, file) Xint fd; Xchar *file; X{ X# ifdef lint X file = file; /* now will you shut up lint???? */ X# endif X return close(fd); X} X# else X X# define LOCKTIME (60) /* 1 minute */ X# include <sys/stat.h> X Xlk_open(file, mode) /* lock a file by crude means */ Xchar *file; Xint mode; X{ X char tfile[128], lfile[128]; X struct stat stbuf; X time_t now; X int fd; X X (void) sprintf(tfile, "%s.t", file); /* temp file */ X (void) sprintf(lfile, "%s.l", file); /* lock file */ X X if( close(creat(tfile, 0)) < 0) /* make temp file */ X return -1; X while( link(tfile, lfile) == -1) /* now attempt the lock file */ X { X if( stat(lfile, &stbuf) < 0) X continue; /* uhh? -- try again */ X time(&now); X /* OK - is this file old? */ X if( stbuf.st_mtime + LOCKTIME < now) X unlink(lfile); /* ok its old enough - junk it */ X else sleep(1); /* snooze ... */ X } X unlink(tfile); /* tmp files done its job */ X if((fd = open(file, mode)) < 0) { X unlink(lfile); X return -1; X } X return fd; X} X Xlk_close(fd, fname) Xint fd; Xchar *fname; X{ X char lfile[128]; X X (void) sprintf(lfile, "%s.l", fname); /* recreate the lock file name */ X if( unlink(lfile) == -1) /* blow it away */ X perror(lfile); X return close(fd); X} X# endif X END_OF_main.c if test 6448 -ne `wc -c <main.c`; then echo shar: \"main.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f makelog -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"makelog\" else echo shar: Extracting \"makelog\" \(217 characters\) sed "s/^X//" >makelog <<'END_OF_makelog' Xcc -DBSD42 -c good.c Xcc -DBSD42 -c main.c Xcc -DBSD42 -c opt.c Xcc -DBSD42 -c robot.c Xcc -DBSD42 -c score.c Xcc -DBSD42 -c user.c Xcc -DBSD42 -o robots good.o main.o opt.o robot.o score.o user.o -lcurses -ltermcap END_OF_makelog if test 217 -ne `wc -c <makelog`; then echo shar: \"makelog\" unpacked with wrong size! fi # end of overwriting check fi if test -f opt.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"opt.c\" else echo shar: Extracting \"opt.c\" \(1651 characters\) sed "s/^X//" >opt.c <<'END_OF_opt.c' X# include "robots.h" X X/* X * opt.c: do a psuedo ROGUEOPTS sort of thing X */ X Xtypedef struct Opt { X char *name; X int type; X} Opt; X XOpt options[] = { X# define OPT_NAME 1 X "name", OPT_NAME, /* Who am i boss ? */ X# define OPT_MOVE_HEAP 2 X "moveheaps", OPT_MOVE_HEAP, /* can push heaps */ X# define OPT_NOMOVE_HEAP 3 X "nomoveheaps", OPT_NOMOVE_HEAP,/* can't push heaps */ X# define OPT_SHOW_HSCORE 4 X "showhscore", OPT_SHOW_HSCORE, X# define OPT_NOSHOW_HSCORE 5 X "noshowhscore", OPT_NOSHOW_HSCORE, X 0, 0 X}; X X/* get_robot_opts: Personalise robots to the users tastes. Model after X * the rogue/urogue type environment stuff. X */ X Xget_robot_opts(str) Xchar *str; X{ X register char *p; X Opt *op; X int len, len2; X X p = str; X while(*p) X { X while(*p && !isalpha(*p)) p++; /* skip non-alphas */ X str = p; X X while(isalpha(*p)) p ++; /* match longest word */ X len = p - str; X X for(op = options; op->name; op ++) /* see if defined */ X if( strncmp(str, op->name, len) == 0) X break; X if( op->name == NULL) X continue; X switch(op->type) /* OK, now do something */ X { X case OPT_NAME: X while(*p == '=') p++; /* skip ='s */ X str = p; /* OK, now look for name */ X while(*p && *p != ',') p++; X len2 = (MAXSTR - 1) - X (strlen(my_user_name) + 4); X len = p - str; X len = len < len2 ? len : len2; X (void) sprintf(whoami, "%.*s (%s)", len, X str, my_user_name); X break; X case OPT_MOVE_HEAP: X moveable_heaps = TRUE; X break; X case OPT_NOMOVE_HEAP: X moveable_heaps = FALSE; X break; X case OPT_SHOW_HSCORE: X show_highscore = TRUE; X break; X case OPT_NOSHOW_HSCORE: X show_highscore = FALSE; X break; X } X } X} X END_OF_opt.c if test 1651 -ne `wc -c <opt.c`; then echo shar: \"opt.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f robot.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"robot.c\" else echo shar: Extracting \"robot.c\" \(3145 characters\) sed "s/^X//" >robot.c <<'END_OF_robot.c' X# include "robots.h" X X/* X * robot.c: most of the robot oriented stuff X */ X Xstruct robot { X bool alive; /* is this suker still kicking */ X int x; X int y; X int speed; /* speed of robot 1 or 2 for now */ X} rbt_list[MAX_ROBOTS+1]; X Xput_robots() /* place some robots */ X{ X register struct robot *r, *end; X register int x, y; X X robot_value += level*(5 + (max_robots/scrap_heaps)); X max_robots += level*3+rnd(level*5); X if(max_robots > MAX_ROBOTS) max_robots = MAX_ROBOTS; X nrobots_alive = max_robots; X scrap_heaps = 0; /* number of scrap heaps created */ X end = &rbt_list[max_robots]; X for(r = rbt_list; r < end; r++) { X for(;;) { X x = rndx(); X y = rndy(); X move(y,x); X if(inch() == ' ') break; X } X r->x = x; X r->y = y; X r->alive = TRUE; X r->speed = 1 + ( rnd(10) > 6 ); X if (r->speed == 2) addch(FROBOT); X else addch(ROBOT); X } X} X Xrobots(speed) /* Troops, Troooooops advance! */ Xint speed; X{ X register struct robot *r, *end; X X end = &rbt_list[max_robots]; X for(r = rbt_list; r < end; r++) { X if(r->alive && r->speed >= speed ) { X mvaddch(r->y,r->x,' '); X } X } X for(r = rbt_list; r < end; r++) { X if (r->alive && r->speed >= speed ) X { X r->x += sign(my_x-r->x); X r->y += sign(my_y-r->y); X move(r->y,r->x); X switch(inch()) { X case ME: /* robot eat me */ X addch(MUNCH); X dead = TRUE; X break; X case SCRAP: /* robot walks into scrap heap */ X r->alive = FALSE; X if(r->speed == 2) X score += (MULT * robot_value); X else score += robot_value; X nrobots_alive--; X break; X case FROBOT: X case ROBOT: /* two robots form scrap heap */ X collision(r, end); X r->alive = FALSE; X addch(SCRAP); X if (r->speed == 2) X score += (MULT * robot_value); X else score += robot_value; X nrobots_alive -= 2; X scrap_heaps++ ; X break; X case MUNCH: X break; X default: X if(r->speed == 2) addch(FROBOT); X else addch(ROBOT); X } X } X } X} X X/* do two robots collide - if so - which two */ Xcollision(r, end) Xregister struct robot *r, *end; X{ X register struct robot *find; X X for(find = rbt_list; find < end; find++) { X if(find->alive && r != find) { X if(r->x == find->x && r->y == find->y) { X find->alive = FALSE; X if (find->speed == 2) X score += (MULT * robot_value); X else score += robot_value; X return; X } /* end of if */ X } X } X} X Xscrewdriver() /* dismantle those robots ... */ X{ X register int test_x, test_y; X register char *m ; X register struct robot *end,*find; X static char moves[] = "hjklyubn."; X X end = &rbt_list[max_robots]; X X for(m = moves; *m; m++) { /* let's see if there is a robot */ X test_x = my_x+xinc(*m); X test_y = my_y+yinc(*m); X move(test_y,test_x); X switch(inch()) { X case FROBOT: X case ROBOT: /* OK so there is now let's look for it */ X for(find = rbt_list; find < end; find++) { X if(find->alive) { X if(test_x == find->x && test_y == find->y) { X find->alive = FALSE; X if (find->speed == 2) score += (MULT * robot_value); X else score += robot_value; X } /* end of if */ X } /* end of if */ X } /* end of for */ X addch(' '); X nrobots_alive--; X break; X } /* end of case */ X } X free_teleports--; X} END_OF_robot.c if test 3145 -ne `wc -c <robot.c`; then echo shar: \"robot.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f robots.6 -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"robots.6\" else echo shar: Extracting \"robots.6\" \(3170 characters\) sed "s/^X//" >robots.6 <<'END_OF_robots.6' X.TH ROBOTS 6 "2 November 1984" X.SH NAME Xrobots \- a game of logic X.SH SYNOPSIS X.B /usr/games/robots [-s] X.SH DESCRIPTION X.B Robots Xis a display-based game which must be played on a CRT terminal Xfrom among those supported by vi(1). XThe object of the game is to avoid the robots: Xcausing them to collide with each other, creating a X.IR scrap\ heap . XRobots are also destroyed if they run into a X.IR scrap\ heap . X.PP XYou are represented on the screen by an I. XThe robots are represented by `=' and `#' signs. XScrap heaps are represented by `@' signs. XAfter each move, all robots move one step towards you except for Xthe `#' robots which move at twice the speed of normal robots. X.PP XThe following commands are recognized: X.IP h XMove left. X.IP l XMove right. X.IP j XMove down. X.IP k XMove up. X.IP y XMove up and left. X.IP u XMove up and right. X.IP b XMove down and left. X.IP n XMove down and right. X.IP . X.IP w XDo nothing. X.IP t XTeleport to a safe square if possible (limited in number). X.IP r XTeleport to a random position. X.IP a XAntimatter, all robots one square away from you vanish. X.IP s X.IP W XSit and watch. X.IP d XDisplay dots. X.IP m XPrint list of `safe' moves. X.IP ? XSame as above. X.IP q XQuit game. X.IP ^R XRedraw the screen. X.IP ^Z XSuspend the game, on systems which support it. X.IP ^W XSit and watch while safe to do so. X.PP XA command may be preceeded by a count where relevant. X.I Shift\-direction Xmoves as far as possible in that direction. X.I Control\-direction Xmoves until adjacent to something. X.PP XA record is kept of the personal best scores of each player: Xone for the current week and one for all time. XScores are printed out at the end of the game. XThe scores can be printed out with the '\-s' parameter. X.SH CONFIGURATION XIf you have in your environment the variable X.I ROBOTOPTS Xthen this is examined for a comma separated list of options to be set. XBinary options can be preceeded with `no' to reverse the meaning. XValid options are X.IP name=string XSet your name to the given string, this is recorded in the high Xscore table. Your name appears as `string (username)'. X.IP moveheaps XMake the scrap heaps movable. If heaps are movable, then Xa scrap heap can be pushed in any direction provided there is nothing Xbehind the heap. This may or may not be the default. X.IP showhscores XThis option shows the highscore table after every game. The Xnegated version will only print out the highscore only if you appear Xon it. X.SH NOTE XThe first time the `t' command is used on a new level Xyou are guaranteed not to land next to a robot, a count of Xthese `safe' teleports is maintained in the bottom left hand corner. X`Antimatters' use up a `safe' teleport. X.br XAn asterisk in the first set of scores indicates an out-of-date entry. X.br XThe value of each robot in the next round is inversely Xproportional to the Xnumber of scrap heaps created in the previous round. XDouble speed robots count 1.5 times the value of normal robots. X.SH FILES X.nf X/usr/games/lib/robots_tmp this week's best scores X/usr/games/lib/robots_hof all time best scores X.fi X.SH AUTHOR XAllan Black, Strathclyde University, Glasgow. X.br XEnhancements by Graeme Lunt & Julian Onions, Nottingham University. END_OF_robots.6 if test 3170 -ne `wc -c <robots.6`; then echo shar: \"robots.6\" unpacked with wrong size! fi # end of overwriting check fi if test -f robots.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"robots.h\" else echo shar: Extracting \"robots.h\" \(2357 characters\) sed "s/^X//" >robots.h <<'END_OF_robots.h' X/* X * robots.h: include file for the robots game X */ X X# include <curses.h> X# include <signal.h> X# include <pwd.h> X# include <ctype.h> X# include <sys/types.h> X# include <errno.h> X# ifdef BSD42 X# include <sys/file.h> X# endif BSD42 X X# define MIN_ROBOTS 10 /* no. of robots you start with */ X# define MAX_ROBOTS 500 /* maximum robots on a screen */ X# define MIN_VALUE 10 /* what each robot is worth to begin */ X# define MAX_FREE 3 /* max free teleports per level */ X# define FASTEST 2 /* the fastest robot (dont fiddle) */ X X# define VERT '|' /* vertical wall */ X# define HORIZ '-' /* horizontal wall */ X# define ROBOT '=' /* normal robot */ X# define FROBOT '#' /* fast robot */ X# define SCRAP '@' X# define ME 'I' X# define MUNCH '*' X# define DOT '.' X X# define LEVEL (level+1) X X# define MSGPOS 35 /* where messages appear on bottom line */ X# define RVPOS 47 X X/* These you may want to fiddle with. Position of the two high score files */ X# define HOF_FILE "/usr/sheriff/jpo/games/lib/robots_hof" X# define TMP_FILE "/usr/sheriff/jpo/games/lib/robots_tmp" X X# define NUMSCORES 20 /* number of people to record */ X# define NUMNAME "Twenty" /* above spelt out */ X X# define TEMP_DAYS 7 /* how long temp scores last */ X# define TEMP_NAME "Week" X X# define ROBOTOPTS "ROBOTOPTS" /* environment tailoring */ X X# define MAXSTR 100 X X# define MULT 1.5 /* multiplier for fast robots */ X X/* if ALLSCORES Undefined - record top n players */ X# define ALLSCORES /* record top n scores */ X X# define SECSPERDAY 86400 X X# define ctrl(x) ((x)&037) X# define BEL ctrl('G') X X# define abs(X) ((X) < 0 ? -(X) : (X)) X# define sign(X) ((X) < 0 ? -1 : (X) > 0) X Xextern char whoami[]; Xextern char my_user_name[]; Xextern char cmd_ch; X Xextern bool moveable_heaps; Xextern bool show_highscore; Xextern bool last_stand; Xextern bool bad_move; Xextern bool running; Xextern bool waiting; Xextern bool first_move; Xextern bool adjacent; Xextern bool dead; X Xextern int my_x, my_y; Xextern int new_x, new_y; Xextern int count; Xextern int free_teleports; Xextern int dots; Xextern int robot_value; Xextern int level; Xextern int max_robots; Xextern int scrap_heaps; Xextern int nrobots_alive; Xextern int free_per_level; Xextern int old_free; X Xextern long score; Xextern long lseek(); X Xextern char *strcpy (); Xextern char *strncpy (); Xextern char *malloc (); Xextern char *gets (); Xextern char *sprintf (); END_OF_robots.h if test 2357 -ne `wc -c <robots.h`; then echo shar: \"robots.h\" 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\" \(4532 characters\) sed "s/^X//" >score.c <<'END_OF_score.c' X# include "robots.h" X X/* X * score.c: All the scoring code is in here. X */ X Xstruct scorefile { X int s_uid; X long s_score; X char s_name[MAXSTR]; X bool s_eaten; X int s_level; X int s_days; X}; X X# define FILE_SIZE (NUMSCORES*sizeof(struct scorefile)) X Xscoring(eaten) X bool eaten; X{ X static char buf[MAXSTR]; X X (void) sprintf(buf,"for this %s",TEMP_NAME); X if( record_score(eaten,TMP_FILE,TEMP_DAYS,buf) || show_highscore) { X printf("[Press return to continue]"); X fflush(stdout); X gets(buf); X } X record_score(eaten,HOF_FILE,0,"of All Time"); X} X X# define sigbit(x) (1 << ((x) - 1)) X Xrecord_score(eaten,fname,max_days,type_str) X bool eaten; X char *fname; X int max_days; X char *type_str; X{ X int value; X int fd; X int omask; X X /* block signals while recording the score X * hope this routine doesn't get stuck! X */ X# ifndef BSD42 X int (*oint)(), (*oterm)(), (*ohup)(); X X oint = signal(SIGINT, SIG_IGN); X oterm = signal(SIGTERM, SIG_IGN); X ohup = signal(SIGHUP, SIG_IGN); X# else X omask = sigblock( sigbit(SIGINT) | sigbit(SIGTERM) | sigbit(SIGHUP) X | sigbit(SIGTSTP)); X# endif X X if((fd = lk_open(fname,2)) < 0) { X perror(fname); X } else { X value = do_score(eaten,fd,max_days,type_str); X lk_close(fd, fname); X } X# ifdef BSD42 X (void) sigsetmask(omask); X# else X (void) signal(SIGINT, oint); X (void) signal(SIGTERM, oterm); X (void) signal(SIGHUP, ohup); X# endif X return value; X} X Xdo_score(eaten,fd,max_days,type_str) X bool eaten; X int fd, max_days; X char *type_str; X{ X register struct scorefile *position; X register int x; X register struct scorefile *remove, *sfile, *eof; X struct scorefile *oldest, *this; X int uid, this_day, limit; X X this_day = max_days ? time((time_t *)0)/SECSPERDAY : 0; X limit = this_day-max_days; X sfile = (struct scorefile *)(malloc(FILE_SIZE)); X if( sfile == NULL) X { X fprintf( stderr, "Out of memmory so no scoring"); X return FALSE; X } X eof = &sfile[NUMSCORES]; X this = 0; X for(position = sfile; position < eof; position++) { X position->s_score = 0; X position->s_days = 0; X } X read(fd, (char *)sfile,FILE_SIZE); X remove = 0; X if(score > 0) { X uid = getuid(); X oldest = 0; X x = limit; X for(position = eof-1; position >= sfile; position--) { X if(position->s_days < x) { X x = position->s_days; X oldest = position; X } X } X position = 0; X for(remove = sfile; remove < eof; remove++) { X if(position == 0 && score > remove->s_score) position = remove; X# ifndef ALLSCORES X if(remove->s_uid == uid) break; X# endif ALLSCORES X } X if(remove < eof) { X if(position == 0 && remove->s_days < limit) position = remove; X } else if(oldest) { X remove = oldest; X if(position == 0) { X position = eof-1; X } else if(remove < position) { X position--; X } X } else if(position) { X remove = eof-1; X } X if(position) { X if(remove < position) { X while(remove < position) { X *remove = *(remove+1); X remove++; X } X } else { X while(remove > position) { X *remove = *(remove-1); X remove--; X } X } X position->s_score = score; X (void) strncpy(position->s_name,whoami,MAXSTR); X position->s_eaten = eaten; X position->s_level = LEVEL; X position->s_uid = uid; X position->s_days = this_day; X this = position; X X if(lseek(fd,0L,0) == -1L || X write(fd,(char *)sfile,FILE_SIZE) != FILE_SIZE) X perror("scorefile"); X close(fd); X } X } X if( show_highscore || this ) X { X printf( X# ifdef ALLSCORES X "\nTop %s Scores %s:\n", X# else ALLSCORES X "\nTop %s Robotists %s:\n", X# endif ALLSCORES X NUMNAME, X type_str X ); X printf("Rank Score Name\n"); X for(position = sfile; position < eof; position++) { X if(position->s_score == 0) break; X if(position == this) X putchar('>'); X else putchar(' '); X printf( X "%c%2d %9ld %s: %s on level %d.", X position->s_days < limit ? '*' : ' ', X position-sfile+1, X position->s_score, X position->s_name, X position->s_eaten ? "eaten" : "chickened out", X position->s_level X ); X if(position == this) X putchar('<'); X putchar('\n'); X } X } X return (this != 0); X} X Xscorer() X{ X static char tels[6]; X if(free_teleports != old_free) { X if(free_teleports > free_per_level) { X (void) sprintf(tels,"%d+%d", X free_per_level, X free_teleports-free_per_level); X } else { X (void) sprintf(tels,"%d",free_teleports); X } X old_free = free_teleports; X } X move(LINES-1,0); X clrtoeol(); X printw("<%s> level: %d score: %ld",tels,LEVEL,score); X mvprintw(LINES-1,RVPOS,"heaps:%3d robots:%3d value: %d", X scrap_heaps,nrobots_alive,robot_value); X clrtoeol(); X} X END_OF_score.c if test 4532 -ne `wc -c <score.c`; then echo shar: \"score.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f user.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"user.c\" else echo shar: Extracting \"user.c\" \(3604 characters\) sed "s/^X//" >user.c <<'END_OF_user.c' X# include "robots.h" X X/* X * user.c: user oriented things X */ X Xcommand() /* whats the user trying to tell us */ X{ Xretry: X move(my_y,my_x); X refresh(); X if(last_stand) return; X bad_move = FALSE; X if(!running) { X cmd_ch = read_com(); X switch(cmd_ch) { X case ctrl('W'): X waiting = TRUE; X case ctrl('H'): X case ctrl('J'): X case ctrl('K'): X case ctrl('L'): X case ctrl('Y'): X case ctrl('U'): X case ctrl('B'): X case ctrl('N'): X cmd_ch |= 0100; X adjacent = TRUE; X case 'H': X case 'J': X case 'K': X case 'L': X case 'Y': X case 'U': X case 'B': X case 'N': X cmd_ch |= 040; X running = TRUE; X first_move = TRUE; X case 't': X case 'T': X case 's': X case 'S': X case 'W': X case 'm': X case 'M': X case '?': X case 'd': X case 'D': X case ctrl('R'): X count = 0; X } X } X switch(cmd_ch) { X case '.': X case 'h': X case 'j': X case 'k': X case 'l': X case 'y': X case 'u': X case 'b': X case 'n': X case 'w': X do_move(cmd_ch); X break; X case 't': X case 'r': X case 'T': X case 'R': X teleport: X new_x = rndx(); X new_y = rndy(); X move(new_y,new_x); X switch(inch()) { X case FROBOT: X case ROBOT: X case SCRAP: X case ME: X goto teleport; X } X if( (free_teleports > 0) X && ((cmd_ch == 't')||(cmd_ch =='T')) ) { X if( !isgood(new_y, new_x)) X goto teleport; X free_teleports--; X } X break; X case 's': X case 'S': X case 'W': X last_stand = TRUE; X leaveok(stdscr,TRUE); X return; X case 'm': X case 'M': X case '?': X good_moves(); X goto retry; X case 'd': X case 'D': X if(dots < 2) { X dots++; X put_dots(); X } else { X erase_dots(); X dots = 0; X } X goto retry; X case 'q': X case 'Q': X quit(FALSE); X case 'a': X case 'A': /* Antimatter - sonic screwdriver */ X if (free_teleports) { new_x = my_x; X new_y = my_y; X screwdriver(); X } X else goto retry; X break; X case ctrl('R'): X clearok(curscr,TRUE); X wrefresh(curscr); X goto retry; X default: X bad_move = TRUE; X } X if(bad_move) { X if(running) { X if(first_move) putchar(BEL); X running = FALSE; X adjacent = FALSE; X waiting = FALSE; X first_move = FALSE; X } else { X putchar(BEL); X } X refresh(); X count = 0; X goto retry; X } X first_move = FALSE; X if(dots) erase_dots(); X mvaddch(my_y,my_x,' '); X my_x = new_x; X my_y = new_y; X move(my_y,my_x); X if(inch() == ROBOT) munch(); X if(inch() == FROBOT) munch(); X if(dots) put_dots(); X mvaddch(my_y,my_x,ME); X refresh(); X} X Xread_com() X{ X static int com; X X if(count == 0) { X if(isdigit(com = readchar())) { X count = com-'0'; X while(isdigit(com = readchar())) X count = count*10+com-'0'; X } X } X if(count > 0) count--; X return(com); X} X Xdo_move(dir) /* implement the users move */ X char dir; X{ X register int x, y; X new_x = my_x+xinc(dir); X new_y = my_y+yinc(dir); X if(adjacent && !first_move) { X for(x = -2; x <= 2; x++) { X for(y = -2; y <= 2; y++) { X move(new_y+y ,new_x+x); X switch(inch()) { X case SCRAP: X if( waiting ) X break; X case ROBOT: X if(abs(x) < 2 && abs(y) < 2) { X bad_move = TRUE; X return; X } X else break; X case FROBOT: X if (waiting && X blocked(new_y, new_x, y, x) ) X break; X bad_move = TRUE; X return; X } X } X } X } X move(new_y,new_x); X switch(inch()) { X case SCRAP: X if(moveable_heaps && move_heap(dir)) X break; X case VERT: X case HORIZ: X bad_move = TRUE; X return; X } X} X Xmove_heap(dir) /* push a scrap heap */ Xchar dir; X{ X register int x, y; X X x = new_x + xinc(dir); X y = new_y + yinc(dir); X move(y, x); X switch(inch()) { X case VERT: X case HORIZ: X case SCRAP: X case ROBOT: X case FROBOT: X return FALSE; X } X addch(SCRAP); X mvaddch(new_y,new_x,' '); X return TRUE; X} END_OF_user.c if test 3604 -ne `wc -c <user.c`; then echo shar: \"user.c\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of shell archive. exit 0