
#define	HELPFILE	"/staff/john/text/kismet.help"
#define	LOGFILE		"/staff/john/text/kismet.log"
#define	RECFILE		"/staff/john/text/kism.rec"

	struct rec {
		short tm[2];
		int sco;
		char name[50];
		}rec;
	struct majent	{
		char who[14];
		long tim;
		int score;
		};
struct majent ent;
struct majent high;



char	*ESCSEQ = "\033=  ";
char	*EQLS = "============================================";
char	*SPACE =
 "                                                                            ";

int	inplen = 0;
int	errlen = 0;

int	btot = 0 ,
	ktot = 0 ,
	gtot = 0 ,
	bnus = 0 ;
int	oldbtot = -1 ,
	oldktot = -1 ,
	oldgtot = -1 ,
	oldbnus = -1 ;



char	disp[5];

char	*cat[15] = {
		"Aces" , "Dueces" , "Treys" , "Fours" , "Fives" , "Sixes" ,
		"2-Pair" , "3-of-a-kind" , "Straight" , "Flush" ,
		"Full-house" , "Full-house-same-color" , "4-of-a-kind" ,
		"Yarborough" , "*KISMET*"
			};



int	score[15] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};

int	mask[6] = { 1, 2, 4, 8, 16, 32};

char	num[3] = {' ' , '0' , ' '};







main(argc,argv)
	char *argv[];
	int argc;
		{
	register int i , j , k;
	int rol , proc , retcod;
	int intr();
	char c , c1 , buf[512];


	write(1,"\032",1);
	write(1,"\n\n*KISMET V3.2-23*\n\n",20);
	if(argc > 1){
		log(argc,argv[1]);
		exit(0);
		     }

	write(1,"Do you need a list of instructions (about 2 pages)? ",52);
	c1 = 0;
	while((c = getchar()) != '\n')if(c1 == 0)c1 = c;
	if((c1 | 32) == 'y'){
		if((i = open(HELPFILE,0)) != -1){
			while(j = read(i,buf,64))write(1,buf,j);
			write(1,"\n\n",2);
			close(i);
									    }
		else	write(1,"\nSorry, no help is available now.\n\n",35);
			}
	i = 0;
	signal(1,intr);
	signal(2,intr);
	signal(3,intr);
	rnd(0);
	setup();

lp:
	total();
	if(i++ == 15){
		record(gtot);
		exit(0);
		     }

	roll(31);
	rol = 0;
reroll1:
	if(getdice(0) == 0)goto categy;
	rol++;
reroll2:
	if(getdice(1)){
		write(1,"\n",1);
		rol++;
		gotorc(21,1);
		if(i == 15){
			signal(1,1);
			signal(2,1);
			signal(3,1);
		}			/* For wise guys... */
		prtrol();
			}
categy:
	gotorc(22,11);
	write(1,SPACE,inplen);
	gotorc(22,11);
	j = 0;
	if(i == 15 &&
		(disp[0] != disp[1] || disp[0] != disp[2] || disp[0] != disp[3] ||
		 disp[0] != disp[4] || score[14] < 1)){
		for(k = 0; k < 15; k++)if(score[k] == -1){
			write(1,cat[k],len(cat[k]));
			write(1,"\n",1);
			goto found;
							}
		write(1,"Error in assume.\n",17);
		exit(1);
		   }
	while((c = getchar()) != '\n')
		buf[j++] = c;
	inplen = j;
	buf[j] = 0;
	if(j == 0)goto categy;
	if(errlen){
		write(1,SPACE,errlen);
		errlen = 0;
	}

	if(buf[0] == '!'){
		write(1,"\032",1);
		if((proc = fork()) == 0){
			execl("/bin/sh","sh","-c",&buf[1],0);
			exit(1);
		}
		signal(1,1);
		signal(2,1);
		signal(3,1);
		while((k = wait(&retcod)) != proc && k != -1);
		signal(1,intr);
		signal(2,intr);
		signal(3,intr);
		sleep(3);
		goto shback;
	}


	gotorc(23,1);
	if(eql(buf,"fix") == 0){
shback:
		setup();
		cleanup();
		scoreup();
		goto categy;
	}

	if(eql(buf,"back") == 0){
		if(rol > 1){
			write(1,"You have already used your two rolls.\n",38);
			errlen = 37;
			goto categy;
		}
		write(1,"Back to your ",13);
		if(rol == 0)write(1,"first",5);
		else	    write(1,"last",4);
		write(1," roll.\n",7);
		errlen = 24;
		gotorc(21,1);
		write(1,SPACE,14);
		if(rol == 0)goto reroll1;
		goto reroll2;
	}

	if(j == 1){
		if((k = buf[0] - '0') < 1 || k > 9){
bad:
			goto redo;
							}
		k--;
		}
	else
		{
			for(k = 0; k < 15; k++){
				if(eql(buf,cat[k]) == 0){
					if(j < 10 && k == 10){
						if(score[10] != -1){
							k = 11;
							goto found;
									}
						if(score[11] != -1)goto found;
						write(1,"Ambiguous.\n",11);
						errlen = 10;
						goto categy;
							     }
					goto found;
							}
						}
			if(j > 2 || (buf[0] != '0' && buf[0] != '1') ||
				(buf[1] < '0' || buf[1] > '5'))goto bad;

			if(buf[0] == '1')
				k = 10;
			else	k = 0;
			k += buf[1] - '1';
		}


found:
	if((score[k] != -1 && k < 14) || (k == 14 && score[14] == 0)){
		write(1,"You already used '",18);
		write(1,cat[k],len(cat[k]));
		write(1,"'\n",2);
		errlen = 19 + len(cat[k]);
redo:
		goto categy;
			  }

	if((j = isok(k+1)) == -1){
		if(k == 14 && score[14] != -1){
			write(1,"You don't have a supplemental '*KISMET*'.  Choose again.\n",57);
			errlen = 56;
			goto redo;
				}

		write(1,"You don't have a '",18);
		write(1,cat[k],len(cat[k]));
		write(1,"'.  Do you want a zero? ",24);
		errlen = 47 + len(cat[k]);
		if(i == 15){
			write(1,"yes\n",4);
			score[k] = 0;
			goto lp;
			   }
		c1 = 0;
		while((c = getchar()) != '\n')if(c1 == 0)c1 = c;
		j = 0;
		if((c1 | 32) == 'y'){
			score[k] = 0;
			if(k < 6)gotorc(k+3,17);
			else	gotorc(k-3,75);
			write(1,"  0",3);
			cleanup();
			}
		else goto redo;
		   }
	i =- j;
	goto lp;
	}





roll(x)
	int x;
		{
			register int i;
			for(i = 0; i < 5; i++)
				if(x & mask[i])disp[i] = rnd(6);
		}





prtrol(){
	register int i;
	for(i = 0; i < 5; i++){
		num[1] = disp[i] + '0';
		write(1,num,3);
	}
}


getdice(which)
	int which;
{
	char c;
	register int dice;
	gotorc(15+which*3,1);
	prtrol();

inp:
	dice = 0;
	gotorc(15+which*3,55);
	while((c = getchar()) != '\n'){
		if(((c =| 32) < 'a' || c > 'e') && c != '?'){
			if(c != ' ' && c != ',')dice =| 8192;
			continue;
	    }

		dice =| mask[c-'a'];
				}

		if(dice & 8192){
			gotorc(23,1);
			write(1,"Illegal character in input.  Retype.",36);
			errlen = 36;
			goto inp;
		}
	if(dice == 0)return(0);
	roll(dice);
	return(1);
	}



eql(s,t)
	char *t , *s;
		{
			while((*s | 32) == (*t | 32) && *s){
				t++;
				s++;
							   }
			return(*s);

		}


len(s)
	char *s;
		{
			char *t;
			t = s;
			while(*s++);
			return(s-t-1);
		}





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

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



isok(x)
	int x;
		{
			register int j , scor , i;
			int n[6] , tot , flg;
			tot = 0;
			for(i = 0; i < 6; i++)n[i] = 0;
			for(i = 0; i < 5; i++){
				n[disp[i]-1]++;
				tot =+ disp[i];
					      }

			flg = scor = 0;

			switch(x){
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
	case 6:
		scor = n[x-1]*x;
		break;

	case 7:
		for(i = 0; i < 6; i++){
			for(j = 0; j < 6; j++){
				if((j != i && n[i] > 1 && n[j] > 1) || n[i] > 3)scor = tot;
						}
					}
		break;

	case 8:
		for(i = 0; i < 6; i++)if(n[i] > 2)scor = tot;
		break;

	case 9:
		if(n[1] == 1 && n[2] == 1 && n[3] == 1 && n[4] == 1)scor = 30;
		break;

	case 10:
		ck1:
			if(n[0] + n[5] == 5 || n[1]+n[4] == 5 || n[2]+n[3] == 5)scor = 35;
			if(flg)goto back1;
		break;

	case 11:
		ck:
			for(i = 0; i < 6; i++){
				for(j = 0; j < 6; j++){
					if((i != j && n[i] > 1 && n[j] > 2) || n[i] > 4)scor = tot + 15;
							}
						}
			if(flg)goto back;
		break;

	case 12:
		flg = 1;
		goto ck;
		back:
			if(scor){
				scor = 0;
				goto ck1;
				}
			back1:
				if(scor)scor = tot + 20;
		break;
	case 13:
		for(i = 0; i < 6; i++)if(n[i] > 3)scor = tot + 25;
		break;

	case 14:
		scor = tot;
		break;

	case 15:
		for(i = 0; i < 6; i++)if(n[i] == 5)scor = tot + 50;
		break;

	default:
		write(1,"Error.\n",7);
		exit(1);
		break;

	}

	if(scor == 0)return(-1);
	i = 0;
	if(x == 15 && score[14] != -1){
		i = 1;
		score[14] =+ scor;
				}
	else	score[x-1] = scor;
	if(x < 7){
		gotorc(x+2,16);
		btot =+ scor;
	}
	else	{
		gotorc(x-4,74);
		ktot =+ scor;
	}

	if(x == 15)scor = score[14];
	write(1,"   ",(scor < 10) + (scor < 100) + 1);
	writes(scor);
	cleanup();
	return(i);
	}


writes(x)
	int x;
		{
			char buf[8] , *p;
			register int i;
			buf[7] = 0;
			p = &buf[6];
			i = x;
			while(i){
				*p-- = i%10 + '0';
				i =/ 10;
				}

			if(x == 0)*p-- = '0';
			p++;
			write(1,p,&buf[7]-p);
		}










record(x)
	int x;
		{
			register char *t;
			char *s , *logdir() , *logname();
			register char c;

			register int i;

			int fd;
			struct	{
				char who[14];
				long histime;
				int  hisscore;
					}uent;
			cleanup();
			gotorc(13,1);
			for(i = 0; i < 3; i++){
				write(1,SPACE,7);
				write(1,"\n",1);
				write(1,SPACE,14);
				write(1,"\n",1);
				write(1, SPACE, 14 + (i < 2 ? 39 : 0));
				write(1,"\n",1);
			}

			write(1,SPACE,10);
			gotorc(15,1);

			if((fd = open(LOGFILE,1)) != -1){
				lseek(fd, 0L, 2);
				s = t = logdir();
				while(*t)if(*t++ == '/')s = t;
				t = uent.who;
				if(*s == 0)	/* '/' home dir */
					s = logname();
				while((*t = *s) && t <= &uent.who[13])s++,t++;
				while(t <= &uent.who[13])*t++ = ' ';
				time(&uent.histime);
				uent.hisscore = x;
				write(fd, &uent, sizeof uent);
				close(fd);
				}

			if((fd = open(RECFILE,2)) == -1)return;
			if(read(fd, &rec, sizeof rec) != sizeof rec){
				endup:

					close(fd);
					write(1,"\n\n",2);
					return;
							}

			write(1,"\n\nThe record for highest score is: ",35);

			writes(rec.sco);
			write(1,", by\n",5);
			write(1,rec.name,len(rec.name));
			write(1," on ",4);
			write(1,ctime(rec.tm),25);
			if(x > rec.sco){
				write(1,"\n\nBut you broke that record.\n\n",30);
				write(1,"Enter your full name (to appear in the record file): ",53);
				i = 0;
				while((c = getchar()) != '\n')if(i < 49)rec.name[i++] = (c >= 'a' && c <= 'z') ? (c & ~32) : c;
				while(i < 50)rec.name[i++] = 0;
				rec.sco = x;
				time(rec.tm);
				lseek(fd, 0L, 0);
				write(fd,&rec,54);
					}
				else	mostus();

				goto endup;
		}
intr(){
	write(2,"\032\n\n",3);
	write(2,"\nInterrupt -- Game spoiled.\n\n",29);
	exit(1);
	}

log(x,s)
	char *s;
	int x;
		{

	register int fd , lim;
	register int nu = 0;
	long ttl = 0L;

	if((fd = open(LOGFILE,0)) != -1){
	lim = 350;
	while(*s && *s != '=')s++;
	if(*s++){
		lim = 0;
		while(*s)lim = lim * 10 + (*s++) - '0';
		if(lim < 0 || lim > 1000)lim = 350;
		}
	if(x == 2){
		write(1,"\n\n Who                         Time               Score\n",56);
		write(1,"==============     ========================     =====\n",54);
		}
		lseek(fd, -(long)(sizeof ent), 2);
		while(read(fd,&ent,sizeof ent) == sizeof ent){
		if(x == 2 && ent.score >= lim){
			write(1,ent.who,14);
			write(1,"     ",5);
			write(1,ctime(&ent.tim),24);
			write(1,"     ",5);
			writeit(ent.score);
			write(1,"\n",1);
			}
			nu++;
			ttl =+ ent.score;
			if(lseek(fd, -2L*(sizeof ent), 1) == -1)break;
									}
		close(fd);
		write(1,"\nAverage score:",15);
		writeit((int)(ttl/nu));
		write(1,"\n\n",2);
								}

}

writeit(x)
	int x;
		{
			register int i;
			register char *p;
			char tmp[16];

			p = &tmp[13];
			i = x;
			while(i)
				{
				*--p = i%10 + '0';
				i =/ 10;
				}

			if(x == 0)*--p = '0';
			while(p > &tmp[8])*--p = ' ';
			write(1,p,5);
}


setup(){
	register int i , j;
	char c;

	write(1,"\032Category List:\n\n",17);
	for(i = 0; i < 9; i++){
		if(i < 6){
			c = i + '1';
			write(1,&c,1);
			gotorc(3+i,9);
			write(1,cat[i],len(cat[i]));
			gotorc(3+i,17);
			write(1,"---",3);
		}
		gotorc(i+3,41);
		j = i + 6;
		write(1,j > 8 ? "1" : " ",1);
		c = (j+1) % 10 + '0';
		write(1,&c,1);
		gotorc(i+3,49);
		write(1,cat[j],len(cat[j]));
		gotorc(j-3,72);
		write(1,"   ---\n",7);
		}
		gotorc(9,1);
		write(1,EQLS,20);
		write(1,"\nBasic Section:  ",17);
		write(1,"\n        Bonus:  ",17);
		gotorc(12,41);
		write(1,EQLS,37);
		gotorc(13,59);
		write(1,"Kismet Section:",15);
		gotorc(14,60);
		write(1,"Basic Section:",14);
		gotorc(15,68);
		write(1,"Bonus:",6);
		gotorc(16,68);
		write(1,"Total:",6);

		gotorc(13,1);
		for(i = 1; i < 4; i++){
			write(1,"Roll ",5);
			writes(i);
			write(1,":\n A  B  C  D  E\n               ",32);
			if(i == 3){
				write(1,"\n",1);
				break;
			}

			write(1,"Which dice do you wish to be rethrown? \n",40);
		}
		write(1,"Category?",9);
	}

gotorc(r,c)
	char r,c;
		{
		ESCSEQ[2] = 31 + r;
		ESCSEQ[3] = 31 + c;
		write(1,ESCSEQ,4);
	}


cleanup(){
	if(errlen){
		gotorc(23,1);
		write(1,SPACE,errlen);
		errlen = 0;
	}
	gotorc(18,1);
	write(1,SPACE,14);
	gotorc(21,1);
	write(1,SPACE,14);
	gotorc(22,11);
	write(1,SPACE,14);
	gotorc(15,55);
	write(1,SPACE,9);
	gotorc(18,55);
	write(1,SPACE,9);
	}


total(){
	if(oldbtot != btot){
		gotorc(10,17);
		write(1,SPACE,(btot < 100) + (btot < 10));
		writes(btot);
		gotorc(14,75);
		write(1,SPACE,(btot < 100) + (btot < 10));
		writes(btot);
		oldbtot = btot;
	}

	bnus = 0;
	if(btot > 77)bnus = 75;
	else	if(btot > 70)bnus = 55;
		else	if(btot > 62)bnus = 35;
	if(oldbnus != bnus){
		gotorc(11,18);
		if(bnus == 0)write(1,SPACE,1);
		writes(bnus);
		gotorc(15,76);
		if(bnus == 0)write(1,SPACE,1);
		writes(bnus);
		oldbnus = bnus;
	}
	if(oldktot != ktot){
		gotorc(13,75);
		write(1,SPACE,(ktot < 100) + (ktot < 10));
		writes(ktot);
		oldktot = ktot;
	}

	gtot = btot + bnus + ktot;
	if(gtot != oldgtot){
	gotorc(16,75);
	write(1,SPACE,(gtot < 100) + (gtot < 10));
	writes(gtot);
	oldgtot = gtot;
	}


}

scoreup(){
	register int i;
	for(i = 0; i < 15;i++){
		if(score[i] == -1)continue;
		if(i < 6)gotorc(i+3,16);
		else gotorc(i-3,74);
		write(1,SPACE,(score[i] < 100) + (score[i] < 10) + 1);
		writes(score[i]);
	}
	oldbtot = oldktot = oldgtot = oldbnus = -1;
	total();
	gotorc(21,1);
	prtrol();
}



mostus(){
	register int max = 0;
	register char *t , *s;
	int i;
	int fd;
	if((fd = open(LOGFILE,0)) == -1)return(0);
	while(read(fd,&ent,sizeof ent) == sizeof ent){
		if(ent.score > max){
			high.score = max = ent.score;
			high.tim = ent.tim;
			s = high.who;
			t = ent.who;
			for(i = 0; i < 14; i++)*s++ = *t++;
		}
	}
	close(fd);

	write(1,"\n\nThe record for highest game this session is: ",47);
	writes(max);
	write(1,", by \"",6);
	s = high.who;
	while(*s != ' ' && s <= &high.who[13])s++;
	*s = 0;
	write(1,high.who,s-high.who);
	write(1,"\" on\n",5);
	write(1,ctime(&high.tim),25);
	return(1);
}



