Robots game for 4.2 BSD (highly addictive).

98 views
Skip to first unread message

Stephen J. Muir

unread,
May 28, 1985, 1:25:12 PM5/28/85
to
Xpath: icdoc ivax


Run the following through the shell.
----------------------------------- cut here ----------------------------------
#!/bin/sh
echo 'Start of robots game, part 01 of 01:'
echo 'x - Makefile'
sed 's/^X//' > Makefile << '/'
Xrobots: robots.c
X cc -O robots.c -o robots -lcurses -ltermcap
X
Xinstall: robots
X cp robots.6 /usr/man/man6/robots.6
X install -s -m 4111 robots /usr/games/robots
X touch /usr/games/lib/robots_hof
X touch /usr/games/lib/robots_tmp
X
Xclean:
X rm -f robots *.o
X
Xlint:
X lint -phbxac robots.c -lcurses -ltermcap > linterrs
/
echo 'x - robots.6'
sed 's/^X//' > 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 `=' signs.
XScrap heaps are represented by `@' signs.
XAfter each move, all robots move one step towards you.
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 .
XDo nothing.
X.IP t
XTeleport.
X.IP s
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.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' argument.
X.SH NOTES
XAt the start of each level, you have a number of
X.I free teleports.
XThese are teleports which are
X.I guaranteed
Xnot to land you next to a robot.
XThe number you have remaining is shown at the bottom left-hand corner
Xof the screen within angled brakets.
XAt the start of the level, you are given one, two or three free teleports.
XThis number starts off as one and increases as follows.
XIf you have one free teleport per level, and you save it,
Xyou will get two per level.
XIf you have two (or more) free teleports, and you save them both,
Xyou will get three per level.
XIf you have two free teleports, and you save one of them,
Xyou have a 50% chance of getting three per level.
XWhere there are two numbers, the second indicates free teleports saved from
Xthe previous level.
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.
/
echo 'x - robots.c'
sed 's/^X//' > robots.c << '/'
X/* Written by Allan R. Black, Strathclyde University.
X * This program may be freely distributed provided that
X * this comment is not removed and that
X * no profit is gained from such distribution.
X */
X
X/*
X * @(#)robots.c 1.7 3/21/84
X */
X
X/* 1.7a modified by Stephen J. Muir at Lancaster University. */
X
X# include <curses.h>
X# include <signal.h>
X# include <pwd.h>
X# include <ctype.h>
X# include <sys/file.h>
X
X# define MIN_ROBOTS 10
X# define MAX_ROBOTS 500
X# define MIN_VALUE 10
X# define MAX_FREE 3
X
X# define VERT '|'
X# define HORIZ '-'
X# define ROBOT '='
X# define SCRAP '@'
X# define ME 'I'
X# define MUNCH '*'
X# define DOT '.'
X
X# define LEVEL (level+1)
X
X# define MSGPOS 39
X# define RVPOS 51
X
X# define HOF_FILE "/usr/games/lib/robots_hof"
X# define TMP_FILE "/usr/games/lib/robots_tmp"
X
X# define NUMSCORES 20
X# define NUMNAME "Twenty"
X
X# define TEMP_DAYS 7
X# define TEMP_NAME "Week"
X
X# define MAXSTR 100
X
Xextern char *getlogin ();
Xextern struct passwd *getpwnam ();
X
Xstruct scorefile {
X int s_uid;
X int 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
X/*# define ALLSCORES*/
X
X# define SECSPERDAY 86400
X
X# define BEL 007
X# define CTLH 010
X# define CTLJ 012
X# define CTLK 013
X# define CTLL 014
X# define CTLY 031
X# define CTLU 025
X# define CTLB 002
X# define CTLN 016
X# define CTLR 022
X
Xchar whoami[MAXSTR];
X
Xint my_x, my_y;
Xint new_x, new_y;
X
Xint level = 0;
Xint score = 0;
Xint free_teleports = 0;
Xint free_per_level = 1;
Xbool dead = FALSE;
Xbool last_stand;
X
Xint count;
Xchar com, cmd_ch;
Xbool running, adjacent, first_move, bad_move;
Xint dots = 0;
X
Xint robot_value = MIN_VALUE;
Xint max_robots = MIN_ROBOTS;
Xint robots_alive;
Xstruct passwd *pass;
X
Xstruct robot {
X bool alive;
X int x;
X int y;
X} robot_list[MAX_ROBOTS];
X
Xint seed;
X
Xstruct ltchars ltc;
X
Xchar dsusp;
X
Xint _putchar();
Xint interrupt();
X
Xchar *forbidden [] =
X { "root",
X "daemon",
X "uucp",
X "pop",
X "ingres",
X "demo",
X "chessel",
X "saturn",
X "sjm",
X "cosmos",
X 0
X };
X
Xmain(argc,argv)
X int argc;
X char *argv[];
X{
X register char *x, **xx;
X if(argc > 1) {
X if(argv[1][0] == '-') {
X switch(argv[1][1]) {
X case 's':
X scoring(FALSE);
X exit(0);
X }
X }
X }
X if ((x = getlogin ()) == 0 || (pass = getpwnam (x)) == 0)
X { printf ("Who the hell are you?\n");
X exit (1);
X }
X strcpy(whoami,x);
X for (xx = forbidden; *xx; ++xx)
X if (strcmp (whoami, *xx) == 0)
X { printf ("only individuals may play robots\n");
X exit (1);
X }
X seed = time(0)+pass->pw_uid;
X signal(SIGQUIT,interrupt);
X signal(SIGINT,interrupt);
X initscr();
X crmode();
X noecho();
X ioctl(1,TIOCGLTC,&ltc);
X dsusp = ltc.t_dsuspc;
X ltc.t_dsuspc = ltc.t_suspc;
X ioctl(1,TIOCSLTC,&ltc);
X for(;;) {
X count = 0;
X running = FALSE;
X adjacent = FALSE;
X last_stand = FALSE;
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(winch(stdscr) != ' ');
X addch(ME);
X for(;;) {
X scorer();
X if(robots_alive == 0) break;
X command();
X robots();
X if(dead) munch();
X }
X if (!level)
X nice (2);
X msg("%d robots are now scrap heaps",max_robots);
X leaveok(stdscr,FALSE);
X move(my_y,my_x);
X refresh();
X 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
Xput_robots()
X{
X register struct robot *r, *end;
X register int x, y;
X robot_value += level*5+rnd(level*10);
X max_robots += level*3+rnd(level*5);
X if(max_robots > MAX_ROBOTS) max_robots = MAX_ROBOTS;
X robots_alive = max_robots;
X end = &robot_list[max_robots];
X for(r = robot_list; r < end; r++) {
X for(;;) {
X x = rndx();
X y = rndy();
X move(y,x);
X if(winch(stdscr) == ' ') break;
X }
X r->x = x;
X r->y = y;
X r->alive = TRUE;
X addch(ROBOT);
X }
X}
X
Xcommand()
X{
X register int x, y;
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 CTLH:
X case CTLJ:
X case CTLK:
X case CTLL:
X case CTLY:
X case CTLU:
X case CTLB:
X case CTLN:
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 'm':
X case 'M':
X case '?':
X case 'd':
X case 'D':
X case CTLR:
X count = 0;
X }
X }
X switch(cmd_ch) {
X case '.':
X return;
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 do_move(cmd_ch);
X break;
X case 't':
X case 'T':
X teleport:
X new_x = rndx();
X new_y = rndy();
X move(new_y,new_x);
X switch(winch(stdscr)) {
X case ROBOT:
X case SCRAP:
X case ME:
X goto teleport;
X }
X if(free_teleports > 0) {
X for(x = new_x-1; x <= new_x+1; x++) {
X for(y = new_y-1; y <= new_y+1; y++) {
X move(y,x);
X if(winch(stdscr) == ROBOT) goto teleport;
X }
X }
X free_teleports--;
X }
X break;
X case 's':
X case 'S':
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 CTLR:
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 first_move = FALSE;
X } else {
X putchar(BEL);
X }
X refresh();
X count = 0;
X goto retry;
X }
X first_move = FALSE;
X mvaddch(my_y,my_x,' ');
X my_x = new_x;
X my_y = new_y;
X move(my_y,my_x);
X if(winch(stdscr) == ROBOT) munch();
X mvaddch(my_y,my_x,ME);
X refresh();
X}
X
Xread_com()
X{
X if(count == 0) {
X if (dots)
X { put_dots ();
X move (my_y, my_x);
X refresh ();
X }
X if(isdigit(com = readchar())) {
X count = com-'0';
X while(isdigit(com = readchar())) count = count*10+com-'0';
X }
X if (dots)
X erase_dots ();
X }
X if(count > 0) count--;
X return(com);
X}
X
Xreadchar()
X{
X static char buf[1];
X while(read(0,buf,1) <= 0);
X return(buf[0]);
X}
X
Xdo_move(dir)
X char dir;
X{
X register int x, y;
X new_x = my_x+xinc(dir);
X new_y = my_y+yinc(dir);
X move(new_y,new_x);
X switch(winch(stdscr)) {
X case VERT:
X case HORIZ:
X case SCRAP:
X bad_move = TRUE;
X }
X if(adjacent & !first_move) {
X for(x = new_x-1; x <= new_x+1; x++) {
X for(y = new_y-1; y <= new_y+1; y++) {
X move(y,x);
X switch(winch(stdscr)) {
X case ROBOT:
X case SCRAP:
X bad_move = TRUE;
X return;
X }
X }
X }
X }
X}
X
Xput_dots()
X{
X register int x, y;
X for(x = my_x-dots; x <= my_x+dots; x++) {
X if (x < 1 || x > COLS - 2)
X continue;
X for(y = my_y-dots; y <= my_y+dots; y++) {
X if (y < 1 || y > LINES - 3)
X continue;
X move(y,x);
X if(winch(stdscr) == ' ') 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 if (x < 1 || x > COLS - 2)
X continue;
X for(y = my_y-dots; y <= my_y+dots; y++) {
X if (y < 1 || y > LINES - 3)
X continue;
X move(y,x);
X if(winch(stdscr) == DOT) addch(' ');
X }
X }
X}
X
Xgood_moves()
X{
X register int x, y;
X register int test_x, test_y;
X register char *m, *a;
X static char moves[] = "hjklyubn.";
X static char ans[sizeof moves];
X a = ans;
X for(m = moves; *m; m++) {
X test_x = my_x+xinc(*m);
X test_y = my_y+yinc(*m);
X move(test_y,test_x);
X switch(winch(stdscr)) {
X case ' ':
X case ME:
X for(x = test_x-1; x <= test_x+1; x++) {
X for(y = test_y-1; y <= test_y+1; y++) {
X move(y,x);
X if(winch(stdscr) == ROBOT) goto bad;
X }
X }
X *a++ = *m;
X }
X bad:;
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
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
Xrobots()
X{
X register struct robot *r, *end, *find;
X end = &robot_list[max_robots];
X for(r = robot_list; r < end; r++) {
X if(r->alive) {
X mvaddch(r->y,r->x,' ');
X }
X }
X for(r = robot_list; r < end; r++) {
X if(r->alive) {
X r->x += sign(my_x-r->x);
X r->y += sign(my_y-r->y);
X move(r->y,r->x);
X switch(winch(stdscr)) {
X case ME:
X addch(MUNCH);
X dead = TRUE;
X break;
X case SCRAP:
X r->alive = FALSE;
X score += robot_value;
X robots_alive--;
X break;
X case ROBOT:
X for(find = robot_list; find < r; find++) {
X if(find->alive) {
X if(r->x == find->x && r->y == find->y) {
X find->alive = FALSE;
X break;
X }
X }
X }
X r->alive = FALSE;
X addch(SCRAP);
X score += robot_value*2;
X robots_alive -= 2;
X break;
X case MUNCH:
X break;
X default:
X addch(ROBOT);
X }
X }
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 readchar();
X quit(TRUE);
X}
X
Xquit(eaten)
X bool eaten;
X{
X move(LINES-1,0);
X refresh();
X endwin();
X putchar('\n');
X ltc.t_dsuspc = dsusp;
X ioctl(1,TIOCSLTC,&ltc);
X scoring(eaten);
X exit(0);
X}
X
Xscoring(eaten)
X bool eaten;
X{
X static char buf[MAXSTR];
X sprintf(buf,"for this %s",TEMP_NAME);
X record_score(eaten,TMP_FILE,TEMP_DAYS,buf);
X printf("[Press return to continue]");
X fflush(stdout);
X gets(buf);
X record_score(eaten,HOF_FILE,0,"of All Time");
X}
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 fd;
X int (*action)();
X action = signal(SIGINT,SIG_IGN);
X if((fd = open(fname,2)) < 0) {
X perror(fname);
X } else {
X if(flock(fd,LOCK_EX) < 0) {
X perror(fname);
X } else {
X do_score(eaten,fd,max_days,type_str);
X flock(fd,LOCK_UN);
X }
X close(fd);
X }
X signal(SIGINT,action);
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 char *so, *ts;
X int uid, this_day, limit;
X static char buf[20];
X ts = buf;
X this_day = max_days ? time(0)/SECSPERDAY : 0;
X limit = this_day-max_days;
X sfile = (struct scorefile *)(malloc(FILE_SIZE));
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,sfile,FILE_SIZE);
X remove = 0;
X if(score > 0) {
X uid = pass->pw_uid;
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)
X { if (remove->s_days < limit)
X oldest = remove;
X else
X break;
X }
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 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 lseek(fd,0,0);
X write(fd,sfile,FILE_SIZE);
X close(fd);
X }
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 count = 0;
X for(position = sfile; position < eof; position++) {
X if(position->s_score == 0) break;
X if(position == this && SO && SE) {
X tputs(SO,0,_putchar);
X }
X if (position->s_days >= limit)
X { printf ("%-6d %-8d %s: %s on level %d.",
X ++count,
X position->s_score,
X position->s_name,
X position->s_eaten ? "eaten" : "chickened out",
X position->s_level
X );
X# ifdef OLDSCORES
X } else
X { printf ("**OLD** %-8d %s: %s on level %d.",
X position->s_score,
X position->s_name,
X position->s_eaten ? "eaten" : "chickened out",
X position->s_level
X );
X# endif OLDSCORES
X }
X if(position == this && SO && SE) {
X tputs(SE,0,_putchar);
X }
X# ifndef OLDSCORES
X if (position->s_days >= limit)
X# endif OLDSCORES
X putchar ('\n');
X }
X}
X
Xscorer()
X{
X static char infobuf [6];
X register int x, y;
X if ((y = free_teleports-free_per_level) < 0)
X y = 0;
X x = free_teleports-y;
X sprintf(infobuf,"%d+%d",x,y);
X if (y == 0)
X infobuf[1] = '\0';
X move(LINES-1,0);
X clrtoeol();
X printw("<%s> level: %d score: %d",infobuf,LEVEL,score);
X mvprintw(LINES-1,RVPOS,"robots: %d value: %d",robots_alive,robot_value);
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*11109+13849) >> 16) & 0xffff) % mod);
X}
X
Xsign(x)
X register int x;
X{
X if(x < 0) return(-1);
X return(x > 0);
X}
X
Xmsg(message,args)
X char *message;
X int args;
X{
X register int x;
X static FILE msgpr;
X static char msgbuf[1000];
X msgpr._flag = _IOSTRG | _IOWRT;
X msgpr._ptr = msgbuf;
X msgpr._cnt = 1000;
X _doprnt(message,&args,&msgpr);
X putc(0,&msgpr);
X mvaddstr(LINES-1,MSGPOS,msgbuf);
X clrtoeol();
X refresh();
X}
X
Xinterrupt()
X{
X quit(FALSE);
X}
/
echo 'Part 01 of robots game complete.'
exit
--
NAME: Stephen J. Muir Project: Alvey ECLIPSE Distribution
JANET: ste...@uk.ac.lancs.comp DARPA: stephen%lancs.comp@ucl-cs
UUCP: ...!ukc!icdoc!dcl-cs!stephen PHONE: +44 524 65201 Ext. 4599
POST: Department of Computing, University of Lancaster, Bailrigg, Lancaster.
LA1 4YR

BEATTIE

unread,
Jun 5, 1985, 10:37:04 AM6/5/85
to
If anyone figures out how to use robots on system V please post.
Tom.

Robert Viduya

unread,
Jun 7, 1985, 3:18:39 PM6/7/85
to
> If anyone figures out how to use robots on system V please post.
> Tom.

Here is a version of the recently posted robots game to run under System V.


robert

--------------------------------------------------------------------------------
#! /bin/sh
# Run the following text with /bin/sh to create:
# Makefile
# robots.6
# robots.c
if test -f 'Makefile'
then
echo "`basename $0`: can't extract" 'Makefile' "- file exists" 1>&2
else
sed 's/^X//' << '--End_of_Makefile--' > 'Makefile'


Xrobots: robots.c
X cc -O robots.c -o robots -lcurses

X
Xinstall: robots
X /etc/install -m 4111 robots /usr/games/robots
X cp robots.6 /usr/man/man6/robots.6


X touch /usr/games/lib/robots_hof
X touch /usr/games/lib/robots_tmp
X
X
Xclean:
X rm -f robots *.o
X
Xlint:
X lint -phbxac robots.c -lcurses -ltermcap > linterrs

--End_of_Makefile--
if test 313 -ne `wc -c < 'Makefile'`
then
echo "`basename $0`: error in" 'Makefile' ": sent 313 chars, received `wc -c < 'Makefile'`" 1>&2
fi
fi
if test -f 'robots.6'
then
echo "`basename $0`: can't extract" 'robots.6' "- file exists" 1>&2
else
sed 's/^X//' << '--End_of_robots.6--' > 'robots.6'

--End_of_robots.6--
if test 2379 -ne `wc -c < 'robots.6'`
then
echo "`basename $0`: error in" 'robots.6' ": sent 2379 chars, received `wc -c < 'robots.6'`" 1>&2
fi
fi
if test -f 'robots.c'
then
echo "`basename $0`: can't extract" 'robots.c' "- file exists" 1>&2
else
sed 's/^X//' << '--End_of_robots.c--' > 'robots.c'


X/* Written by Allan R. Black, Strathclyde University.
X * This program may be freely distributed provided that
X * this comment is not removed and that
X * no profit is gained from such distribution.
X */
X
X/*
X * @(#)robots.c 1.7 3/21/84
X */
X
X/* 1.7a modified by Stephen J. Muir at Lancaster University. */
X
X#include <curses.h>
X#include <signal.h>
X#include <pwd.h>
X#include <ctype.h>

X#include <fcntl.h>
X
X#define MIN_ROBOTS 10
X#define MAX_ROBOTS 500
X#define MIN_VALUE 10
X#define MAX_FREE 3
X
X#define VERT '|'
X#define HORIZ '-'
X#define ROBOT '='
X#define SCRAP '@'
X#define ME 'I'
X#define MUNCH '*'
X#define DOT '.'
X
X#define LEVEL (level+1)
X
X#define MSGPOS 39
X#define RVPOS 51
X
X#define HOF_FILE "/usr/games/lib/robots_hof"
X#define TMP_FILE "/usr/games/lib/robots_tmp"
X
X#define NUMSCORES 20
X#define NUMNAME "Twenty"
X
X#define TEMP_DAYS 7
X#define TEMP_NAME "Week"
X
X#define MAXSTR 100
X
Xextern char *cuserid ();


Xextern struct passwd *getpwnam ();
X
Xstruct scorefile {
X int s_uid;
X int 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
X/*# define ALLSCORES*/
X
X#define SECSPERDAY 86400
X
X#define BEL 007
X#define CTLH 010
X#define CTLJ 012
X#define CTLK 013
X#define CTLL 014
X#define CTLY 031
X#define CTLU 025
X#define CTLB 002
X#define CTLN 016

X#define CTLR 022

X/* don't use tputs
Xint _putchar();
X*/
Xint interrupt();
Xlong time (), lseek ();
Xchar *malloc (), *strcpy (), *strncpy ();
Xvoid perror (), exit ();
X
Xchar *forbidden [] = { "root", "daemon", "uucp", 0 };
X
Xstatic char msgbuf[1000];
X
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];


X{
X register char *x, **xx;
X

X if (argc > 1) {
X if (argv[1][0] == '-') {


X switch(argv[1][1]) {
X case 's':
X scoring(FALSE);
X exit(0);
X }
X }
X }

X if ((x = cuserid ((char *) 0)) == 0 || (pass = getpwnam (x)) == 0) {
X (void) printf ("Who the hell are you?\n");
X exit (1);
X }
X (void) strcpy(whoami,x);


X for (xx = forbidden; *xx; ++xx)
X if (strcmp (whoami, *xx) == 0) {

X (void) printf ("only individuals may play robots\n");
X exit (1);
X }
X seed = (int) time((long *) 0)+pass->pw_uid;
X (void) signal(SIGQUIT,interrupt);
X (void) signal(SIGINT,interrupt);


X initscr();
X crmode();
X noecho();

X for(;;) {
X count = 0;
X running = FALSE;
X adjacent = FALSE;
X last_stand = FALSE;
X if (rnd(free_per_level) < free_teleports) {
X free_per_level++;
X if (free_per_level > MAX_FREE)

X 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 (winch(stdscr) != ' ');


X addch(ME);
X for (;;) {
X scorer();
X if (robots_alive == 0)

X break;


X command();
X robots();
X if (dead)

X munch();
X }
X (void) sprintf (msgbuf, "%d robots are now scrap heaps",max_robots);
X msg();


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

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
Xput_robots()
X{
X register struct robot *r, *end;
X register int x, y;
X
X robot_value += level*5+rnd(level*10);
X max_robots += level*3+rnd(level*5);
X if (max_robots > MAX_ROBOTS)

X max_robots = MAX_ROBOTS;


X robots_alive = max_robots;
X end = &robot_list[max_robots];

X for (r = robot_list; r < end; r++) {
X for (;;) {


X x = rndx();
X y = rndy();
X move(y,x);
X if (winch(stdscr) == ' ')

X break;


X }
X r->x = x;
X r->y = y;
X r->alive = TRUE;
X addch(ROBOT);
X }
X}
X
Xcommand()
X{
X register int x, y;
X

Xretry:
X
X move(my_y,my_x);
X refresh();
X if (last_stand)
X return;

X for (x = new_x-1; x <= new_x+1; x++) {
X for (y = new_y-1; y <= new_y+1; y++) {


X move(y,x);
X if (winch(stdscr) == ROBOT)

X goto teleport;
X }
X }

X free_teleports--;
X }
X break;
X case 's':
X case 'S':
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 }
X else {
X erase_dots();
X dots = 0;
X }
X goto retry;
X case 'q':
X case 'Q':
X quit(FALSE);
X case CTLR:
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)

X (void) putchar(BEL);


X running = FALSE;
X adjacent = FALSE;
X first_move = FALSE;
X }

X else {
X (void) putchar(BEL);


X }
X refresh();
X count = 0;
X goto retry;
X }
X first_move = FALSE;
X mvaddch(my_y,my_x,' ');
X my_x = new_x;
X my_y = new_y;
X move(my_y,my_x);
X if (winch(stdscr) == ROBOT)

X munch();


X mvaddch(my_y,my_x,ME);
X refresh();
X}
X
Xread_com()
X{

X if (count == 0) {


X if (dots) {
X put_dots ();
X move (my_y, my_x);
X refresh ();
X }

X if (isdigit(com = readchar())) {


X count = com-'0';

X while (isdigit(com = readchar()))
X count = count*10+com-'0';


X }
X if (dots)
X erase_dots ();
X }
X if (count > 0)

X count--;


X return(com);
X}
X
Xreadchar()
X{
X static char buf[1];
X
X while(read(0,buf,1) <= 0)

X ;


X return(buf[0]);
X}
X
Xdo_move(dir)

Xchar dir;


X{
X register int x, y;
X
X new_x = my_x+xinc(dir);
X new_y = my_y+yinc(dir);
X move(new_y,new_x);
X switch (winch(stdscr)) {
X case VERT:
X case HORIZ:
X case SCRAP:
X bad_move = TRUE;

X return;
X }
X if (adjacent & !first_move) {
X for (x = new_x-1; x <= new_x+1; x++) {
X for (y = new_y-1; y <= new_y+1; y++) {


X move(y,x);
X switch(winch(stdscr)) {
X case ROBOT:
X case SCRAP:
X bad_move = TRUE;
X return;
X }
X }
X }
X }
X}
X
Xput_dots()
X{
X register int x, y;
X

X for (x = my_x-dots; x <= my_x+dots; x++) {


X if (x < 1 || x > COLS - 2)
X continue;

X for (y = my_y-dots; y <= my_y+dots; y++) {


X if (y < 1 || y > LINES - 3)
X continue;
X move(y,x);
X if (winch(stdscr) == ' ')

X addch(DOT);


X }
X }
X}
X
Xerase_dots()
X{
X register int x, y;
X

X for (x = my_x-dots; x <= my_x+dots; x++) {


X if (x < 1 || x > COLS - 2)
X continue;

X for (y = my_y-dots; y <= my_y+dots; y++) {


X if (y < 1 || y > LINES - 3)
X continue;
X move(y,x);

X if (winch(stdscr) == DOT)
X addch(' ');


X }
X }
X}
X
Xgood_moves()
X{
X register int x, y;
X register int test_x, test_y;
X register char *m, *a;
X static char moves[] = "hjklyubn.";
X static char ans[sizeof moves];
X
X a = ans;

X for (m = moves; *m; m++) {


X test_x = my_x+xinc(*m);
X test_y = my_y+yinc(*m);
X move(test_y,test_x);
X switch(winch(stdscr)) {
X case ' ':
X case ME:

X for (x = test_x-1; x <= test_x+1; x++) {
X for (y = test_y-1; y <= test_y+1; y++) {


X move(y,x);
X if (winch(stdscr) == ROBOT)

X goto bad;


X }
X }
X *a++ = *m;
X }
Xbad: ;
X }
X *a = 0;

X if (ans[0]) {

X end = &robot_list[max_robots];

X for (r = robot_list; r < end; r++) {
X if (r->alive) {


X mvaddch(r->y,r->x,' ');
X }
X }

X for (r = robot_list; r < end; r++) {
X if (r->alive) {


X r->x += sign(my_x-r->x);
X r->y += sign(my_y-r->y);
X move(r->y,r->x);
X switch (winch(stdscr)) {
X case ME:
X addch(MUNCH);
X dead = TRUE;
X break;
X case SCRAP:
X r->alive = FALSE;
X score += robot_value;
X robots_alive--;
X break;
X case ROBOT:

X for (find = robot_list; find < r; find++) {
X if (find->alive) {
X if (r->x == find->x && r->y == find->y) {


X find->alive = FALSE;
X break;
X }
X }
X }
X r->alive = FALSE;
X addch(SCRAP);
X score += robot_value*2;
X robots_alive -= 2;
X break;
X case MUNCH:
X break;
X default:
X addch(ROBOT);
X }
X }
X }
X}
X
Xmunch()
X{
X scorer();

X (void) sprintf (msgbuf, "MUNCH! You're robot food");
X msg();


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)

Xbool eaten;


X{
X move(LINES-1,0);
X refresh();
X endwin();

X (void) putchar('\n');


X scoring(eaten);
X exit(0);
X}
X
Xscoring(eaten)

Xbool eaten;


X{
X static char buf[MAXSTR];
X

X (void) sprintf(buf,"for this %s",TEMP_NAME);
X record_score(eaten,TMP_FILE,TEMP_DAYS,buf);
X (void) printf("[Press return to continue]");
X (void) fflush(stdout);
X (void) gets(buf);


X record_score(eaten,HOF_FILE,0,"of All Time");
X}
X
Xrecord_score(eaten,fname,max_days,type_str)
Xbool eaten;
Xchar *fname;
Xint max_days;

Xchar *type_str;


X{
X int fd;
X int (*action)();

X struct flock fl;
X
X action = signal(SIGINT,SIG_IGN);
X if ((fd = open(fname,2)) < 0) {
X perror(fname);
X }
X else {
X fl.l_type = F_WRLCK;
X fl.l_whence = 0;
X fl.l_start = 0;
X fl.l_len = 0L;
X fl.l_pid = getpid ();
X if (fcntl (fd, F_SETLKW, &fl) < 0) {
X perror(fname);
X }
X else {
X do_score(eaten,fd,max_days,type_str);
X fl.l_type = F_UNLCK;
X (void) fcntl (fd, F_SETLK, &fl);
X }
X (void) close(fd);
X }
X (void) signal(SIGINT,action);
X}
X
Xdo_score(eaten,fd,max_days,type_str)
Xbool eaten;
Xint fd, max_days;
Xchar *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 ? (int) time((long *) 0)/SECSPERDAY : 0;
X limit = this_day-max_days;
X sfile = (struct scorefile *)(malloc((unsigned) FILE_SIZE));


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 (void) read(fd,sfile,FILE_SIZE);
X remove = 0;
X if (score > 0) {


X uid = pass->pw_uid;
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)
X position = remove;


X# ifndef ALLSCORES
X if (remove->s_uid == uid) {
X if (remove->s_days < limit)
X oldest = remove;
X else
X break;
X }
X# endif ALLSCORES
X }
X if (remove < eof) {

X if (position == 0 && remove->s_days < limit)
X position = remove;
X }
X else if (oldest) {
X remove = oldest;
X if (position == 0) {


X position = eof-1;
X }

X else if (remove < position) {
X position--;
X }
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 }

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 (void) lseek(fd,0,0);
X (void) write(fd,sfile,FILE_SIZE);
X (void) close(fd);
X }
X }
X (void) 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 (void) printf("Rank Score Name\n");
X count = 0;
X for (position = sfile; position < eof; position++) {
X if (position->s_score == 0)
X break;
X /* this should be improved
X if (position == this && SO && SE) {
X tputs(SO,0,_putchar);
X }
X */


X if (position->s_days >= limit) {

X (void) printf ("%-6d %-8d %s: %s on level %d.",


X ++count,
X position->s_score,
X position->s_name,
X position->s_eaten ? "eaten" : "chickened out",
X position->s_level
X );
X# ifdef OLDSCORES
X }

X else {
X (void) printf ("**OLD** %-8d %s: %s on level %d.",


X position->s_score,
X position->s_name,
X position->s_eaten ? "eaten" : "chickened out",
X position->s_level
X );
X# endif OLDSCORES
X }

X /* this should be improved
X if (position == this && SO && SE) {
X tputs(SE,0,_putchar);
X }
X */


X# ifndef OLDSCORES
X if (position->s_days >= limit)
X# endif OLDSCORES

X (void) putchar ('\n');


X }
X}
X
Xscorer()
X{
X static char infobuf [6];
X register int x, y;
X
X if ((y = free_teleports-free_per_level) < 0)
X y = 0;
X x = free_teleports-y;

X (void) sprintf(infobuf,"%d+%d",x,y);


X if (y == 0)
X infobuf[1] = '\0';
X move(LINES-1,0);
X clrtoeol();
X printw("<%s> level: %d score: %d",infobuf,LEVEL,score);
X mvprintw(LINES-1,RVPOS,"robots: %d value: %d",robots_alive,robot_value);
X}
X
Xrndx()
X{
X return(rnd(COLS-2)+1);
X}
X
Xrndy()
X{
X return(rnd(LINES-3)+1);
X}
X
Xrnd(mod)
Xint mod;
X{
X if (mod <= 0)

X return(0);


X return((((seed = seed*11109+13849) >> 16) & 0xffff) % mod);
X}
X
Xsign(x)
Xregister int x;
X{
X if (x < 0)

X return(-1);


X return(x > 0);
X}
X

Xmsg()
X{


X mvaddstr(LINES-1,MSGPOS,msgbuf);
X clrtoeol();
X refresh();
X}
X
Xinterrupt()
X{
X quit(FALSE);
X}

--End_of_robots.c--
if test 14968 -ne `wc -c < 'robots.c'`
then
echo "`basename $0`: error in" 'robots.c' ": sent 14968 chars, received `wc -c < 'robots.c'`" 1>&2
fi
fi
exit
--
Robert Viduya 01111000
Georgia Institute of Technology

...!{akgua,allegra,amd,hplabs,ihnp4,masscomp,ut-ngp}!gatech!gitpyr!robert
...!{rlgvax,sb1,uf-cgrl,unmvax,ut-sally}!gatech!gitpyr!robert

Carl Lowenstein

unread,
Jun 13, 1985, 10:22:09 AM6/13/85
to
I wish that the modified sources for SysV had not so many whitespace
changes. It sure makes producing a joint source file for conditional
compilation difficult!

Note that on SysV it is possible that a not-perfect terminfo file can
cause 'robots' to crash. I have found this using the 4425 terminfo that
wandered across the net a while ago. The program dies with an addressing
error while doing 'tputs'. Anyone else with this type of problem?

Background information: I'm using either a VAX750 with 4.2BSD, or a
3B2 with SysVRel2. The 4410 or vt100 terminfo's work reasonably well
with robots, the 4425 terminfo makes it crash. No apparent problems with
termcap on the BSD.


--
carl lowenstein marine physical lab u.c. san diego
{ihnp4|decvax|akgua|dcdwest|ucbvax} !sdcsvax!mplvax!cdl

Robert Viduya

unread,
Jun 15, 1985, 4:38:54 PM6/15/85
to
>
> Note that on SysV it is possible that a not-perfect terminfo file can
> cause 'robots' to crash. I have found this using the 4425 terminfo that
> wandered across the net a while ago. The program dies with an addressing
> error while doing 'tputs'. Anyone else with this type of problem?
>

I've posted a fixed terminfo for the 4425 to net.info-terms and net.sources.

robert

Troy Torgerson

unread,
Jun 19, 1985, 11:15:09 AM6/19/85
to

I also have a problem with the scoreboard for robots. The files exist, and
both have twenty entries. I had to recompile it to change where the files
were and it now only writes to the scorefiles once in a great while.
Anybody have a fix for this (especially the guy who wrote it)???
I don't have time to sit down and hack it to pieces and figure out why it is
doing that, so. . . If someone else could post a fix, I'd be grateful!


Troy Torgerson
udenva!ttorgers

Carl Lowenstein

unread,
Jun 21, 1985, 12:25:55 PM6/21/85
to
In article <7...@udenva.UUCP> ttor...@udenva.UUCP (Troy Torgerson) writes:
>
>I also have a problem with the scoreboard for robots.
> it now only writes to the scorefiles once in a great while.
Note the variable ALLSCORES. If defined, the scorefiles hold the
NUMSCORES highest scores. If not defined (the way the source file came)
the scorefiles hold that many scores for individual users. So it only
writes to the scorefile when you exceed your own previous best score and
there are not 20 people ahead of you with better scores.
Reply all
Reply to author
Forward
0 new messages