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

	struct	{
		int tm[2];
		int sco;
		char name[50];
		}rec;



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;
	int intr();
	char c , c1 , buf[64];


	write(1,"\n\n*KISMET V2.2-09*\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);

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

	write(1,"\nHere is your roll:\n",20);
	roll(31);
	prtrol();
	rol = 0;
reroll1:
	if(getdice() == 0)goto categy;
	rol++;
reroll2:
	if(getdice()){
		write(1,"\n",1);
		rol++;
			}
categy:
	write(1,"Category? ",10);
	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')if(c != ' ' && c != 9)buf[j++] = c;
	buf[j] = 0;
	if(j == 0)goto categy;
	if(eql(buf,"back") == 0){
		if(rol > 1){
			write(1,"You have already used your two rolls.\n",38);
			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);
		prtrol();
		if(rol == 0)goto reroll1;
		goto reroll2;
	}

	if(j == 1){
		if((k = buf[0] - '0') < 1 || k > 9){
bad:
			categ();
			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);
						goto categy;
							     }
					goto found;
							}
						}
			if(j > 2 || (buf[0] != '0' && buf[0] != '1') ||
				(buf[1] < '0' || buf[1] > '5'))goto bad;

			k = 10*(buf[0] == '1') + 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);
redo:
		prtrol();
		write(1,"\n",1);
		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);
			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);
		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;
		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;
	write(1," A  B  C  D  E \n",16);
	for(i = 0; i < 5; i++){
		num[1] = disp[i] + '0';
		write(1,num,3);
				}
	}


getdice(){
	char c;
	register int dice;

inp:
	write(1,"Which dice do you wish to be rethrown? ",39);
	dice = 0;
	while((c = getchar()) != '\n'){
		if(((c =| 32) < 'a' || c > 'e') && c != '?'){
			if(c != ' ' && c != ',')dice =| 8192;
			continue;
							    }

		if(c == '?'){
			while((c = getchar()) != '\n');
			categ();
			prtrol();
			goto inp;
			    }

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

	if(dice & 8192){
		write(1,"%Data conversion error in routine \".GETDICE.\" line ?\n",53);
		write(1,"From routine \".MAIN.\" line ?\n",29);
		prtrol();
		goto inp;
		}


	if(dice == 0)return(0);
	roll(dice);
	prtrol();
	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);
		}

categ(){
	register int i;
	char c;

	write(1,"\nCategories Left:\n\n",19);
	for(i = 0; i < 15; i++){
		if(score[i] == -1 || (i == 14 && score[i] > 0)){
			if(score[i] > 0)write(1,"      ( ",8);
			else	write(1,"        ",8);
			c = i > 8 ? '1' : ' ';
			write(1,&c,1);
			if(i > 8)c = i-9;
			else	c = i + 1;
			c =+ '0';
			write(1,&c,1);
			write(1,"		",2);
			write(1,cat[i],len(cat[i]));
			if(score[i] > 0)write(1," )",2);
			write(1,"\n",1);
				}
			        }

	write(1,"\n\n",2);
	}




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;
	write(1,"Your score for category #",25);
	writes(x);
	write(1,", ",2);
	write(1,cat[x-1],len(cat[x-1]));
	write(1,", is: ",6);
	writes(scor);
	write(1,"\n",1);
	return(i);
	}


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

			p++;
			write(1,p,&buf[7]-p);
		}






total(){
	register int i , tot1 , tot2 , j;
	char *sp = "                         ";
	tot1 = tot2 = 0;
	write(1,"\n\n\nTotals:\n\nSection I.\n",23);
	for(i = 0; i < 15; i++){
		j = len(cat[i]);
		write(1,cat[i],j);
		write(1,sp,25-j+(score[i] < 10)-((i == 14) && score[14] > 99));
		writes(score[i]);
		write(1,"\n",1);
		tot1 =+ score[i];
		if(i == 5 || i == 14)write(1,"----------------------------\n",29);
		if(i == 5){
			write(1,"Total Section I:",16);
			write(1,sp,8+(tot1 < 100) + (tot1 < 10));
			writes(tot1);
			write(1,"\n\nBonus:",8);
			if(tot1 > 77)tot2 = 75;
			else	if(tot1 > 70)tot2 = 55;
				else	if(tot1 > 62)tot2 = 35;
			write(1,sp,19+(tot2 == 0));
			writes(tot2);
			tot1 =+ tot2;
			write(1,"\n\nSection II.\n",14);
			tot2 = tot1;
			}
				}

	write(1,"Total Section II:",17);
	j = tot1-tot2;
	write(1,sp,7+(j < 100) + (j < 10));
	writes(j);
	write(1,"\n\nTotal:",8);
	write(1,sp,18+(tot1 < 100) + (tot1 < 10));
	writes(tot1);
	write(1,"\n\n\n\n",4);
	return(tot1);
}





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

			register int i;

			int fd;
			struct	{
				char who[14];
				long histime;
				int  hisscore;
					}entry;

			if((fd = open(LOGFILE,1)) != -1){
				seek(fd,0,2);
				s = t = logdir();
				while(*t)if(*t++ == '/')s = t;
				t = entry.who;
				while((*t = *s) && t <= &entry.who[13])s++,t++;
				while(t <= &entry.who[13])*t++ = ' ';
				time(&entry.histime);
				entry.hisscore = x;
				write(fd,&entry,20);
				close(fd);
				}

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

					close(fd);
					write(1,"\n\n\n\n",4);
					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);
				seek(fd,0,0);
				write(fd,&rec,54);
					}

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

log(x,s)
	char *s;
	int x;
		{
	struct	{
		char who[14];
		long tim;
		int score;
		}ent;

	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);
		}
		seek(fd,-20,2);
		while(read(fd,&ent,20) == 20){
		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(seek(fd,-40,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);
}
