/*

Mind Fighter
by Syed Mehroz Alam,

CIS-61, First Year, Sec-A, Batch 2002-03
Computer & Information Systems Dept,
NED University, Karachi, Pakistan.
Email: smehrozalam@yahoo.com

Date: 13-Dec-03
*/

#include
#include
#include
#include
#include
#include

#define MAX_ORDER 10
#define SIZE 50
#define board_posx 10
#define board_posy 10
#define player1 1
#define player2 2
#define empty 0
#define BallValue 1
#define STATE 5
#define F1_KEY 59
#define ColorP1 7
#define ColorP2 1



int order=7;
int balls1=0,balls2=0;
int board[MAX_ORDER][MAX_ORDER];
int ball[2]={player1, player2};
int computer=1;
int computer_level=1;
union REGS in,out;
int move;

//initializers for graphics mode and mouse
void graph_init(void);
int initmouse(void);
void showmouseptr(void);
void restrictmouseptr(int x1, int y1, int x2, int y2);
void getmousepos(int *button, int *x, int *y);

//displays the current position of board at (x,y)
void displayboard(int x, int y);

/*
the function returns the index of an element in a 2D array if its
starting address, size, no. of cols, and the given element's address is given
its a generic function that can be used for any type of array(int, char, etc)
*/
int find_element(void *starting_add, int cols, int size, void *element_add, int *x, int *y);

//checks if any player had won
int chkboard(void);
void ShowHelp(void);

/*
moves from (x1,y1) to (x2,y2),
move is the current move(helps to determine the current player)
*/

void do_move(int x1,int y1, int x2,int y2, int move);

/*
returns the position (how much good or bad) for a player
according to current situation of board
helps to determine the computer move
*/
int chk_playerpos(int player);

// determines the move for computer
void computer_move(int level, int move, int player);

/*
replicates a board,
used for determing computer move as the computer_move() uses simulation
*/
void copy_board(int srcboard[][MAX_ORDER], int newboard[][MAX_ORDER]);


void main(void)
{
	clrscr();
	textcolor(15);
	gotoxy(35,4); cprintf("Mind Fighter");
	gotoxy(35,5); cprintf("様様様様様様");
	gotoxy(31,7); cprintf("by Syed Mehroz Alam");
	gotoxy(20,9);  cprintf("CIS-61, First Year, Sec-A, Batch 2002-03");
	gotoxy(20,10); cprintf("  Computer & Information Systems Dept,");
	gotoxy(20,11); cprintf("   NED University, Karachi, Pakistan.");
	gotoxy(20,13); cprintf("     Email: smehrozalam@yahoo.com");
	gotoxy(20,16); cprintf("     Press any key to begin......");
	getch();
	textcolor(7);
	printf("\n\n\t\tPlay versus Computer (y/n) ");
	char ch;
	if ( (ch=getch())=='n' || ch=='N' )
		computer=3;
	else
	{
		printf("\n\t\tComputer is player 1(white) or 2(blue) ");
		if ( (ch=getch())=='1' )
			computer=0;
		else
			computer=1;
	}
	graph_init();
//	setbkcolor(3);

	int maxx=getmaxx(), maxy=getmaxy(), x, y, button;
	if (initmouse()==0)
	{
		outtextxy(400,425, "Can't Initialize Mouse..");
		outtextxy(400,450, "Press any key to exit...");
		getch();
		closegraph();
		exit(0);
	}
	int click_x, click_y,i,j,temp_x, temp_y,move=0,x1,y1;
	int *selected=NULL;

	board[0][0]=board[order-1][order-1]=ball[0];
	board[0][order-1]=board[order-1][0]=ball[1];
	restrictmouseptr(0,0,maxx-9,maxy-9);
	showmouseptr();
	displayboard(board_posx, board_posy);
	int balls1,balls2;
	while ( 1 )
	{
		chkboard();
		if (::balls1!=balls1 || ::balls2!=balls2)
		{
			balls1=::balls1;
			balls2=::balls2;
			char temp[30];
			setcolor(0);
			setfillstyle(1,0);
			fillellipse(450,20,100,10);
			setcolor(7);
			sprintf( temp, "White balls: %d", balls1 );
			outtextxy(400, 10, temp);
			sprintf( temp, "Blue balls: %d", balls2 );
			outtextxy(400, 20, temp);
		}

		if ( kbhit() )
		{
			if ( (ch=getch())==27 ) // if escape key
				break;
			if (ch=='\r') // if enter then move given to other player
			{
				move++;
				selected=NULL;
			}

			if (ch==0)	// if special key
				if ( (ch=getch())==F1_KEY )
				{
					ShowHelp();
					displayboard(board_posx, board_posy);
					char temp[30];
					setcolor(0);
					setfillstyle(1,0);
					fillellipse(450,20,100,10);
					setcolor(7);
					sprintf( temp, "White balls: %d", balls1 );
					outtextxy(400, 10, temp);
					sprintf( temp, "Blue balls: %d", balls2 );
					outtextxy(400, 20, temp);
				}
		}
		if (computer==move%2)	// if computer's move
		{
			computer_move(computer_level, move, move%2);
			move++;
			cleardevice();
			displayboard(board_posx, board_posy);
		}
		getmousepos(&button, &x, &y);
//		if (selected==NULL)
//			displayboard(board_posx, board_posy);
		if (button==1 && temp_x!=x && temp_y!=y)
			{
				click_x=(x-board_posx)/SIZE;
				click_y=(y-board_posy)/SIZE;
				temp_x=x;
				temp_y=y;

				if ( click_x>=0 && click_y>=0 && click_x<=order-1 && click_y<=order-1 ) // if clicked inside board
				{
					if ( board[click_y][click_x]==ball[move%2] ) // if clicked on current player's ball
					{
						cleardevice();
						displayboard(board_posx, board_posy);
//						printf("sel=(%d,%d)",click_y, click_x);
						selected=&board[click_y][click_x];
						setcolor(2);
						ellipse(board_posx+click_x*SIZE+SIZE/2, board_posy+click_y*SIZE+SIZE/2, 0, 360, SIZE/2-5, SIZE/2-5);
						for (i=click_y-2 ; i<=click_y+2 ; i++)
							for (j=click_x-2 ; j<=click_x+2 ; j++)
							{
								if (i<0 || j<0 || i>order-1 || j>order-1 || board[i][j]!=empty)
									continue;
								rectangle(board_posx+j*SIZE, board_posy+i*SIZE, board_posx+j*SIZE+SIZE, board_posy+i*SIZE+SIZE);
							}
						setcolor(15);
					}	// end if clicked on current player's ball
					else if ( board[click_y][click_x]==empty && selected!=NULL ) // if made a move
					{
						find_element(board, MAX_ORDER, sizeof(board[0][0]), selected, &x1, &y1);
						if ( click_yy1+2 || click_xx1+2 )  // if incorrect move
							continue;	// dont move
						// else if correct move
						setfillstyle(1,3);
						fillellipse(board_posx+click_x*SIZE+SIZE/2, board_posy+click_y*SIZE+SIZE/2, SIZE/2-5, SIZE/2-5);
						delay(500);

						do_move(x1, y1, click_x,click_y, move);
						selected=NULL;
						move++;
						cleardevice();
						displayboard(board_posx, board_posy);
					}
				}	// end if clicked inside board;

			}	// end if (button==1)
	}
	closegraph();
}

void graph_init(void)
{
   int gdriver = DETECT, gmode, errorcode;
   initgraph(&gdriver, &gmode, "..\\bgi");
   errorcode = graphresult();
   if (errorcode != grOk)
   {
	  printf("Graphics error: %s\n", grapherrormsg(errorcode));
	  printf("Press any key to halt:");
	  getch();
	  exit(1);    /* terminate with an error code */
   }
}

int initmouse(void)
{
	in.x.ax=0;
	int86(0x33,&in, &out);
	return(out.x.ax);
}

void showmouseptr(void)
{
	in.x.ax=1;
	int86(0x33, &in, &out);
}

void restrictmouseptr(int x1, int y1, int x2, int y2)
{
	in.x.ax=7;
	in.x.cx=x1;
	in.x.dx=x2;
	int86(0x33,&in, &out);
	in.x.ax=8;
	in.x.cx=y1;
	in.x.dx=y2;
	int86(0x33, &in, &out);
}

void getmousepos(int *button, int *x, int *y)
{
	in.x.ax=3;
	int86(0x33, &in, &out);
	*button=out.x.bx;
	*x=out.x.cx;
	*y=out.x.dx;
}

void displayboard(int x, int y)
{
	setcolor(15);
	outtextxy(100,440,"Press F1 for help");

	for (int i=0;ip2_balls)
		outtextxy(400,40,"Player 1(White) won");
	else if (p1_ballsorder-1 || l>order-1 || board[k][l]!=empty)
							continue;
						do_move(j,i,l,k,move);
						::move=move;
						temp_pos=chk_playerpos(player);
/*			cleardevice();
			displayboard(board_posx, board_posy);
			char temp[10];
			sprintf(temp, "pos2=%d",temp_pos);
			outtextxy(500,300,temp);
			setcolor(0);
			setfillstyle(1,0);
			fillellipse(550,320,70,10);
			setcolor(7);
//			getch();
*/
						if (temp_pos>pos)
//						if ( (player==1 && temp_pos>pos)  || (player==0 && temp_posy1+1 || x2x1+1 )  // if not adjacent
		board[y1][x1]=empty;	// then jump i.e. erase previous ball

	// capture all adjacent opposite players' balls
	for (int i=y2-1 ; i<=y2+1; i++)
		for (int j=x2-1 ; j<=x2+1; j++)
			{
			if (i<0 || j<0 || i>order-1 || j>order-1 || board[i][j]==empty )
				continue;
			else
				board[i][j]=ball[move%2];
			}
}

void ShowHelp(void)
{
	cleardevice();
	setcolor(7);
	outtextxy(10,20, "The aim of this game is to have your balls greater in number than your");
	outtextxy(10,35, "opponents', until the board fills up or until your opponent has lost all");
	outtextxy(10,50, "his balls. When you move your ball to an adjacent square(out of 8), it");
	outtextxy(10,65, "replicates itself. When you move one level higher(the next 16 boxes), the");
	outtextxy(10,80, "ball jumps from its original position and loses its previous place.");
	outtextxy(10,95, "Whenever you move, you capture all your opponents balls adjacent to your ball.");
	outtextxy(10,130, "How To Play:");
	outtextxy(10,145, "Whenever a ball is clicked, its possible moves are highlighted. Click on the");
	outtextxy(10,160, "target box to place your ball on it.");
	outtextxy(10,175, "Pressing  during the game play cancels the current player's move");
	outtextxy(10,190, " (useful if you have no legal move left).");
	setcolor(15);
	outtextxy(200,300, "Press any key to return to game");
	getch();
	setcolor(7);
	cleardevice();
}

    Source: geocities.com/smehrozalam/source

               ( geocities.com/smehrozalam)