#define RECFIL  "/staff/john/text/robots.rec"
#define NROB    16
	struct  {
		unsigned short num;
		long when;
		char who[9];
	} rec;


	struct  {
		char is , os;
		char er , kl;
		int mode;
	}ttys;



int     m[24][73] , rob[2][31];

int     jt[] = { 5  ,  1  ,  4  ,  7  ,  8  ,  9  ,  6  ,  3  ,  2 };
int     it[] = { 5  ,  1  ,  2  ,  3  ,  6  ,  9  ,  8  ,  7  ,  4 };
int     error = 0;

char    escseq[] = {27 , '=' , ' ' , ' '};
int     speed = 0;
int     diff;


#define CLEAR   write(1,"\032",1)

main(cn,vs)
char **vs;
{
	register i , j , x;

	int r , m1 , h , v , r2 , consec;
	char c;

	diff = 2;
	if(cn == 2) {
		diff = 0;
		vs++;
		while(**vs >= '0' && **vs <= '9')
			diff = diff*10 + (*(*vs)++) - '0';
			if(diff < 0 || diff > 5) {
				write(1,"Illegal difficulty\n",19);
				exit(1);
			}
	}
	nice(3);
	ttyset(0);

restart:
	CLEAR;
	rnd(0);
	speed = 0;
	for(i = 1; i < 24; i++){
		for(j = 1; j < 73; j++){
			m[i][j] = 0;
			m[1][j] = m[23][j] = 100;
		}
	m[i][1] = m[i][72] = m[rnd(23)][rnd(72)] = 100;
	}

	while(m[i = rnd(23)][j = rnd(72)]);
	m[i][j] = 200;
	rob[0][0] = i;
	rob[1][0] = j;
	r = NROB;
	for(x = 1; x <= r; x++){
		while(m[i = rnd(23)][j = rnd(72)]);
		m[i][j] = 300+x;
		rob[0][x] = i;
		rob[1][x] = j;
		while(m[i = rnd(23)][j = rnd(72)]);
		m[i][j] = 400;
	}

	for(i = 1; i < 24; i++){
		if(i == 1 || i == 23)set(i,1);
		for(j = 1; j < 73; j++){
			if(i == 1 || i == 23)
				write(1,"X",1);
			else
				if((c = " X*+@#"[m[i][j]/100]) != ' ') {
					set(i,j);
					write(1,&c,1);
				}
		}
	}
	set(1,74);
	write(1,"1 2 3",5);
	set(2,74);
	write(1,"8 * 4",5);
	set(3,74);
	write(1,"7 6 5",5);

	rcnt(r);
	set(rob[0][0],rob[1][0]);
	write(1,"",3);
	sleep(4);
	for( ;; ) {
		for(x = 1; x <= NROB; x++){
			if((( x % (1 << diff))+speed) == 0 && r > 4)sleep(1);
			if(!empty(0))
				mov();
			if(error){
				consec = 0;
				goto en;
			}

			if(rob[0][x] == 0)continue;
			i = rob[0][0] - rob[0][x];
			j = rob[1][0] - rob[1][x];
			i = rob[0][x] + sg(i);
			j = rob[1][x] + sg(j);

whirl:
			m1 = m[i][j]/100;
			clr(rob[0][x],rob[1][x]);
			if(m1 == 0)mover(i,j,x);
			else    if(m1 == 1 || m1 == 5){
					r--;
					rcnt(r);
					rob[0][x] = 0;
				}
				else    if(m1 == 2){
						CLEAR;
						write(1,"*** You have been destroyed by a lucky ",39);
						write(1,"robot ***\n\rYou lose !!!\n",24);
						consec = 0;
						goto en;
					}
					else    if(m1 == 3){
							r2 = m[i][j] - 300;
							r--;
							r--;
							rcnt(r);
							m[i][j] = 500;
							rob[0][x] = rob[0][r2] = 0;
							set(i,j);
							write(1,"#",1);
						}
						else    if(m[i = rnd(23)][j = rnd(72)] != x + 300)
								goto whirl;
		}
		if(r == 0)break;
	}
	CLEAR;
	consec++;
	write(1,"You Win!!!\n\n\r",13);
	printf("You have won %d consecutive game%c.\n\n\r",consec,consec == 1 ? 0 : 's');
	record(-1);
en:
	write(1,"\r\nPlay again? ",14);
	ttyset(2);
	read(0,&c,1);
	if(((c & 0177) | 32) != 'n') {
		error = 0;
		goto restart;
	}
	record(consec);
	ttyset(1);
	exit(1);
}



mover(h,v,n)
	register h , v , n;
		{
			m[h][v] = 300 + n;
			rob[0][n] = h;
			rob[1][n] = v;
			set(h,v);
			write(1,"+",1);
	}

clr(h,v)
	register h,v;
		{
			m[h][v] = 0;
			set(h,v);
			write(1," ",1);
	}

mov(){
	register c , i , j;
	char cc;

	cc = 0;
	while(!empty(0))
		read(0, &cc, 1);
	c = cc & 0177;
	if(c == 0 || c == 3 || c == 4 || c == 127)
		ttyset(1);
	c =- '0';
	if(c < 1 || c > 8){
		if(c == 22)speed = 1;
		return;
	}

	write(1,"",1);
	i = rob[0][0];
	j = rob[1][0];
	clr(i,j);
	i =+ (((it[c]-1)/3)-1);
	j =+ (((jt[c]-1)/3)-1);
redo:
	c = m[i][j]/100;
	if(c == 0){
		m[rob[0][0] = i][rob[1][0] = j] = 200;
		set(i,j);
		write(1,"*",1);
	}

	else    if(c == 4){
			i = rnd(23);
			j = rnd(72);
			set(i,j);
			write(1,"",3);
			sleep(3);
			goto redo;
		}
		else    {
			CLEAR;
			if(c == 1)write(1,
		"Hey genius!  You touched the fence!!!!!\n\r***** ZAP ***** You're dead!!!\r\n",74);
			else    if(c == 3)write(1,
		"Right into the hands of a waiting robot, just your luck!\n\r",58);
				else    write(1,
		"You have run into a radioactive pile.\n\rMay you sizzle in peace!!\n\r",66);
		error = 1;
		}

}


set(i,j)
	register i , j;
		{
		escseq[2] = 31 + i;
		escseq[3] = 31 + j;
		write(1,escseq,4);
}


rnd(x)
	int x;
		{
			short tvec[2];
			int y;
			float f;
			if(x == 0){
				time(tvec);
				tvec[1] =+ (getpid() + getppid());
				srand(tvec[1]);
				return(0);
				}

			return((rand() % x) + 1);
		}

sg(x)
	register int x;
		{
			register int y;
			y = x;
			x = ((x > 0) ? 1 : -1);
			if(y == 0)x = 0;
			return(x);
		}


ttyset(status)
int status;
{
	if(status == 1){
		stty(0,&ttys);
		write(1,"\n\n",2);
		exit(0);
	}
	if(status == 0)
		gtty(0,&ttys);
	status = ttys.mode;
	ttys.mode = (ttys.mode | 040) & ~010;
	stty(0,&ttys);
	ttys.mode = status;
}


rcnt(r)
register r;
{
	set(23,75);
	printf("%2d",r);
}


record(x)
int x;
{
	int fd;
	register char *s , *t , *h;
	char *logdir() , *logname() , *ctime();

	if((fd = open(RECFIL,2)) == -1){
		write(2,"No recordfile open - ERROR\n",27);
		return(1);
	}
	lseek(fd, diff*(sizeof rec), 0);
	read(fd,&rec,sizeof rec);
	if(x != -1)printf("\n\n\n\rThe record for most consecutive games at difficulty level ");
	else    printf("Record at level ");
	printf("%d is%s",diff,x == -1 ? ": " : "\n\r");
	printf("%u game%c%c",rec.num,
		rec.num == 1 ? 0 : 's' , x == -1 ? '.' : ',');
	if(x != -1)printf(" by \"%s\" on %s",rec.who,ctime(&rec.when));
	printf("\n\r\n");

	if(x == -1){
		close(fd);
		return;
	}
	if(rec.num < x) {
		printf("But you broke that record with %d games.\n\r\n",x);
		lseek(fd, -(long)(sizeof rec), 1);
		rec.num = x;
		time(&rec.when);
		s = rec.who;
		t = logdir();
		h = t;
		while(*t)if(*t++ == '/')h = t;
		if(*h == 0)h = logname();
		while(*s++ = *h++);
		write(fd,&rec,sizeof rec);
	}
	close(fd);
}
