[net.sources.games] Robots game for 4.2 BSD

stephen@dcl-cs.UUCP (Stephen J. Muir) (05/28/85)

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:	stephen@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

twb@hoqam.UUCP (BEATTIE) (06/05/85)

If anyone figures out how to use robots on system V please post.
Tom.

robert@gitpyr.UUCP (Robert Viduya) (06/07/85)

> 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'
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.
--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
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
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    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':
Xteleport:
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)
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	a = ans;
X    }
X    else {
X	a = "Forget it!";
X    }
X    mvprintw(LINES-1,MSGPOS,"%*.*-s",RVPOS-MSGPOS,RVPOS-MSGPOS,a);
X}
X
Xxinc(dir)
Xchar	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)
Xchar 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
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

cdl@mplvax.UUCP (Carl Lowenstein) (06/13/85)

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@gitpyr.UUCP (Robert Viduya) (06/15/85)

> 
> 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
-- 
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

ttorgers@udenva.UUCP (Troy Torgerson) (06/19/85)

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

cdl@mplvax.UUCP (Carl Lowenstein) (06/21/85)

In article <716@udenva.UUCP> ttorgers@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.

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