#include <gemdefs.h>
#include <math.h>
#include <obdefs.h>
#include <osbind.h>
#include <stdio.h>
#include <linea.h>

#define	ONE = 16
#define	TWO = 8
#define	THREE = 4
#define FOUR = 2
#define FIVE = 1
#define TRUE  1
#define FALSE  0

/*
	VDI Globals
*/

int		contrl[12];
int		intin[256], ptsin[256];
int		intout[256], ptsout[256];
int		ev_bclicks,
		ev_bmask,
		ev_bstate,
		ev_bmx,
		ev_bmy,
		ev_bbutton,
		ev_bkstate;

/*
	AES Globals
*/

int		work_out[57], work_in[12];
int		gr_hwchar, gr_hhchar;
int		gr_hwbox, gr_hhbox;
int		resolution;
int		ap_id;
int		phys_handle;
int		handle;
int		uscore[6];
int		lscore[6];
int		score[6];
int		bonus[6];
int		l_turn[6];
int		flags[6] = {0,0,0,0,0,0};
int		players;

int		dval[5];
int		sx[10];
int		sy[5] = {28, 60, 92, 124, 156};

char	names[][] = 
		{
		{' ',' ',' ',' ',' ',' ',' ',' ','\0'},
		{' ',' ',' ',' ',' ',' ',' ',' ','\0'},
		{' ',' ',' ',' ',' ',' ',' ',' ','\0'},
		{' ',' ',' ',' ',' ',' ',' ',' ','\0'},
		{' ',' ',' ',' ',' ',' ',' ',' ','\0'},
		{' ',' ',' ',' ',' ',' ',' ',' ','\0'}
		};

char	name1[] = ' ',' ',' ',' ',' ',' ',' ',' ','\0';
char	c[] = ' ','\0';

lineaport *myport;

sprite 	dice[12];
spriteback back[10];

/*
	Various GEM subroutines
*/

initialize()
{
	int		i,w;
	char	c;
	
	ap_id = appl_init();
	phys_handle = graf_handle(&gr_hwchar, &gr_hhchar, &gr_hwbox, &gr_hhbox);
	for(i=0;i<10;work_in[i++]=1);
	work_in[10] = 2;
	v_opnvwk(work_in, &handle, work_out);
	myport = a_init();
	a_hidemouse();
	v_clrwk();
	color_white();
	myport -> planefill = 1;
	myport -> copymode = 0;
	myport -> writemode = 0;
	myport -> linemask = 0xFFFF;
	resolution = Getrez();
	if(resolution != 1)
	{
		a_showmouse();
		form_alert(1,"[1][This program runs|in medium|resolution only!][Aborting]");
		a_hidemouse();
		return(1);
	}
	for(i=0;i<200;i++)
	{ 
		a_hline(0, 639, i);
		a_hline(0, 639, i);
	}
	clr_scrn();
	a_showmouse();
	form_alert( 1, "[1][    YAHTZEE!   | Copyright 1988 | by Mark A. Danley ][YAHTZEE!]");
	a_hidemouse();
	makesprites();
	get_players();
	draw_display(players);
	return(0);
}

get_players()
{
	int		i,w;
	char	c;

	a_showmouse();
	players = form_alert(3,"[2][Select # of players][1|2|MORE]");
	if(players == 3)
	{
		players = form_alert(3,"[2][Select # of players][3|4|MORE]");
		if(players == 1)
			players = 3;
		else if(players == 2)
			players = 4;
		else if(players == 3)
		{
			players = form_alert(0,"[2][Select # of players][5|6]");
			if(players == 1)
				players = 5;
			else
				players = 6;
		}
	}
	a_hidemouse();
	get_names();
	get_Xvals();
}

color_white()
{
	myport -> plane0 = 0;
	myport -> plane1 = 0;
}

color_red()
{
	myport -> plane0 = 0xFFFF;
	myport -> plane1 = 0;
}

color_green()
{
	myport -> plane0 = 0;
	myport -> plane1 = 0xFFFF;
}

box1(x_1,y_1,x_2,y_2)
	int x_1,y_1,x_2,y_2;
{
	a_hline(x_1,x_2,y_1);
	a_hline(x_1,x_2,y_2);
	a_line(x_1,y_1,x_1,y_2);
	a_line(x_2,y_1,x_2,y_2);
}

box(x_1,y_1,x_2,y_2)
	int	x_1,y_1,x_2,y_2;
{
		a_hline(x_1,x_2,y_1);
		a_hline((x_1+4),(x_2-4),y_1+2);
		a_line(x_1, y_1, x_1, y_2);
		a_line(x_2, y_1, x_2, y_2);
		a_line((x_1+4), (y_1+2), (x_1+4), (y_2-2));
		a_line((x_2-4), (y_1+2), (x_2-4), (y_2-2));
		a_hline((x_1+4), (x_2-4), (y_2-2));
		a_hline(x_1, x_2, y_2);
}

clr_scrn()
{
	int	i,w;

	for(w=6;w<200;w += 8)
	{
		for(i=0;i<638;i+=8)
			v_gtext(handle, i, w, " ");
	}
	for(w=0;w<200;w++)
		a_hline(0, 639, w);		
}

get_names()
{
	int		i, z;

	color_white();
	clr_scrn();
	color_red();
	box(156, 70, 480, 126);
	for(i=1;i<=players;i++)
	{
		color_red();
		box(156, 70, 480, 126);
		v_gtext(handle, 224, 88, "Enter name of player #");
		c[0] = i+48;
		v_gtext(handle, 404, 88, &c[0]);
		get_name(i-1);
		color_white();
		for( z = 68; z<483; z++)
			a_hline(154, 482, z);
	}
	for(i=0;i<8;i++)
		name1[i] = names[0][i];
}

get_name(i)
	int	i;
{
	int	w,j;

	w = 0;
	Cursconf(2, 0);
	Bconout(2, '\033');
	Bconout(2, 'Y');
	Bconout(2, '-');
	Bconout(2, '<');
	Cursconf(1, 0);
	do
	{
		j = Bconin(2
		);
		if((w<8) && (((j>64) && (j<91)) || ((j>96) && (j<123)) || (j == 32)))
		{
			Cconout(j);
			names[i][w] = (char)j;
			w += 1;
		}
		else if((j == 8) && (w>0))
		{
			w -= 1;
			names[i][w] = ' ';
			Cconout(8);
			Cconout(32);
			Cconout(8);
		}
	}while(j != 13);
	Cursconf(0, 0);
	names[i][8] = '\0';
}
	
makesprites()
{
	int 	w;
	sprite	*z;
	
	for(z = dice; z < dice+12; z++)
	{
		z -> x         = 0;
		z -> y         = 0;
		z -> format    = 0;
		z -> forecolor = 0;
		z -> backcolor = 1;
		for(w=0;w<32;w+=2)
		{
			z -> image[w]   = 0xFFFF;
			z -> image[w+1] = 0xFFFF;
		}
	}
	spot_4(0);
	spot_1(2);
	spot_7(3);
	spot_1(4);
	spot_4(4);
	spot_7(5);
	spot_1(6);
	spot_2(7);
	spot_6(6);
	spot_7(7);
	spot_1(8);
	spot_2(9);
	spot_4(8);
	spot_6(8);
	spot_7(9);
	spot_1(10);
	spot_2(11);
	spot_3(10);
	spot_5(11);
	spot_6(10);
	spot_7(11); 
	
}

spot_1(index)
	int index;
{
	sprite *z;
	
	z = dice+index;
	z -> image[5] = 0xE8FF;
	z -> image[7] = 0xE8FF;
}

spot_2(index)
	int	index;
{
	sprite *z;
	
	z = dice+index;
	z -> image[5] = 0xFE8F;
	z -> image[7] = 0xFE8F;
}

spot_3(index)
	int index;
{
	sprite *z;
	
	z = dice+index;
	z -> image[15] = 0xE8FF;
	z -> image[17] = 0xE8FF;
}

spot_4(index)
	int	index;
{
	sprite *z;
	
	z = dice+index;
	z -> image[15] = 0xFFFC;
	z -> image[17] = 0xFFFC;
	z += 1;
	z -> image[15] = 0x3FFF;
	z -> image[17] = 0x3FFF;
}

spot_5(index)
	int	index;
{
	sprite *z;
	
	z = dice+index;
	z -> image[15] = 0xFE8F;
	z -> image[17] = 0xFE8F;
}

spot_6(index)
	int index;
{
	sprite *z;
	
	z = dice+index;
	z -> image[25] = 0xE8FF;
	z -> image[27] = 0xE8FF;
}

spot_7(index)
	int index;
{
	sprite *z;
	
	z = dice+index;
	z -> image[25] = 0xFE8F;
	z -> image[27] = 0xFE8F;
}

draw_display(num)
	int	num;
{
	int w,z;

	myport -> plane0 = 0xFFFF;
	myport -> plane1 = 0;
	a_line(0, 0, 0, 199);
	a_hline(0,(num*65)+98,0);
	a_hline(0,(num*65)+98,199);
	v_gtext(handle, 1, 7, "Player Name ");
	a_hline(0,(num*65)+97,9);
	v_gtext(handle, 1, 16, "Aces        ");
	a_hline(0,(num*65)+97,18);
	v_gtext(handle, 1, 25, "Twos        ");
	a_hline(0,(num*65)+97,27);
	v_gtext(handle, 1, 34, "Threes      ");
	a_hline(0,(num*65)+97,36);
	v_gtext(handle, 1, 43, "Fours       ");
	a_hline(0,(num*65)+97,45);
	v_gtext(handle, 1, 52, "Fives       ");
	a_hline(0,(num*65)+97,54);
	v_gtext(handle, 1, 61, "Sixes       ");
	a_hline(0,(num*65)+97,63);
	v_gtext(handle, 1, 70, "Total Score ");
	a_hline(0,(num*65)+97,72);
	v_gtext(handle, 1, 79, "Bonus       ");
	a_hline(0,(num*65)+97,81);
	v_gtext(handle, 1, 88, "Upper Total ");
	a_hline(0,(num*65)+97,90);
	a_hline(0,(num*65)+97,91);
	v_gtext(handle, 1, 98, "3 of a kind ");
	a_hline(0,(num*65)+97,100);
	v_gtext(handle, 1, 107, "4 of a kind ");
	a_hline(0,(num*65)+97,109);
	v_gtext(handle, 1, 116, "Full House  ");
	a_hline(0,(num*65)+97,118);
	v_gtext(handle, 1, 125, "Sm. Straight");
	a_hline(0,(num*65)+97,127);
	v_gtext(handle, 1, 134, "Lg. Straight");
	a_hline(0,(num*65)+97,136);
	v_gtext(handle, 1, 143, "YAHTZEE!    ");
	a_hline(0,(num*65)+97,145);
	v_gtext(handle, 1, 152, "Chance      ");
	a_hline(0,(num*65)+97,154);
	v_gtext(handle, 1, 161, "Yahtzee     ");
	a_hline(98,(num*65)+97,163);
	for(w = 0; w<num;w++)
	{
		a_line(120+(w*65),154,120+(w*65),163);
		a_line(143+(w*65),154,143+(w*65),163);
	}
	v_gtext(handle, 1, 170, "   Bonus    ");
	a_hline(0,(num*65)+97,172);
	v_gtext(handle, 1, 179, "Lower Total ");
	a_hline(0,(num*65)+97,181);
	v_gtext(handle, 1, 188, "Upper Total ");
	a_hline(0,(num*65)+97,190);
	v_gtext(handle, 1, 197, "Grand Total ");
	a_hline(0,(num*65)+97,199);
	a_line(98, 0, 98, 199);
	for (w=1;w<=num;w++)
	{
		a_line((w*65)+98, 0, (w*65)+98, 199);
		v_gtext(handle, ((w-1)*65)+99, 7, &names[w-1][0]);
	}
	color_green();
	for(w=0;w<200;w++)
		a_hline((num*65)+99,639,w);
	for(w=0;w<5;w++)
	{
		a_drawsprite(sx[w*2], sy[w], &dice[10], back[w*2]);
		a_drawsprite(sx[(w*2)+1], sy[w], &dice[11], back[(w*2)+1]);
	}

}

get_Xvals()
{
	int	w,zx1,zx2;
	
	zx1 = 639-((players*65)+98);
	zx2 = (zx1/2)+((players*65)+98);
	zx1 = zx2-16;
	for(w=0;w<5;w++)
	{
		sx[w*2] = zx1;
		sx[(w*2)+1] = zx2;
	}
}

show_name(num)
	int	num;
{
	int nlen,done;

	nlen = 0;
	done = FALSE;
	do
	{
		if ((names[num][nlen] > ' ') && (names[num][nlen] < '{'))
			nlen += 1;
		else if (names[num][nlen] == ' ')
		{
			if ((names[num][nlen+1] > ' ') && (names[num][nlen+1] < '{'))
				nlen += 1;
			else done = TRUE;
		}
		else done = TRUE;
	} while (done == FALSE);
	v_gtext(handle, (players*65)+102, 7, &names[num][0]);
	v_gtext(handle, (players*65)+102+(nlen*8), 7, "'s roll.");
	color_red();
	box1((players*65)+100,0,(players*65)+167+(nlen*8),9);
	color_green();
}

roll_dice(num)
	int	num;
{
	int	w,l1,l2,z,i;
	char	c;
	
	i = 0;
	for(l1=1;l1<32;l1*=2)
	{
		if( (l1 & num) != 0 )
		{
			w = (int)Random();
			if(w<0)
				w *= -1;
			w = (w%10)+2;
			for(l2=1;l2<w;l2++)
			{
				z = 6;
				if((z<0) || (z>5))
				{
					z = (int)Random();
					if(z<0)
						z *= -1;
					z = z%6;
				}
				Vsync();
				a_undrawsprite(back[i*2]);
				Vsync();
				a_undrawsprite(back[(i*2)+1]);
				Vsync();
				a_drawsprite(sx[i*2], sy[i], &dice[z*2], back[i*2]);
				Vsync();
				a_drawsprite(sx[(i*2)+1], sy[i], &dice[(z*2)+1], back[(i*2)+1]);
				dval[i] = z+1;
			}
		}
	i += 1;
	}
	
}

get_reroll()
{
	int	j,z,i,w,l,pstatus,mxx,myy;
	
	w = 0;
	v_gtext(handle, 503, 189, "Double click here");
	v_gtext(handle, 503, 197, "when finished    ");
	color_red();
	box1(502,182,639,199);
	color_green();
	j = 0;
	z = 1;
	do
	{
		i = 0;
		a_showmouse();
		evnt_button( 1, 1, 1, &ev_bmx, &ev_bmy,	&ev_bbutton, &ev_bkstate);
		a_hidemouse();
		do
		{
			vq_mouse(handle, &pstatus, &mxx, &myy);
		}while(pstatus == 1);
		l = 1;
		for(l=1;l<32;l*=2)
		{
			if((ev_bmx>sx[i*2]) && (ev_bmx<(15 + (sx[(i*2)+1])))
			&& (ev_bmy>sy[i]) && (ev_bmy<(sy[i]+15)))
			{
				if((w & l) == 0)
				{
					w = w | l;
					j = 0;
					color_white();
					box1(sx[i*2],sy[i],sx[(i*2)+1]+15,sy[i]+15);
					z = 1;
				}
				else
				{
					j = 0;
					a_undrawsprite(back[i*2]);
					a_undrawsprite(back[(i*2)+1]);
					a_drawsprite(sx[i*2], sy[i], &dice[(dval[i]-1)*2], back[i*2]);
					a_drawsprite(sx[(i*2)+1], sy[i], &dice[((dval[i]-1)*2)+1], back[(i*2)+1]);
					w = w ^ l;
					z = 1;
				}
			}
			i += 1;
		}
		if((ev_bmx>504) && (ev_bmy>184))
		{
			j += 1;
			if(j == 2)
			{
				color_green();
				for(z = 182; z<200; z++)
					a_hline( 502, 639, z);
				z = 0;
			}
		}
	}
	while(z == 1);
	return(w);
}

get_score(p,turn)
	int	p,turn;
{
	int	w, z;

	w = 0;
	do
	{
		v_gtext(handle, players*65+102, 189, "Click on box to");
		v_gtext(handle, players*65+102, 197, "place score in.");
		color_red();
		box1(players*65+100, 182, players*65+224, 199);
		a_showmouse();
		evnt_button( 1, 1, 1, &ev_bmx, &ev_bmy, &ev_bbutton, &ev_bkstate);
		a_hidemouse();
		if((ev_bmy>9) && (ev_bmy<18))
			w = get_ones(p);
		else if((ev_bmy>18) && (ev_bmy<27))
			w = get_twos(p);
		else if((ev_bmy>27) && (ev_bmy<36))
			w = get_threes(p);
		else if((ev_bmy>36) && (ev_bmy<45))
			w = get_fours(p);
		else if((ev_bmy>45) && (ev_bmy<54))
			w = get_fives(p);
		else if((ev_bmy>54) && (ev_bmy<63))
			w = get_sixes(p);
		else if((ev_bmy>91) && (ev_bmy<100))
			w = get_3kind(p);
		else if((ev_bmy>100) && (ev_bmy<109))
			w = get_4kind(p);
		else if((ev_bmy>109) && (ev_bmy<118))
			w = get_fhouse(p);
		else if((ev_bmy>118) && (ev_bmy<127))
			w = get_sstr8(p);
		else if((ev_bmy>127) && (ev_bmy<136))
			w = get_lstr8(p);
		else if((ev_bmy>136) && (ev_bmy<145))
			w = get_yatz(p);
		else if((ev_bmy>145) && (ev_bmy<154))
			w = get_chance(p);
		else if((ev_bmy>154) && (ev_bmy<172))
			w = get_bonus(p,turn);
	}
	while(w == 0);
	color_green();
	for(z = 182; z<200; z++)
		a_hline( players*65+100,players*65+224, z);
}

get_ones(p)
	int	p;
{
	int		but,i,tot;
	char	c;
	static	char	str1[] = "[2][5 on ones ?][YES|NO]";

	tot = 0;
	if((flags[p] & 1) != 0)
	{
		a_showmouse();
		form_alert( 1, "[3][You already|have your ones.][Select again]");
		a_hidemouse();
		return(0);
	}
	for(i=0;i<5;i++)
	{
		if(dval[i] == 1)
			tot += 1;
	}
	str1[4] = (char)(tot +48);
	a_showmouse();
	but = form_alert( 1, str1);
	a_hidemouse();
	if(but == 2)
		return(0);
	c = (char)(tot + 48);
	v_gtext(handle, (p*65)+126, 16, &c);
	flags[p] = flags[p] ^ 1;
	uscore[p] = uscore[p]+tot;
	return(1);
}

get_twos(p)
	int	p;
{
	int		but,i,tot;
	char	c;
	static	char	str2[] = "[2][10 on twos ?][YES|NO]";

	tot = 0;
	if((flags[p] & 2) != 0)
	{
		a_showmouse();
		form_alert( 1, "[3][You already|have your twos.][Select again]");
		a_hidemouse();
		return(0);
	}
	for(i=0;i<5;i++)
	{
		if(dval[i] == 2)
			tot += 2;
	}
	str2[4] = (char)(tot/10 +48);
	str2[5] = (char)(tot%10 + 48);
	a_showmouse();
	but = form_alert( 1, str2);
	a_hidemouse();
	if(but == 2)
		return(0);
	c = (char)(tot/10 + 48);
	v_gtext(handle, (p*65)+122, 25, &c);
	c = (char)(tot%10 + 48);
	v_gtext(handle, (p*65)+130, 25, &c);
	flags[p] = flags[p] ^ 2;
	uscore[p] += tot;
	return(1);
}
				
get_threes(p)
	int	p;
{
	int		but,i,tot;
	char	c;
	static	char	str1[] = "[2][15 on threes ?][YES|NO]";

	tot = 0;
	if((flags[p] & 4) != 0)
	{
		a_showmouse();
		form_alert( 1, "[3][You already|have your threes.][Select again]");
		a_hidemouse();
		return(0);
	}
	for(i=0;i<5;i++)
	{
		if(dval[i] == 3)
			tot += 3;
	}
	str1[4] = (char)(tot/10 +48);
	str1[5] = (char)(tot%10 + 48);
	a_showmouse();
	but = form_alert( 1, str1);
	a_hidemouse();
	if(but == 2)
		return(0);
	c = (char)(tot/10 + 48);
	v_gtext(handle, (p*65)+122, 34, &c);
	c = (char)(tot%10 + 48);
	v_gtext(handle, (p*65)+130, 34, &c);
	flags[p] = flags[p] ^ 4;
	uscore[p] += tot;
	return(1);
}
				
get_fours(p)
	int	p;
{
	int		but,i,tot;
	char	c;
	static	char	str1[] = "[2][20 on fours ?][YES|NO]";

	tot = 0;
	if((flags[p] & 8) != 0)
	{
		a_showmouse();
		form_alert( 1, "[3][You already|have your fours.][Select again]");
		a_hidemouse();
		return(0);
	}
	for(i=0;i<5;i++)
	{
		if(dval[i] == 4)
			tot += 4;
	}
	str1[4] = (char)(tot/10 + 48);
	str1[5] = (char)(tot%10 + 48);
	a_showmouse();
	but = form_alert( 1, str1);
	a_hidemouse();
	if(but == 2)
		return(0);
	c = (char)(tot/10 + 48);
	v_gtext(handle, (p*65)+122, 43, &c);
	c = (char)(tot%10 + 48);
	v_gtext(handle, (p*65)+130, 43, &c);
	flags[p] = flags[p] ^ 8;
	uscore[p] += tot;
	return(1);
}
				
get_fives(p)
	int	p;
{
	int		but,i,tot;
	char	c;
	static	char	str1[] = "[2][25 on fives ?][YES|NO]";

	tot = 0;
	if((flags[p] & 16) != 0)
	{
		a_showmouse();
		form_alert( 1, "[3][You already|have your fives.][Select again]");
		a_hidemouse();
		return(0);
	}
	for(i=0;i<5;i++)
	{
		if(dval[i] == 5)
			tot += 5;
	}
	str1[4] = (char)(tot/10 + 48);
	str1[5] = (char)(tot%10 + 48);
	a_showmouse();
	but = form_alert( 1, str1);
	a_hidemouse();
	if(but == 2)
		return(0);
	c = (char)(tot/10 + 48);
	v_gtext(handle, (p*65)+122, 52, &c);
	c = (char)(tot%10 + 48);
	v_gtext(handle, (p*65)+130, 52, &c);
	flags[p] = flags[p] ^ 16;
	uscore[p] += tot;
	return(1);
}
				
get_sixes(p)
	int	p;
{
	int		but,i,tot;
	char	c;
	static	char	str1[] = "[2][30 on sixes ?][YES|NO]";

	tot = 0;
	if((flags[p] & 32) != 0)
	{
		a_showmouse();
		form_alert( 1, "[3][You already|have your sixes.][Select again]");
		a_hidemouse();
		return(0);
	}
	for(i=0;i<5;i++)
	{
		if(dval[i] == 6)
			tot += 6;
	}
	str1[4] = (char)(tot/10 + 48);
	str1[5] = (char)(tot%10 + 48);
	a_showmouse();
	but = form_alert( 1, str1);
	a_hidemouse();
	if(but == 2)
		return(0);
	c = (char)(tot/10 + 48);
	v_gtext(handle, (p*65)+122, 61, &c);
	c = (char)(tot%10 + 48);
	v_gtext(handle, (p*65)+130, 61, &c);
	flags[p] = flags[p] ^ 32;
	uscore[p] += tot;
	return(1);
}
				
get_3kind(p)
	int	p;
{
	int		but,i,j,tot,sav;
	char	c;
	static	char	str1[] = "[2][30 on three|of a kind ?][YES|NO]";

	tot = 0;
	if((flags[p] & 64) != 0)
	{
		a_showmouse();
		form_alert( 1, "[3][You already filled|three of a kind.][Select again]");
		a_hidemouse();
		return(0);
	}
	for(j=1;j<7;j++)
	{
		sav = 0;
		for(i=0;i<5;i++)
		{
			if(dval[i] == j)
				sav += 1;
		}
		if(sav>2)
			tot = 1;
	}
	if(tot == 1)
	{
		tot = 0;
		for(i = 0; i<5; i++)
			tot += dval[i];
	}
	str1[4] = (char)(tot/10 + 48);
	str1[5] = (char)(tot%10 + 48);
	a_showmouse();
	but = form_alert( 1, str1);
	a_hidemouse();
	if(but == 2)
		return(0);
	c = (char)(tot/10 + 48);
	v_gtext(handle, (p*65)+122, 98, &c);
	c = (char)(tot%10 + 48);
	v_gtext(handle, (p*65)+130, 98, &c);
	flags[p] = flags[p] ^ 64;
	lscore[p] += tot;
	return(1);
}
				
get_4kind(p)
	int	p;
{
	int		but,i,j,tot,sav;
	char	c;
	static	char	str1[] = "[2][30 on four|of a kind ?][YES|NO]";

	tot = 0;
	if((flags[p] & 128) != 0)
	{
		a_showmouse();
		form_alert( 1, "[3][You already filled|four of a kind.][Select again]");
		a_hidemouse();
		return(0);
	}
	for(j=1;j<7;j++)
	{
		sav = 0;
		for(i=0;i<5;i++)
		{
			if(dval[i] == j)
				sav += 1;
		}
		if(sav>3)
			tot = 1;
	}
	if(tot == 1)
	{
		tot = 0;
		for(i = 0; i<5; i++)
			tot += dval[i];
	}
	str1[4] = (char)(tot/10 + 48);
	str1[5] = (char)(tot%10 + 48);
	a_showmouse();
	but = form_alert( 1, str1);
	a_hidemouse();
	if(but == 2)
		return(0);
	c = (char)(tot/10 + 48);
	v_gtext(handle, (p*65)+122, 107, &c);
	c = (char)(tot%10 + 48);
	v_gtext(handle, (p*65)+130, 107, &c);
	flags[p] = flags[p] ^ 128;
	lscore[p] += tot;
	return(1);
}
				
get_fhouse(p)
	int	p;
{
	int		but,i,j,sav,tot,num;
	char	c;
	static	char	str1[] = "[2][40 on full house ?][YES|NO]";

	tot = 0;
	if((flags[p] & 256) != 0)
	{
		a_showmouse();
		form_alert( 1, "[3][You already filled|your full house.][Select again]");
		a_hidemouse();
		return(0);
	}
	for(j=1;j<7;j++)
	{
		sav = 0;
		for(i=0;i<5;i++)
		{
			if(dval[i] == j)
				sav += 1;
		}
		if(sav > 2)
		{
			tot = 1;
			num = j;
		}
	}
	if(tot == 1)
	{
		for(j=1;j<7;j++)
		{
			if(j != num)
			{
				sav = 0;
				for(i=0;i<5;i++)
				{
					if(dval[i] == j)
						sav += 1;
				}
				if(sav>1)
					tot = 2;
			}
		}
	}
	if((tot == 2) || (check(p) == 1))
		tot = 25;
	else
		tot = 0;
	str1[4] = (char)(tot/10 + 48);
	str1[5] = (char)(tot%10 + 48);
	a_showmouse();
	but = form_alert( 1, str1);
	a_hidemouse();
	if(but == 2)
		return(0);
	c = (char)(tot/10 + 48);
	v_gtext(handle, (p*65)+122, 116, &c);
	c = (char)(tot%10 + 48);
	v_gtext(handle, (p*65)+130, 116, &c);
	flags[p] = flags[p] ^ 256;
	lscore[p] += tot;
	return(1);
}
				
get_sstr8(p)
	int	p;
{
	int		but,i,tot,j;
	char	c;
	static	char	str1[] = "[2][30 on small straight ?][YES|NO]";

	tot = 0;
	if((flags[p] & 512) != 0)
	{
		a_showmouse();
		form_alert( 1, "[3][You already filled|your small straight.][Select again]");
		a_hidemouse();
		return(0);
	}
	tot = 0;
	for(j=1;j<5;j++)
	{
		if(cnum(j) == 0)
			tot = 1;
	}
	if(tot == 1)
	{
		tot = 0;
		for(j=2;j<6;j++)
		{
			if(cnum(j) == 0)
				tot = 1;
		}
	}
	if(tot == 1)
	{
		tot = 0;
		for(j=3;j<7;j++)
		{
			if(cnum(j) == 0)
				tot = 1;
		}
	}
	if((tot == 0) || (check(p) == 1))
		tot = 30;
	else
		tot = 0;
	str1[4] = (char)(tot/10 + 48);
	str1[5] = (char)(tot%10 + 48);
	a_showmouse();
	but = form_alert( 1, str1);
	a_hidemouse();
	if(but == 2)
		return(0);
	c = (char)(tot/10 + 48);
	v_gtext(handle, (p*65)+122, 125, &c);
	c = (char)(tot%10 + 48);
	v_gtext(handle, (p*65)+130, 125, &c);
	flags[p] = flags[p] ^ 512;
	lscore[p] += tot;
	return(1);
}

get_lstr8(p)
	int	p;
{
	int		but,i,tot,j;
	char	c;
	static	char	str1[] = "[2][40 on large straight ?][YES|NO]";

	tot = 0;
	if((flags[p] & 1024) != 0)
	{
		a_showmouse();
		form_alert( 1, "[3][You already filled|your large straight.][Select again]");
		a_hidemouse();
		return(0);
	}
	for(j=1;j<6;j++)
	{
		if(cnum(j) == 0)
			tot = 1;
	}
	if(tot == 1)
	{
		tot = 0;
		for(j=2;j<7;j++)
		{
			if(cnum(j) == 0)
				tot = 1;
		}
	}
	if(tot == 0)
		j = 1;
	if((j == 1) || (check(p) == 1))
		tot = 40;
	else
		tot = 0;
	str1[4] = (char)(tot/10 + 48);
	str1[5] = (char)(tot%10 + 48);
	a_showmouse();
	but = form_alert( 1, str1);
	a_hidemouse();
	if(but == 2)
		return(0);
	c = (char)(tot/10 + 48);
	v_gtext(handle, (p*65)+122, 134, &c);
	c = (char)(tot%10 + 48);
	v_gtext(handle, (p*65)+130, 134, &c);
	flags[p] = flags[p] ^ 1024;
	lscore[p] += tot;
	return(1);
}

cnum(i)
	int	i;
{
	int	w;
	
	for(w = 0;w<5;w++)
	{
		if(dval[w] == i)
			return(1);
	}
	return(0);
}

get_yatz(p)
	int	p;
{
	int		but,i,j,tot,sav;
	char	c;
	static	char	str1[] = "[2][50 on YAHTZEE ?][YES|NO]";

	tot = 0;
	if((flags[p] & 2048) != 0)
	{
		a_showmouse();
		form_alert( 1, "[3][You already filled YAHTZEE.][Select again]");
		a_hidemouse();
		return(0);
	}
	for(j=1;j<7;j++)
	{
		sav = 0;
		for(i=0;i<5;i++)
		{
			if(dval[i] == j)
				sav += 1;
		}
		if(sav == 5)
			tot = 1;
	}
	if(tot == 1)
	{
		tot = 50;
		flags[p] = flags[p] ^ 4096;
	}
	else
		tot = 0;
	str1[4] = (char)(tot/10 + 48);
	str1[5] = (char)(tot%10 + 48);
	a_showmouse();
	but = form_alert( 1, str1);
	a_hidemouse();
	if(but == 2)
		return(0);
	c = (char)(tot/10 + 48);
	v_gtext(handle, (p*65)+122, 143, &c);
	c = (char)(tot%10 + 48);
	v_gtext(handle, (p*65)+130, 143, &c);
	flags[p] = flags[p] ^ 2048;
	lscore[p] += tot;
	return(1);
}
				
get_chance(p)
	int	p;
{
	int		but,i,tot;
	char	c;
	static	char	str1[] = "[2][30 on chance ?][YES|NO]";

	tot = 0;
	if((flags[p] & 8192) != 0)
	{
		a_showmouse();
		form_alert( 1, "[3][You already|filled your chance.][Select again]");
		a_hidemouse();
		return(0);
	}
	for(i=0;i<5;i++)
	{
		tot += dval[i];
	}
	i = check(p);
	str1[4] = (char)(tot/10 + 48);
	str1[5] = (char)(tot%10 + 48);
	a_showmouse();
	but = form_alert( 1, str1);
	a_hidemouse();
	if(but == 2)
		return(0);
	c = (char)(tot/10 + 48);
	v_gtext(handle, (p*65)+122, 152, &c);
	c = (char)(tot%10 + 48);
	v_gtext(handle, (p*65)+130, 152, &c);
	flags[p] = flags[p] ^ 8192;
	lscore[p] += tot;
	return(1);
}

get_bonus(p,turn)
	int	p,turn;
{
	int		but,i,j,tot,sav;
	char	c;

	tot = 0;
	if((turn == l_turn[p]) && (turn != 0))
	{
		a_showmouse();
		form_alert( 1,"[3][I'm not that stupid!][*$*@$@*$]");
		a_hidemouse();
		return(0);
	}
	l_turn[p] = turn;
	if((flags[p] & 2048) == 0)
	{
		a_showmouse();
		form_alert( 1, "[3][You haven't filled|your YAHTZEE yet.][Select again]");
		a_hidemouse();
		return(0);
	}
	if((flags[p] & 4096) == 0)
	{
		a_showmouse();
		form_alert( 1, "[3][You already zeroed|your YAHTZEE][Select again]");
		a_hidemouse();
		return(0);
	}
	for(j=1;j<7;j++)
	{
		sav = 0;
		for(i=0;i<5;i++)
		{
			if(dval[i] == j)
				sav += 1;
		}
		if(sav == 5)
			tot = 1;
	}
	if(tot == 1)
	{
		j = 0xc000;
		j = j & flags[p];
		if(j == 0)
		{
			flags[p] = flags[p] ^ 0x4000;
			tot = 100;
		}
		else if(j == 0x4000)
		{
			flags[p] = flags[p] & 0x3fff;
			flags[p] = flags[p] ^ 0x8000;
			tot = 200;
		}
		else if(j == 0x8000)
		{
			flags[p] = flags[p] ^ 0x4000;
			tot = 300;
		}
		else
		{
			a_showmouse();
			form_alert( 1, "[3][You've already|rolled 4 YAHTZEE's !][Enough is enough]");
			a_hidemouse();
			return(0);
		}
	}
	else
	{
		a_showmouse();
		form_alert( 1, "[3][That's not a YAHTZEE !][OOPS!]");
		a_hidemouse();
		return(0);
	}
	c = (char)(tot/100 + 48);
	v_gtext(handle, (p*65)+118, 170, &c);
	c = (char)(48);
	v_gtext(handle, (p*65)+126, 170, &c);
	v_gtext(handle, (p*65)+134, 170, &c);
	c = 'x';
	switch(tot)
	{
		case 100:
			v_gtext(handle, (p*65)+105, 161, &c);
			break;
		case 200:
			v_gtext(handle, (p*65)+127, 161, &c);
			break;
		case 300:
			v_gtext(handle, (p*65)+150, 161, &c);
			break;
	}
	a_showmouse();
	form_alert( 1,"[1][You get to|select another][YIPPEE!!]");
	a_hidemouse();
	lscore[p] += 100;
	return(0);
}

check(p)
	int	p;
{
	int	j,i,tot,num;

	num = 0;
	for(i=1;i<7;i++)
	{
		tot = 0;
		for(j=0;j<5;j++)
		{
			if(dval[j] == i)
				tot += 1;
		}
		if(tot == 5)
			num = i;
	}
	if(num != 0)
	{
		switch(num)
		{
			case 1:
				if((flags[p] & 1) == 1)
					return(1);
				else
					out(num);
					return(0);
			case 2:
				if((flags[p] & 2) == 2)
					return(1);
				else
					out(num);
					return(0);
			case 3:
				if((flags[p] & 4) == 4)
					return(1);
				else
					out(num);
					return(0);
			case 4:
				if((flags[p] & 8) == 8)
					return(1);
				else
					out(num);
					return(0);
			case 5:
				if((flags[p] & 16) == 16)
					return(1);
				else
					out(num);
					return(0);
			case 6:
				if((flags[p] & 32) == 32)
					return(1);
				else
					out(num);
					return(0);
		}
	}
	return(0);
}

out(num)
	int	num;
{
	char	c;
	static char str[] = "[3][You must use|this on 1's][^%@^#%]";
	
	str[25] = (char)(num+48);
	a_showmouse();
	form_alert( 1, str);
	a_hidemouse();
}

sh_score(p)
	int p;
{
	int		j,i;
	char	c;
	
	if((uscore[p]>62) && (bonus[p] == 0))
	{
		c = '3';
		v_gtext(handle, (p*65)+122, 79, &c);
		c = '5';
		v_gtext(handle, (p*65)+130, 79, &c);
	
		bonus[p] = 35;
	}	
	c = (char)(uscore[p]/100+48);
	v_gtext(handle, (p*65)+118, 70, &c);
	if(bonus[p] == 35)
		c = (char)((uscore[p]+35)/100+48);
	v_gtext(handle, (p*65)+118, 88, &c);
	v_gtext(handle, (p*65)+118, 188, &c);
	i = uscore[p]%100;
	c = (char)(i/10 + 48);
	v_gtext(handle, (p*65)+126, 70, &c);
	if(bonus[p] == 35)
	{
		j = (uscore[p]+35)%100;
		c = (char)(j/10 + 48);
	}
	v_gtext(handle, (p*65)+126, 88, &c);
	v_gtext(handle, (p*65)+126, 188, &c);
	c = (char)(i%10 + 48);
	v_gtext(handle, (p*65)+134, 70, &c);
	if(bonus[p] ==  35)
		c = (char)(j%10 + 48);
	v_gtext(handle, (p*65)+134, 88, &c);
	v_gtext(handle, (p*65)+134, 188, &c);
	c = (char)(lscore[p]/100 + 48);
	v_gtext(handle, (p*65)+118, 179, &c);
	i = lscore[p]%100;
	c = (char)(i/10 + 48);
	v_gtext(handle, (p*65)+126, 179, &c);
	c = (char)(i%10 + 48);
	v_gtext(handle, (p*65)+134, 179, &c);
}

sh_gt()
{
	int		i,j;
	char	c;

	for(i = 0;i<players;i++)
	{
		score[i] = lscore[i] + uscore[i] + bonus[i];
		c = (char)(score[i]/100 + 48);
		v_gtext(handle, (i*65)+118, 197, &c);
		j = score[i]%100;
		c = (char)(j/10 + 48);
		v_gtext(handle, (i*65)+126, 197, &c);
		c = (char)(j%10 + 48);
		v_gtext(handle, (i*65)+134, 197, &c);
	}
	v_gtext(handle, (players*65)+102, 7, "Press mouse button");
	v_gtext(handle, (players*65)+102, 15,"when done looking.");
	color_red();
	box1(players*65+101,0,players*65+247,17);
	evnt_button( 1, 1, 1, &ev_bmx, &ev_bmy, &ev_bbutton, &ev_bkstate);
}

clr_scores()
{
	int		i;
	
	for(i=0;i<7;i++)
	{
		flags[i] = 0;
		lscore[i] = 0;
		uscore[i] = 0;
		bonus[i] = 0;
		l_turn[i] = 0;
		score[i] = 0;
	}
}

main()
{
	int w,l1,l2,rr,lp;
	
	if (initialize() == 0)
	{
		do
		{
			for(w=0;w<13;w++)
			{
				for(l1=0;l1<players;l1++)
				{
					rr = 0x1f;
					show_name(l1);
					roll_dice(rr);
					for(l2=0;l2<2;l2++)
					{
						rr = get_reroll();
						roll_dice(rr);
					}
					get_score(l1,w);
					sh_score(l1);
				}
			}
			sh_gt();
			a_showmouse();
			w = form_alert( 1,"[2][Play again ?][Yes|No]");
			a_hidemouse();
			if(w == 1)
			{
				color_white();
				clr_scrn();
				clr_scores();
				a_showmouse();
				l1 = form_alert( 1,"[2][Any player changes ?][Yes|No]");
				a_hidemouse();
				if(l1 == 1)
					get_players();
				for(lp=0;lp<8;lp++)
					names[0][lp] = name1[lp];
				draw_display(players);
			}
			else
			{
				a_showmouse();
				v_clsvwk(handle);
				appl_exit();
			}
		}
		while(w == 1);
	}
}
