#define	RECFIL	"/staff/john/text/chase.rec"
#define	HELPFILE	"/staff/john/text/chase.help"

char ESC[] = { 27 , '=' , ' ' , ' ' };
char *SPACE = "                                                     ";



main(argc,argv)
	int argc;
	char *argv[];
		{
		int consec = 0;
		int m[61][121] , scr[23][80] , r[2][31];
		int contflg , whirlflg = 0;
		register int i , j , c;
		int s,s1,s2,x,r1,c1,c2,i1,i2,j1,j2;
		int  oldr1 , reprnt , m1,r2,i8;
		static int jt[9] = { 5, 1, 4, 7, 8, 9, 6, 3, 2 };
		static int it[9] = { 5, 1, 2, 3, 6, 9, 8, 7, 4 };
		char *cont , *ptr;
		char is , mem[128];
		static char ci[7] = { ' ', 'X', '*', '+', '@', '#', '.' };
		s = s1 = s2 = x = i = j = r1 = c1 = c2 = i1 = i2 = j2 = j1 = 0;
		c = r2 = i8 = 0;
		s = rnd(0);
		if(argc == 2){
			while((is = *(argv[1])++) != 0)s = s * 10 + is - '0';
			goto in1;
			}

		write(1,"\032\n\n			** C H A S E **",21);
		write(1,"\n\n			    V7.0-17\n\n",18);
		write(1,"Use 'chase.old' for large boards (>21) and non-cursor addressing game.\n\n",72);
		write(1,"Try 'chasex' for something new. (Doc in /staff/john/text/chasex.help\n\n",70);
		write(1,"\nDo you need instructions? ",27);
			is = 0;
			while((mem[is++] = getchar()) != '\n');
			if(mem[0] == 'y'){
				if((s1 = open(HELPFILE,0)) == -1)
					write(1,"\nNo help yet.\n\n",14);
				else	{
					while(s = read(s1,mem,12))write(1,mem,s);
					close(s1);
					write(1,"\n\n",2);
					}
				legal();

					}
		sleep(1);

	in:
		write(1,"\032",1);
		write(1,"Maze size (4 to 21)? ",21);
		contflg = 0;
		s = 0;
		while((is = getchar()) != '\n')s = s * 10 + is - '0';

	in1:
		if(s < 4 || s > 21)goto in;
		s1 = s/2;
		s2 = s*2;
		write(1,"\032",1);
		for(i = 0; i < 23;i++){
				for(j = 0; j < 80; j++)scr[i][j] = -1;
		}
		reprnt = 1;

		for(i = 1; i <= s; i++){
			for(x = 1; x <= s2; x++)m[i][x] = 0;
				m[rnd(s)][rnd(s2)] = 100;
				m[i][1] = m[i][s2] = 100;
					}

		for(x = 1; x <= s2; x++)m[1][x] = m[s][x] = 100;
		while(m[(i = rnd(s))][(j = rnd(s2))]);
		m[i][j] = 200;
		x = 0;
		r[0][x] = i;
		r[1][x] = j;
		for(x = 1; x <= s1; x++){
			while(m[(i = rnd(s))][(j = rnd(s2))]);
			m[i][j] = 300 + x;
			r[0][x] = i;
			r[1][x] = j;
					}
		r1 = s1;
		for(x = 1; x <= s1; x++){
			while(m[(i = rnd(s))][(j = rnd(s2))]);
			m[i][j] = 400;
					}
		set(1,50);
		printf("There are %2d robots left.",r1);
		oldr1 = r1;
		sulegal();

	l120:

		set(1,1);


		i1 = j1 = 1;
		i2 = s;
		j2 = s2;


		for(i = i1; i <= i2; i++){
			for(j = j1; j <= j2; j++){
				c = ((m[i][j])/100) + 1;
				if((j == j1 || j == j2 || i == i1 ||
				    i == i2) && c == 1)c = 7;
					if(reprnt == 0)
							if(scr[i-i1][j-j1] != c &&
							  (i != s && j != j1))
								set(i-i1+1,j-j1+1);
							else	goto contlp;

					scr[i-i1][j-j1] = c;
					write(1,&ci[c-1],1);
contlp:;
						}
						if(reprnt)write(1,"\n",1);
							}

		reprnt = 0;

		if(r1 != oldr1){
			oldr1 = r1;
			robots(r1);
		}

	mv:


		i = s < 21 ? s+2 : 22;
		if(contflg){
			mem[0] = 0;
			i8 = m1 = 0;
			goto finlp;
		}
		set(i,1);
		write(1,"Your move? ",11);
		m1 = i8 = 0;
		while((is = getchar()) != '\n')
			mem[i8++] = is;
		mem[i8] = 0;
		if(whirlflg){
			whirlflg = 0;
			set(23,1);
			write(1,"                              ",28);
		}
		cont = "finish";
		ptr = mem;
		while(*ptr == *cont){
			if(*ptr == 0){
				mem[0] = '0';
				mem[1] = 0;
				contflg = 1;
				break;
			}
			ptr++;
			cont++;
		}

		set(i,12);
		write(1,SPACE,i8 > 20 ? 24 : i8 + 4);
finlp:
		i8 = 0;
		switch(mem[0]){
	case	'u':
		switch(mem[1]){
			case	'l':
				m1 = 1;
				break;
			case	'r':
				m1 = 3;
				break;
			case	0:
				m1 = 2;
				break;
			default:
				m1 = 99;
				break;
				}
		break;
	case	'd':
	case	'b':
		switch(mem[1]){
			case	'l':
				m1 = 7;
				break;
			case	'r':
				m1 = 5;
				break;
			case	0:
				m1 = 6;
				break;
			default:
				m1 = 99;
				break;
				}
		break;
	case	'l':
		m1 = 8;
		break;
	case	'r':
		m1 = 4;
		break;
	default:
		while(mem[i8])m1 = m1 * 10 + mem[i8++] - '0';
		break;
	}
		i8 = 0;


		if(m1 == 9){
			write(1,"\032",1);
			set(1,50);
			write(1,"There are    robots left.",25);
			sulegal();
			robots(r1);
			reprnt = 1;
			goto l120;
		}

		if(m1*(8-m1) < 0 || m1 < 0){
			set(23,1);
			write(1,"Illegal move: retype",20);
			whirlflg = 1;
			goto mv;
					}

		i = r[0][0] + (((it[m1] - 1)/3) - 1);
		j = r[1][0] + (((jt[m1] - 1)/3) - 1);
		x = 0;

	l155:
		m1 = (m[i][j]/100);
		if(m1 == 2 || m1 == 0){
			m[r[0][0]][r[1][0]] = 0;
			m[i][j] = 200;
			r[0][x] = i;
			r[1][x] = j;
			goto rob;
					}

		if(m1 != 4)write(1,"\032",1);
			else	set(s+3,1);

		switch(m1){
			case	1:
				write(1,"Hey genius!  You touched the ",29);
				write(1,"fence!!!!!\n***** ZAP ***** ",28);
				write(1,"You're dead!!!\n",15);
				goto en;

			case	3:
				write(1,"Right into the hands of a waiting ",34);
				write(1,"robot, just your luck!\n",23);
				goto en;

			case	4:
				set(23,1);
				write(1,"You have entered a whirlpool",28);
				i = rnd(s);
				j = rnd(s2);
				whirlflg = 1;
				goto l155;

			case	5:
				write(1,"You have run into a radioactive ",32);
				write(1,"pile.\n",6);
				write(1,"May you sizzle in peace!!\n",26);
				goto en;

			default:
				write(2,"\n??? Error in person move switch.\n",34);
				exit(127);

						}

	rob:
		for(x = 1; x <= s1; x++){
			if(r[0][x] == 0)continue;
			i = r[0][0] - r[0][x];
			j = r[1][0] - r[1][x];
			i = r[0][x] + sg(i);
			j = r[1][x] + sg(j);

	l210:
			m1 = (m[i][j]/100);
			if(m1 == 0){
				m[r[0][x]][r[1][x]] = 0;
				m[i][j] = 300 + x;
				r[0][x] = i;
				r[1][x] = j;
				continue;
					}

	l230:
			if(m1 == 1){
	l231:
				r1--;
				m[r[0][x]][r[1][x]] = 0;
				r[0][x] = 0;
				continue;
				}
			if(m1 == 2){
				write(1,"\032",1);
				write(1,"*** You have been destroyed by a lucky ",39);
				write(1,"robot ***\nYou lose!!!\n",22);
				goto en;
				  }

			if(m1 == 3){
				r2 = m[i][j] - 300;
				r1--;
				r1--;
				m[r[0][x]][r[1][x]] = 0;
				m[r[0][r2]][r[1][r2]] = 500;
				r[0][x] = r[0][r2] = 0;
				continue;
					}

			if(m1 == 4){
				i = rnd(s);
				j = rnd(s2);
				if(m[i][j] != (x + 300))goto l210;
				continue;
					}

			if(m1 == 5){
				goto l231;
				   }

			write(1,"\n??? Error at robot move `if' block.\n",37);
			exit(127);


				}


		if(r1 > 0)goto l120;
		++consec;
		sleep(1);
		write(1,"\032",1);
		printf("You win!!!\n\nYou have won %d consecutive game%c.\n\n",
			consec , consec == 1 ? 0 : 's');
		goto skpen;
	en:
		consec = 0;
	skpen:
		write(1,"Do you want to play again? ",27);
		is = 0;
		while((mem[is++] = getchar()) != '\n');
		if((mem[0] | 32) != 'n')goto in;
		if((x = open(RECFIL,0)) == -1)exit(0);
		s = 0;
		read(x,&s,2);
		s1 = read(x,mem,80);
		close(x);
		mem[s1] = 0;
		printf("\nThe record for most consecutive games won is %d by:\n%s\n\n",s,mem);
		if(consec > s){
			if((x = open(RECFIL,1)) == -1)exit();
			write(1,"\nBut, you broke that record.\n",29);
			seek(x,0,0);
			write(x,&consec,2);
			for(s = 0; s < 81; mem[s++] = 0);
			write(1,"Input your name: (80 char max.)\n",32);
			s = 0;
			while((is = getchar()) != '\n')if(s < 80)mem[s++] = is;
			write(x,mem,80);
			close(x);
				}
	}


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

	getanother:
			f = (rand())/10000.;
			y = f;
			if(y == 3)goto getanother;
			return(((f-y)*x)+1);
		}

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


legal(){
	write(1,"\032",1);
	write(1,"\n\nValid moves are designated as follows:\n\n",42);
	write(1,"	1 2 3		ul u ur\n",16);
	write(1,"	8 * 4		 l * r\n",15);
	write(1,"	7 6 5		bl b br\n\n",17);
	write(1,"Where you are the asterisk (*).  Zero (0) means ",48);
	write(1,"no move.\n\n",10);
	write(1,"\nTo get a new board, type 9 <RETURN>\n\n",38);
	sleep(5);
	write(1,"\032",1);
	}



set(x,y)
	int x,y;
		{
			ESC[2] = (char) (31 + x);
			ESC[3] = (char) (31 + y);
			write(1,ESC,4);
		}



robots(x)
	int x;
		{
			if (x > 1){
				set(1,60);
				printf("%2d",x);
				return;
			}
			set(1,56);
			write(1,"is  1 robot left.   ",20);
			return;
}

sulegal(){

	set(5,56);
	write(1,"1  2  3",7);
	set(6,56);
	write(1,"8  *  4",7);
	set(7,56);
	write(1,"7  6  5",7);
	set(11,56);
	write(1,"ul u ur",7);
	set(12,56);
	write(1,"l  *  r",7);
	set(13,56);
	write(1,"dl d dr",7);
	set(18,56);
	write(1,"0 = No move",11);
	set(19,56);
	write(1,"9 = New board",13);
	set(21,56);
	write(1,"finish = Play out",17);
}

