billr@saab.CNA.TEK.COM (Bill Randle) (05/02/91)
Submitted-by: Tad White <tadpole@math.ucla.edu> Posting-number: Volume 12, Issue 66 Archive-name: torus/Part01 Environment: curses [[This is a topologically enhanced version of Robots2, played on a torus (or optionally on an annulus or a rectangle).]] #! /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 archive 1 (of 1)." # Contents: Makefile good.c main.c opt.c robot.c robots.h score.c # torus.6 user.c # Wrapped by billr@saab on Wed May 1 13:02:47 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(5805 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' X# Makefile written by Paul Pomes, University of Illinois, X# Computing Services Office X# X# Copyright (C) 1986 by Paul Pomes and the University of Illinois Board X# of Trustees X# X# This Makefile is distributed in the hope that it will be useful, X# but without any warranty. No author or distributor accepts X# responsibility to anyone for the consequences of using it or for X# whether it serves any particular purpose or works at all, unless X# s/he says so in writing. X# X# Everyone is granted permission to copy, modify and redistribute X# this Makefile under the following conditions: X# X# Permission is granted to anyone to make or distribute copies X# of Makefile source code, either as received or modified, in any X# medium, provided that all copyright notices, permission and X# nonwarranty notices are preserved, and that the distributor X# grants the recipient permission for further redistribution as X# permitted by this document, and gives him and points out to X# him an exact copy of this document to inform him of his rights. X# X# Permission is granted to distribute this Makefile in compiled X# or executable form under the same conditions applying for X# source code, provided that either X# A. it is accompanied by the corresponding machine-readable X# source code, or X# B. it is accompanied by a written offer, with no time limit, X# to give anyone a machine-readable copy of the corresponding X# source code in return for reimbursement of the cost of X# distribution. This written offer must permit verbatim X# duplication by anyone. X# C. it is distributed by someone who received only the X# executable form, and is accompanied by a copy of the X# written offer of source code which he received along with it. X# X# In other words, you are welcome to use, share and improve this X# Makefile. You are forbidden to forbid anyone else to use, share X# and improve what you give them. Help stamp out software-hoarding! X# X# UUCP: {ihnp4,seismo}!uiucuxc!paul X# Internet: paul@uxc.cso.uiuc.edu BITNET: paul@uiucuxc X# MILNET: paul@uiucuxc.arpa CSNET: paul%uxc@uiuc.csnet X# US Mail: Univ of Illinois, CSO, 1304 W Springfield Ave, Urbana, IL 61801 X X# .PREFIXES: ./RCS X.SUFFIXES: .c,v .h,v .y,v X XCC = cc XCO = co XRM = /bin/rm -f X XHOF_FILE= ${DESTLIB}/robots2_hof XTMP_FILE= ${DESTLIB}/robots2_tmp XT_HOF_FILE= ${DESTLIB}/torus_hof XT_TMP_FILE= ${DESTLIB}/torus_tmp X X# -DBSD42 provides big performance win X XDEFS = -DBSD42 -DHOF_FILE='"${HOF_FILE}"' -DTMP_FILE='"${TMP_FILE}"' -DT_HOF_FILE='"${T_HOF_FILE}"' -DT_TMP_FILE='"${T_TMP_FILE}"' XCFLAGS = ${DEFS} -O XFFLAGS = ${DEFS} XPFLAGS = ${DEFS} XLFLAGS = XYFLAGS = XLDFLAGS= XLIBS = -lcurses -ltermcap X XDESTBIN= /home/oak/grad/tadpole/topology XDESTETC= /home/oak/grad/tadpole/topology/etc XDESTLIB= /home/oak/grad/tadpole/topology/lib XMS = l X X XHDRS = robots.h XSRCS = 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 XVERS = X X.c,v.o: X ${CO} -q $*.c X ${CC} ${CFLAGS} -c $*.c X ${RM} $*.c X X.c,v.c: X ${CO} -q $*.c X X.h,v.h: X ${CO} -q $*.h X X.y,v.y: X ${CO} -q $*.y X Xall: torus X Xtorus: ${OBJS} X ${CC} -o torus ${LDFLAGS} ${OBJS} ${LIBS} X Xinstall: torus X install -s -m 2511 -g games torus ${DESTBIN} X touch ${HOF_FILE} ${TMP_FILE} X chmod 664 ${HOF_FILE} ${TMP_FILE} X chgrp games ${HOF_FILE} ${TMP_FILE} X touch ${T_HOF_FILE} ${T_TMP_FILE} X chmod 664 ${T_HOF_FILE} ${T_TMP_FILE} X chgrp games ${T_HOF_FILE} ${T_TMP_FILE} X install -c -m 444 torus.6 ${MANDIR}/torus.${MS} X Xuninstall: /tmp X rm -f ${DESTBIN}/torus \ X ${MANDIR}/torus.${MS} ${CATDIR}/torus.${MS} \ X ${HOF_FILE} ${TMP_FILE} X Xlint: ${HDRS} ${SRCS} X lint -habx ${DEFS} ${SRCS} X Xshar: ${HDRS} ${SRCS} ${OTHERS} X shar ${HDRS} ${SRCS} ${OTHERS} > torus.shar X Xtags: ${HDRS} ${SRCS} X ctags ${HDRS} ${SRCS} X Xclean: X @echo "Removing object and junk files." X rm -f robots2 *.o core a.out make.log lint.out Makefile.bak torus.shar X Xclobber: X @echo "Removing read-only source files that have RCS parents." X @echo "Error code 1 indicates last file in SRCS list was not removed." X @echo "(Which is OK)" X make clean X -if [ `whoami` != root ]; then \ X for i in ${HDRS} ${SRCS}; do \ X if [ ! -w $$i ]; then \ X ( if [ -f $$i,v ]; then rm -f $$i; \ X elif [ -f RCS/$$i,v ]; then rm -f $$i; \ X fi ); \ X else echo $$i "writeable, not removed"; \ X fi; \ X done; \ X else echo "Running \"make clobber\" as root will zap ALL SRCS,\ X RCS'ed or not (not done)."; \ X fi X Xcompress: X make clean X @echo "Compressing source and RCS files." X find . -size +2 \( -name \*.h -o -name \*.c -o -name \*.f \ X -o -name \*.p -o -name \*.l -o -name \*.y -o -name \*,v \) \ X -exec compress {} \; X Xuncompress: X uncompressdir . X X# RCS stuff X Xci: ${HDRS} ${SRCS} X -ci $? X @touch ci X Xcoall: X co -l ${HDRS} ${SRCS} X Xupdate: X ci -sDist -u -f${VERS} ${HDRS} ${SRCS} X @touch ci X Xdepend: X grep '^#[ ]*include' /dev/null ${SRCS} \ X | sed -e '/"/s/:[^"]*"\([^"]*\)".*/: \1/' \ X -e '/</s/:[^<]*<\([^>]*\)>.*/: \/usr\/include\/\1/' \ X | sed -e 's/\.c:/.o:/' -e 's/\.p:/.o:/' \ X -e 's/\.y:/.o:/' -e 's/\.l:/.o:/' >makedep X echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep X echo '$$r makedep' >>eddep X echo 'w' >>eddep X cp Makefile Makefile.bak X ed - Makefile < eddep X rm eddep makedep X echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile X echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile X echo '# see make depend above' >> Makefile X X# DO NOT DELETE THIS LINE -- make depend uses it X Xgood.o: robots.h Xmain.o: robots.h Xmain.o: /usr/include/sys/stat.h Xopt.o: robots.h Xrobot.o: robots.h Xscore.o: robots.h Xuser.o: robots.h X# DEPENDENCIES MUST END AT END OF FILE X# IF YOU PUT STUFF HERE IT WILL GO AWAY X# see make depend above END_OF_FILE if test 5805 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'good.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'good.c'\" else echo shar: Extracting \"'good.c'\" \(3748 characters\) sed "s/^X//" >'good.c' <<'END_OF_FILE' 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 = hbound(my_y+yinc(*m),my_x+xinc(*m)); X test_y = vbound(my_y+yinc(*m),my_x+xinc(*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 = hbound(test_y +yinc(*m),test_x +xinc(*m)); X nscrap_y = vbound(test_y +yinc(*m),test_x +xinc(*m)); X move(nscrap_y,nscrap_x); X/* if (inch()==DOT) { X addch(SCRAP); X if (isgood(test_y,test_x)) X *a++ = *m; X move(nscrap_y,nscrap_x); X addch(DOT); 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 } */ /* rfs -- rewritten to eliminate bug in wimpy mode */ X if ((savechar=inch())==DOT || savechar==' ') { X addch(SCRAP); X if (isgood(test_y,test_x)) X *a++ = *m; X move(nscrap_y,nscrap_x); X addch(savechar); X } /* rfs -- end of replacement code */ 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 tmove(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 tmove(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 tmove(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 tmove(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 tmove(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 tmove(my+y, mx+x); X return inch() == SCRAP; X} END_OF_FILE if test 3748 -ne `wc -c <'good.c'`; then echo shar: \"'good.c'\" unpacked with wrong size! fi # end of 'good.c' fi if test -f 'main.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'main.c'\" else echo shar: Extracting \"'main.c'\" \(9110 characters\) sed "s/^X//" >'main.c' <<'END_OF_FILE' X/* X * R O B O T S ( T O R U 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 * Topological modifications: X * Tad White <tadpole@math.ucla.edu> 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 adjacent, first_move, bad_move, waiting; Xbool moveable_heaps = TRUE; Xbool hsew = TRUE; Xbool vsew = TRUE; Xbool toral = TRUE; Xbool hrev = FALSE; Xbool vrev = FALSE; Xbool wimpy = FALSE; Xbool all_moves = FALSE; Xbool continuous = FALSE; 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 X# ifdef TURBOC Xint X#endif Xr_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(); X# ifndef TURBOC /* rfs */ Xstruct passwd *getpwuid(); Xchar _obuf[BUFSIZ]; X# endif X Xmain(argc,argv) X int argc; X char *argv[]; X{ X# ifndef TURBOC /* rfs */ X register struct passwd *pass; X# endif X X register char *x; X int i; X X# ifndef TURBOC /* rfs */ X setbuf(stdout, _obuf); X# endif X if(argc > 1) X for(i=1;i<argc;i++) { X if(argv[i][0] == '-') X switch(argv[i][1]) { X case 's': X show_highscore = TRUE; X scoring(FALSE); X exit(0); X break; X case 'h': X hsew = FALSE; X /* hrev = TRUE; */ X break; X case 'v': X vsew = FALSE; X /* vrev = TRUE; */ X break; X case 'w': X wimpy = FALSE; X break; X case 'c': X continuous = FALSE; X break; X } X if(argv[i][0] == '+') { X switch(argv[i][1]) { X case 'h': X hsew = TRUE; X hrev = FALSE; X break; X case 'v': X vsew = TRUE; X vrev = FALSE; X break; X case 'w': X wimpy = TRUE; X break; X case 'c': X continuous = TRUE; X break; X } X } X if (argv[i][0] == '0') { X switch(argv[i][1]) { X case 'h': X hsew = FALSE; X hrev = FALSE; X break; X case 'v': X vsew = FALSE; X vrev = FALSE; X break; X } X } X } X# ifdef TURBOC /* rfs */ X if (strcmp(x=getenv("USERNAME"),"")==0) x="ANON"; X# else X if((pass = getpwuid(getuid())) == 0) { X x = "ANON"; X } else { X x = pass->pw_name; X } X# endif 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# ifndef TURBOC /* rfs */ X (void) signal(SIGQUIT,r_interrupt); X (void) signal(SIGINT,r_interrupt); X# endif X if( initscr() == ERR) { X fprintf(stderr, "Curses won't initialize - seek a guru\n"); X quit(); 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 Xrestart: X dead = FALSE; X free_teleports = 0; X level = 0; X free_per_level = 1; X scrap_heaps = 1; X score = 0; X robot_value = MIN_VALUE; X max_robots = MIN_ROBOTS; X for(;;) { X count = 0; 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 if (dots) put_dots(); 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(); goto restart; } 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# ifdef TURBOC /* rfs */ X return getch(); X# else X static char buf[1]; X extern int errno; X X while(read(0,buf,1) != 1) X if( errno != EINTR) { X scoring(TRUE); X quit(); X } X return(buf[0]); X# endif 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 tmove(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 tmove(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 Xint vbound(y,x) /* for toral robots: converts y to lie within boundary */ X int y,x; X{ X register int t_y; X t_y = y; X if ( vsew /* ||vrev */ ) { X if (y >= LINES-2) t_y = y - (LINES-3); X if (y <= 0) t_y = y + (LINES-3); X } X /* if ( (hrev) && ((x >= COLS-1) || (x <= 0)) ) t_y = LINES - 2 - t_y; */ X return(t_y); X} X Xint hbound(y,x) X int y,x; X{ X register int t_x; X t_x = x; X if (hsew /*||hrev*/ ) { X if (x >= COLS-1) t_x = x - (COLS-2); X if (x <= 0) t_x = x + (COLS-2); X } X /* if ( (vrev) && ((y >= LINES-2) || (y <= 0)) ) t_x = COLS - 1 - t_x; */ X return(t_x); X} X Xtmove(y,x) /* move with wrap-around, if edge identifications made. */ Xint y,x; X{ X move(vbound(y,x),hbound(y,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 scoring(TRUE); X if (!continuous) quit(); X} X Xquit() 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 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 X# ifdef TURBOC /* rfs */ Xint X# endif Xr_interrupt() X{ X scoring(FALSE); X quit(); X} X X/* X * file locking routines - much nicer under BSD ... X */ X X# ifdef TURBOC /* rfs */ Xlk_open(file,mode) /* don't need to lock score files on IBM PCs */ Xchar *file; Xint mode; X{ X int fd; X if ((fd = open(file, mode, S_IREAD|S_IWRITE)) < 0) return -1; X return fd; X} X Xlk_close(fd, fname) Xint fd; Xchar *fname; X{ X return close(fd); X} X X# endif X# if defined(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 X# ifdef TURBOC /* rfs */ Xint getuid () { X return 0; X } X# endif END_OF_FILE if test 9110 -ne `wc -c <'main.c'`; then echo shar: \"'main.c'\" unpacked with wrong size! fi # end of 'main.c' fi if test -f 'opt.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'opt.c'\" else echo shar: Extracting \"'opt.c'\" \(2564 characters\) sed "s/^X//" >'opt.c' <<'END_OF_FILE' 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# define OPT_HSEW 6 X "hsew", OPT_HSEW, X# define OPT_NOHSEW 7 X "nohsew", OPT_NOHSEW, X# define OPT_VSEW 8 X "vsew", OPT_VSEW, X# define OPT_NOVSEW 9 X "novsew", OPT_NOVSEW, X# define OPT_WIMPY 10 X "wimpy", OPT_WIMPY, X# define OPT_STUDLY 11 X "studly", OPT_STUDLY, X# define OPT_CONT 12 X "continuous", OPT_CONT, X# define OPT_NOCONT 13 X "nocontinuous", OPT_NOCONT, 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 case OPT_HSEW: X hsew = TRUE; X break; X case OPT_NOHSEW: X hsew = FALSE; X break; X case OPT_VSEW: X vsew = TRUE; X break; X case OPT_NOVSEW: X vsew = FALSE; X break; X case OPT_WIMPY: X wimpy = TRUE; X break; X case OPT_STUDLY: X wimpy = FALSE; X break; X case OPT_CONT: X continuous = TRUE; X break; X case OPT_NOCONT: X continuous = FALSE; X break; X } X } X} X END_OF_FILE if test 2564 -ne `wc -c <'opt.c'`; then echo shar: \"'opt.c'\" unpacked with wrong size! fi # end of 'opt.c' fi if test -f 'robot.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'robot.c'\" else echo shar: Extracting \"'robot.c'\" \(4144 characters\) sed "s/^X//" >'robot.c' <<'END_OF_FILE' 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 register int x_inc, y_inc, h_dist, v_dist; 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 x_inc = sign(my_x-r->x); X y_inc = sign(my_y-r->y); X /* X h_dist = (hrev) ? abs(my_x-WIDTH+r->x) : abs(my_x-r->x); X v_dist = (vrev) ? abs(my_y-HEIGHT+r->y) : abs(my_y-r->y); X if ((hsew || hrev) && (h_dist > WIDTH/2)) x_inc *= -1; X if ((vsew || vrev) && (v_dist > HEIGHT/2)) y_inc *= -1; X if ((hrev) && (v_dist > HEIGHT/2)) y_inc *= -1; X if ((vrev) && (h_dist > WIDTH/2)) x_inc *= -1; X */ X if ( hsew && (abs(my_x-r->x) > (COLS-2)/2) ) X x_inc *= -1; X if ( vsew && (abs(my_y-r->y) > (LINES-3)/2) ) X y_inc *= -1; X r->y=vbound(r->y+y_inc,r->x+x_inc); X r->x=hbound(r->y+y_inc,r->x+x_inc); 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 = hbound(my_y+yinc(*m),my_x+xinc(*m)); X test_y = vbound(my_y+yinc(*m),my_x+xinc(*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_FILE if test 4144 -ne `wc -c <'robot.c'`; then echo shar: \"'robot.c'\" unpacked with wrong size! fi # end of 'robot.c' fi if test -f 'robots.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'robots.h'\" else echo shar: Extracting \"'robots.h'\" \(2662 characters\) sed "s/^X//" >'robots.h' <<'END_OF_FILE' 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 '@' 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# define WIDTH (COLS-2) X# define HEIGHT (LINES-3) X X/* These you may want to fiddle with. Position of the two high score files */ X#ifndef HOF_FILE X# define HOF_FILE "/usr/sheriff/jpo/games/lib/robots_hof" X#endif X#ifndef TMP_FILE X# define TMP_FILE "/usr/sheriff/jpo/games/lib/robots_tmp" X#endif 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 hsew; Xextern bool vsew; Xextern bool toral; Xextern bool hrev; Xextern bool vrev; Xextern bool wimpy; Xextern bool continuous; Xextern bool all_moves; 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_FILE if test 2662 -ne `wc -c <'robots.h'`; then echo shar: \"'robots.h'\" unpacked with wrong size! fi # end of 'robots.h' fi if test -f 'score.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'score.c'\" else echo shar: Extracting \"'score.c'\" \(5431 characters\) sed "s/^X//" >'score.c' <<'END_OF_FILE' 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 bool s_hsew; X bool s_vsew; X bool s_wimpy; 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 toral = hsew && vsew; X (void) sprintf(buf,"for this %s",TEMP_NAME); X if( record_score(eaten,toral?T_TMP_FILE:TMP_FILE,TEMP_DAYS,buf) X || show_highscore) { X printf("[Press return to continue]"); X fflush(stdout); X gets(buf); X } X record_score(eaten,toral?T_HOF_FILE: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# ifdef TURBOC /* rfs */ X void X# else X int X# endif X (*oint)(), (*oterm)(), (*ohup)(); X X oint = signal(SIGINT, SIG_IGN); X oterm = signal(SIGTERM, SIG_IGN); X# ifndef TURBOC /* rfs */ X ohup = signal(SIGHUP, SIG_IGN); X# endif X# else X omask = sigblock( sigbit(SIGINT) | sigbit(SIGTERM) | sigbit(SIGHUP) X | sigbit(SIGTSTP)); X# endif X X if((fd = lk_open(fname, X# ifdef TURBOC /* rfs */ X O_RDWR | O_CREAT | O_BINARY X# else X 2 X# endif X )) < 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# ifndef TURBOC /* rfs */ X (void) signal(SIGHUP, ohup); X# endif 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; */ /* rfs */ X register struct scorefile *remove, *eof; /* rfs */ X static struct scorefile *sfile=NULL; /* rfs */ 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 if (sfile==NULL) /* rfs */ X sfile = (struct scorefile *)(malloc(FILE_SIZE)); X if( sfile == NULL) X { X fprintf( stderr, "Out of memory 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_hsew = hsew; X position->s_vsew = vsew; X position->s_wimpy = wimpy; X position->s_days = this_day; X this = position; 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 %s Scores %s:\n", X# else ALLSCORES X "\nTop %s %s Robotists %s:\n", X# endif ALLSCORES X NUMNAME, X toral?"Toral":"Non-Toral", 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 %10ld %8s: %s on %6s", X position->s_days < limit ? '*' : ' ', X position-sfile+1, X position->s_score, X position->s_name, X position->s_eaten ? X "robot chow" : "ducked out", X position->s_wimpy ? "wimpy" : "studly"); X if(position->s_hsew) X printf( " %7s", X (position->s_vsew) ? "toral" : "annular"); X else X printf( " %7s", X (position->s_vsew) ? "annular" : "planar"); X printf(" level %d.", 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_FILE if test 5431 -ne `wc -c <'score.c'`; then echo shar: \"'score.c'\" unpacked with wrong size! fi # end of 'score.c' fi if test -f 'torus.6' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'torus.6'\" else echo shar: Extracting \"'torus.6'\" \(4302 characters\) sed "s/^X//" >'torus.6' <<'END_OF_FILE' X.TH TORUS 6 "30 January 1990" X.SH NAME Xtorus \- a game of logic X.SH SYNOPSIS X.B /usr/games/torus X.RB [-c] [-s] [+-h] [+-v] [+-w] X.SH DESCRIPTION X.B Torus Xis a display-based game which must be played on a CRT terminal Xfrom among those supported by vi(1). This is a topologically Xenhanced version of the game Robots. 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 XThe current version supports non-planar games. Orientation- Xpreserving identifications of the sides may be made independently Xin both directions. The default playing field is a flat torus. X.PP XYou are represented on the screen by a '@' sign. 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 (if using the 'wimpy' option). X.IP M XTurn on or off the continuous display 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 OPTIONS XThe following command line options can be used to override Xthe environment settings: X.TP X.B \-s XDisplay the high scores. X.TP X.B \-c XPlay continuously -- no pauses between games. X.TP X.B \+h XIdentify the left and right edges of the screen. X.TP X.B \-h XDo not identify the left and right edges of the screen. X.TP X.B \+\/\-v XSame as above, but controls the top and bottom edges. X.TP X.B \+\/\-w XTurn on or off the Wimp setting (view legal moves). 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.IP continuous XPlay continuously without pauses between games. X.IP hsew XThis option identifies the left and right horizontal borders of the playing Xfield. 'vsew' is also available. X.IP wimpy/studly XThese options control the ability to display legal moves. 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. X.br XTopological enhancements by Tad White. X END_OF_FILE if test 4302 -ne `wc -c <'torus.6'`; then echo shar: \"'torus.6'\" unpacked with wrong size! fi # end of 'torus.6' fi if test -f 'user.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'user.c'\" else echo shar: Extracting \"'user.c'\" \(4626 characters\) sed "s/^X//" >'user.c' <<'END_OF_FILE' 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 if (all_moves && wimpy) good_moves(); X move(my_y,my_x); X refresh(); X if(last_stand) return; X bad_move = FALSE; X switch(cmd_ch=read_com()) { 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 all_moves = !all_moves; X goto retry; X case 'm': X case '?': X if (wimpy) good_moves(); X else mvprintw(LINES-1,MSGPOS,"Be a stud!"); 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 putchar(BEL); X refresh(); X count = 0; X adjacent=FALSE; X waiting=FALSE; X first_move=FALSE; 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)||(inch() == FROBOT)) dead=TRUE; X else { X if(dots) put_dots(); X mvaddch(my_y,my_x,ME); X refresh(); X } 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 else { /* rfs -- eliminate possible infinite loop when running */ X switch (com) { X case ctrl('W'): X /* com |= 0040; */ 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 com |= 0100; X adjacent = TRUE; X first_move=TRUE; X } X switch (com) { X case 'H': X case 'L': X count = WIDTH; X com |= 0040; X first_move=TRUE; X break; X case 'J': X case 'K': X count = HEIGHT; X com |= 0040; X first_move=TRUE; X break; X case 'Y': X case 'U': X case 'N': X case 'B': X case 'W': X { /* set count to the least common multiple of WIDTH and HEIGHT */ X int w=WIDTH, h=HEIGHT,t; X while (w>h) { X t=w-h; X if (t<h) { w=h; h=t; } X else w=t; X } X count=(WIDTH/w)*HEIGHT; X } X com |= 0040; X first_move=TRUE; X break; X default: X count=0; X break; X } 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 = hbound(my_y+yinc(dir),my_x+xinc(dir)); X new_y = vbound(my_y+yinc(dir),my_x+xinc(dir)); X if(adjacent && !first_move) { X for(x = -2; x <= 2; x++) { X for(y = -2; y <= 2; y++) { X tmove(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); /* already bounded */ X switch(inch()) { X case SCRAP: X if(moveable_heaps && move_heap(dir)) break; X else { X bad_move = TRUE; X return; X } X case VERT: X if (hsew||hrev) break; X else { X bad_move = TRUE; X return; X } X case HORIZ: X if (vsew||vrev) break; X else { X bad_move = TRUE; X return; X } X } X} X Xmove_heap(dir) /* push a scrap heap */ Xchar dir; X{ X register int x, y; X X x = hbound(new_y + yinc(dir),new_x + xinc(dir)); X y = vbound(new_y + yinc(dir),new_x + xinc(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_FILE if test 4626 -ne `wc -c <'user.c'`; then echo shar: \"'user.c'\" unpacked with wrong size! fi # end of 'user.c' fi echo shar: End of archive 1 \(of 1\). cp /dev/null ark1isdone MISSING="" for I in 1 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have the archive. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0