Mind Fighter
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>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_y
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;i
rectangle(x+j*SIZE, y+i*SIZE, x+j*SIZE+SIZE, y+i*SIZE+SIZE);
if ( board[i][j]==ball[0] )
{
setfillstyle(1,ColorP1);
fillellipse(x+j*SIZE+SIZE/2, y+i*SIZE+SIZE/2, SIZE/2-5, SIZE/2-5);
}
if ( board[i][j]==ball[1] )
{
setfillstyle(1,ColorP2);
fillellipse(x+j*SIZE+SIZE/2, y+i*SIZE+SIZE/2, SIZE/2-5, SIZE/2-5);
}
}
}
int find_element(void *starting_add, int cols, int size, void *element_add, int *x, int *y)
{
*y=( (char*)element_add - (char*)starting_add) / (size * cols);
*x=( (char*)element_add - (char*)starting_add - (*y)*size*cols) / (size);
return 1;
}
int chkboard(void)
{
int p1_balls=0,p2_balls=0, balls_empty=0;
for (int i=0;i
if (board[i][j]==empty)
balls_empty++;
else if (board[i][j]==ball[0])
p1_balls++;
else if (board[i][j]==ball[1])
p2_balls++;
}
// if board is filled chk who won
::balls1=p1_balls;
::balls2=p2_balls;
if (balls_empty && p1_balls!=0 && p2_balls!=0)
return 0;
char temp[30];
sprintf( temp, "White balls: %d", p1_balls );
outtextxy(400, 10, temp);
sprintf( temp, "Blue balls: %d", p2_balls );
outtextxy(400, 20, temp);
if (p1_balls>p2_balls)
outtextxy(400,40,"Player 1(White) won");
else if (p1_balls
else if (p1_balls==p2_balls)
outtextxy(400,40,"Draw");
getch();
closegraph();
exit(0);
}
void copy_board(int srcboard[][MAX_ORDER], int newboard[][MAX_ORDER])
{
for (int i=0;i
}
int chk_playerpos(int player)
{
int player_balls=0;
int current_ball=ball[player];
for (int i=0;i
if (board[i][j]==current_ball)
{
player_balls+=BallValue+(::move/STATE);
if (board[i-1][j-1]==current_ball)
player_balls++;
if (board[i-1][j]==current_ball)
player_balls++;
if (board[i][j-1]==current_ball)
player_balls++;
if (board[i+1][j+1]==current_ball)
player_balls++;
if (board[i+1][j]==current_ball)
player_balls++;
if (board[i][j+1]==current_ball)
player_balls++;
if (board[i+1][j-1]==current_ball)
player_balls++;
if (board[i-1][j+1]==current_ball)
player_balls++;
// player_balls+= board[i-1][j-1]==current_ball + board[i-1][j]==ball[1] + board[i][j-1]==ball[1] + board[i+1][j+1]==ball[1] + board[i+1][j]==ball[1] + board[i][j+1]==ball[1] + board[i+1][j-1]==ball[1] + board[i-1][j+1]==ball[1] ;
}
}
return player_balls;
}
void computer_move(int level, int move, int player)
{
int temp_pos, pos=0, best_x1,best_y1,best_x2,best_y2;
int temp_board[MAX_ORDER][MAX_ORDER];
copy_board(board, temp_board);
for (int i=0;i
{
for (int k=i-2; k<=i+2 ; k++)
for (int l=j-2; l<=j+2 ; l++)
{
if (k<0>order-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_pos
best_x1=j; best_y1=i;
best_x2=l; best_y2=k;
pos=temp_pos;
}
copy_board(temp_board, board);
}
}
delay(1000);
do_move(best_x1,best_y1, best_x2,best_y2, move);
setfillstyle(1,3);
fillellipse(board_posx+best_x1*SIZE+SIZE/2, board_posy+best_y1*SIZE+SIZE/2, SIZE/2-5, SIZE/2-5);
delay(500);
setfillstyle(1,3);
fillellipse(board_posx+best_x2*SIZE+SIZE/2, board_posy+best_y2*SIZE+SIZE/2, SIZE/2-5, SIZE/2-5);
delay(500);
}
void do_move(int x1,int y1, int x2,int y2, int move)
{
board[y2][x2]=ball[move%2];
if ( y2
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>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
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();
}
No comments:
Post a Comment