
#include <GRAPHICS.H>
#include <CONIO.H>
#include <STDIO.H>
#include <STDLIB.H>
#include <DOS.H>

//const int COLOR[7] = { 0, 1, 2, 3, 4, 5, 6 };
const int HOLECOL = 15;
const int HOLERAD = 15;
const int HOLEXGAP = 5;
const int HOLEYGAP = 6;
const int PEGRAD = 7;
const int PEGGRIDGAP = 20;
const int PEGGAP = 5;
const int TRUEPEGCOL = 1;
const int PEGCOL = 2;
const int CURCOL = 3;
const int SETX = 600;

enum bool { false, true };

int startx, starty;
int selected[4];
int claim[4];
int truematch, match;
int chances;
int types;
bool repeat;

void draw_screen();
void select();
void draw_cursor(int, int, int);
void justify();
void drawresult(int);
void fill_hole(int, int, int);
void playgame();

void main()
	{

	//intro screen
	clrscr();
	textcolor(GREEN); cputs("\r\n Welcome to Brain. "); textcolor(BROWN);
	cputs("\r\n This game tests your analytical and logical skills.");
	cputs("\r\n\n\n The computer randomly selects four colors from a set.");
	cputs("\r\n Within a fixed number of guesses, you have to find that pattern of four.");
	cputs("\r\n\n After each guess, the computer comments on it's correctness.");
	cputs("\r\n Blue color means a colour in the guess is in the right position.");
	cputs("\r\n Green means that a colour is right but misplaced.");
	cputs("\r\n\n\n\n Press any key to select options");
	getch();

	//select options screen
	char ch;

	clrscr();
	cputs("Options:");

	cputs("\r\n Allow Repeat(Y/N) (Default=Y): ");
	do
		{ ch = getch(); }
	while (ch!='y' && ch!='Y' && ch!= 'n' && ch!='N' && ch!=13);
	if (ch==13) ch = 'y';
	putch(ch);
	if (ch=='y' || ch=='Y') repeat = true; else repeat = false;

	cputs("\r\n Enter number of colours computer makes choice from(4-9)(Default=7): ");
	do
		{ ch = getch(); }
	while ((ch < '4' || ch > '9') && ch!=13);
	if (ch==13) ch = '7';
	putch(ch);
	types = ch-'0';

	cputs("\r\n Enter the number of guesses you would need (6-10): (Default=10) ");
	do
		{ ch = getch(); }
	while ((ch < '6' || ch > '9') && ch!='1' && ch!=13);
	if (ch==13) ch='1';
	if (ch=='1') { putch('1'); putch('0'); } else putch(ch);
	if (ch=='1') chances = 10; else chances = ch-'0';

	cputs("\r\n\n\n\n Press any key to start game...");
	getch();

	registerbgidriver(EGAVGA_driver);
	int gd = VGA, gm=VGAHI;	//640X480 - 16 color
	initgraph(&gd, &gm, "");

	draw_screen();
	select();
	playgame();

	closegraph();

	}

void playgame()
	{
	int row=1;
	while(row<=chances)
		{
		int col=0, ncol=0;
		bool done=false;
		for(int i=0; i<=3; i++) claim[i] = 0;

		draw_cursor(col, row, CURCOL);
		while (!done)
			{
			char ch;
			if (col!=ncol)
				{
				draw_cursor(col, row, 0);
				col = ncol;
				draw_cursor(col, row, CURCOL);
				}
			switch(ch=getch())
				{
				case 27:
					sound(5000); delay(100); nosound();
					closegraph();
					exit(1);

				case 0:
					switch(getch())
						{
						case 'M':	ncol = (col==3)? 0 : col+1; break;
						case 'K':	ncol = (col==0)? 3 : col-1; break;
						}
					break;

				case '1': case '2': case '3':
				case '4': case '5': case '6':
				case '7': case '8': case '9':
					if ( (ch-'1') <=types-1)
						{
						claim[col] = ch-'1';
						fill_hole(col, row, ch-'1');
						ncol = (col==3)? 0 : col+1; break;
						}
					break;

				case 32:
					claim[col] = (claim[col]==types-1)? 0 : claim[col]+1;
					fill_hole(col, row, claim[col]);
					break;

				case 13:
					justify();
					drawresult(row);
					draw_cursor(col, row, 0);
					row++;
					done = true;
					break;
				}
			}
		if (truematch==4) break;
		}
	if (truematch==4)
		{
		printf("\n\n You Won");
		sound(1000); delay(200); nosound();
		}
	else
		{
		printf("\n\nYou lost");
		sound(300); delay(100); nosound();
		}

	for(int i=0; i<=3; i++)
		fill_hole(i, 0, selected[i]);

	getch();
	}

void draw_screen()
	{
	printf("Number of chances: %d", chances);
	printf("\nNumber of colours in set: %d", types);
	printf("\nRepeat %sallowed.", (repeat)? "" : "not ");

	startx = 320 - (HOLERAD*8 + HOLEXGAP*3)/2;
	starty = 240 - (HOLERAD*22 + HOLEYGAP*10)/2;

	setcolor(HOLECOL);

	for (int r=0; r<=chances; r++)
		for(int c=0; c<=3; c++)
			circle(startx + c*2*HOLERAD + c*HOLEXGAP + HOLERAD,
							starty + HOLERAD*2*r + r*HOLEYGAP + HOLERAD,
								HOLERAD);

	char numstr[2]; numstr[1] = 0;
	for(int count=0; count<=8; count++)
		{
		setcolor(WHITE);
		numstr[0]=48+count+1;
		outtextxy(SETX-20, 10+count*20, numstr);

		setcolor(count);
		circle(SETX, 10+count*20,8);
		setfillstyle(SOLID_FILL, count);
		floodfill(SETX, 10+count*20, count);
		}

	}

void select()
	{
	randomize();

	if (repeat)
		{
		for (int i=0; i<=3; i++)
			selected[i] = random(types);
		return;
		}

	int t; bool flag;
	for (int i=0; i<=3; i++ )
		{
		t=random(types); flag = false;
		for (int j=0; j<=i-1; j++)
			if (t==selected[j]) flag = true;

		if (!flag) selected[i] = t; else i--;
		}

	}

void draw_cursor(int x, int y, int c)
	{
	int x1 = startx + 2*x*HOLERAD + HOLEXGAP*x - HOLEXGAP/2;
	int y1 = starty + 2*y*HOLERAD + HOLEYGAP*y - HOLEYGAP/2;

	int x2 = x1 + 2*HOLERAD + HOLEXGAP;
	int y2 = y1 + 2*HOLERAD + HOLEYGAP;

	setcolor(c);
	rectangle(x1, y1, x2, y2);

	}

void justify()
	{
	int i, j;
	int selover[4] = {0,0,0,0}, claimover[4] = {0,0,0,0};

	truematch=0;
	for (i=0; i<=3; i++)
		if (selected[i] == claim[i])
			{
			selover[i] = claimover[i] = 1;
			truematch++;
			}

	match=0;
	for (i=0; i<=3; i++)
		for (j=0; j<=3; j++)
			if ( (!claimover[i]) && (!selover[j]) )
				if (claim[i] == selected[j])
					{
					match++;
					selover[j] = claimover[i] = 1;
					}

	}

void drawresult(int y)
	{
	int x1=startx+ HOLERAD*2*4 + HOLEXGAP*3 + PEGGRIDGAP;
	int y1=starty+ HOLERAD*2*y + HOLEYGAP*y + HOLERAD/2;


	setcolor(TRUEPEGCOL);
	setfillstyle(SOLID_FILL, TRUEPEGCOL);

	for (int i=0; i<=truematch-1; i++)
		{
		circle(x1+i*2*PEGRAD+i*PEGGAP, y1, PEGRAD);
		floodfill(x1+i*2*PEGRAD+i*PEGGAP, y1, TRUEPEGCOL);
		}

	x1 += (truematch*2*PEGRAD + i*PEGGAP);

	setcolor(PEGCOL);
	setfillstyle(SOLID_FILL, PEGCOL);
	for(i=0; i<=match-1; i++)
		{
		circle(x1+i*2*PEGRAD+i*PEGGAP, y1, PEGRAD);
		floodfill(x1+i*2*PEGRAD+i*PEGGAP, y1, PEGCOL);
		}

	}

void fill_hole(int x, int y, int c)
	{
	setfillstyle(SOLID_FILL, c);

	floodfill(startx + x*2*HOLERAD + x*HOLEXGAP + HOLERAD,
							starty + HOLERAD*2*y + y*HOLEYGAP + HOLERAD,
								HOLECOL);

	}
