/*
Mind Killer
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
updated: 9-Apr-04
*/
#include
#include
#include
#include
#include
#include
//program constants(enumerations)
#define USERBOARD 1
#define RANDOMBOARD 2
#define F1_KEY 59
/* MAX_ORDER determines the maximum order of board
user_pos x,y determines the position of userboard (left board)
random_pos x,y determines the position of randomboard (given right board)
*/
#define MAX_ORDER 5
#define user_posx 80
#define user_posy 10
#define random_posx 350
#define random_posy 10
int SIZE;
int order=2;
typedef struct block
{
int left;
int right;
int top;
int bottom;
int fill;
} BLOCK;
union REGS in,out;
BLOCK board[MAX_ORDER][MAX_ORDER];
BLOCK randomboard[MAX_ORDER][MAX_ORDER];
BLOCK userboard[MAX_ORDER][MAX_ORDER];
void Play(void); //main function that uses the following:
//graphics and mouse initializers
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);
void printblock(int x,int y,BLOCK bl); //prints a single block at (x,y)
void makeboard(void); //generates a board
//dislplays the passed board at position x,y
void displayboard(int x, int y, BLOCK b[MAX_ORDER][MAX_ORDER]);
void randomizeboard(void); //randomizes the generated board
/*
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);
int chkboard(void); //checks if the board is solved
void showhelp(void); //displays help
void main(void)
{
clrscr();
textcolor(15);
gotoxy(35,4); cprintf("Mind Killer");
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);
Play();
}
void Play(void)
{
char temp[20];
printf("\n\n\n\t\t\tEnter order(2 to 5) : ");
order=atoi(gets(temp));
SIZE=90-order*10;
if ( order>5 || order<1 )
exit(1);
graph_init();
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);
}
restrictmouseptr(0,0,maxx-9,maxy-9);
showmouseptr();
randomize();
makeboard();
displayboard(user_posx,user_posy,userboard);
randomizeboard();
displayboard(random_posx,random_posy,randomboard);
BLOCK *selected_box=NULL, *click_box=NULL;
int click_x, click_y, click_board;
int selected_x, selected_y, selected_board;
int rec_x=0, rec_y=0;
int block_x,block_y,invalid_move=0;
char ch;
time_t start, current;
char tm[20];
start = time(NULL); /* Gets system time */
float diff, temp_diff;
int clearstatus=0;
while ( 1 )
{
if (selected_box->fill==0 && clearstatus==0)
{
cleardevice();
clearstatus=1;
}
displayboard(user_posx,user_posy,userboard);
displayboard(random_posx,random_posy,randomboard);
outtextxy(100,440,"Press F1 for help");
current = time(NULL); /* Gets system time */
temp_diff=difftime(current, start);
if (temp_diff!=diff || selected_box->fill==0)
{
sprintf(tm, "Time ellapsed=%g secs", temp_diff );
setcolor(0);
setfillstyle(1,0);
fillellipse(100, 420, 100, 10);
setcolor(7);
outtextxy(20,420,tm);
diff=temp_diff;
}
if ( invalid_move==0 ) // if some block has moved
if ( chkboard()==1 )
{
setcolor(15);
outtextxy(100,400,"Congatulations! You have solved the game");
for (int i=100;i<1500;i++)
{
sound(i);
delay(1);
}
nosound();
getch();
closegraph();
return;
}
if (rec_x)
{
setcolor(2);
rectangle(rec_x, rec_y, rec_x+SIZE, rec_y+SIZE);
setcolor(7);
}
delay(10);
if ( kbhit() )
{
if ( (ch=getch())==27 ) // if escape key
break;
if (ch==0) // Special Key
{
char ch2=getch();
if ( ch2==F1_KEY )
showhelp();
}
if ( ch=='\r' ) // if Enter Key then display solution
{
outtextxy(getmaxx()-order*SIZE-20, getmaxy()-order*SIZE-35, "Solution");
displayboard(getmaxx()-order*SIZE-20, getmaxy()-order*SIZE-20, board);
}
}
getmousepos(&button, &x, &y);
if (button==1)
{
clearstatus=0;
click_x=(x-user_posx)/SIZE;
click_y=(y-user_posy)/SIZE;
if ( click_x>=0 && click_y>=0 && click_x<=order-1 && click_y<=order-1 ) // if clicked on userboard
{
rec_x=user_posx+click_x*SIZE+click_x*2;
rec_y=user_posy+click_y*SIZE+click_y*2;
click_box=&userboard[click_y][click_x];
if ( click_box->fill!=0 ) // if clicked on filled box
{
selected_box=click_box;
}
else if ( click_box->fill==0 ) // if clicked on empty box
{
if ( selected_box!=NULL && selected_box->fill!=0) // some box is already selected
{
invalid_move=0;
find_element(userboard, MAX_ORDER, sizeof(userboard[0][0]), click_box, &block_x, &block_y);
selected_box->fill=0;
if ( block_x>0 && userboard[block_y][block_x-1].right!=selected_box->left && userboard[block_y][block_x-1].fill!=0)
invalid_move=1;
else if ( block_xright && userboard[block_y][block_x+1].fill!=0)
invalid_move=1;
else if ( block_y>0 && userboard[block_y-1][block_x].bottom!=selected_box->top && userboard[block_y-1][block_x].fill!=0)
invalid_move=1;
else if ( block_ybottom && userboard[block_y+1][block_x].fill!=0)
invalid_move=1;
if (!invalid_move)
{
*click_box=*selected_box;
// selected_box->fill=0;
click_box->fill=1;
}
else //if (invalid_move)
{
sound(1000);
selected_box->fill=1;
delay(100);
nosound();
}
}
}
}
else // if not clicked on userboard
{
click_x=(x-random_posx)/SIZE;
click_y=(y-random_posy)/SIZE;
if ( click_x>=0 && click_y>=0 && click_x<=order-1 && click_y<=order-1 )
{
rec_x=random_posx+click_x*SIZE+click_x*2;
rec_y=random_posy+click_y*SIZE+click_y*2;
click_box=&randomboard[click_y][click_x];
if ( click_box->fill!=0 ) // if clicked on filled box
{
selected_box=click_box;
}
else // if clicked on empty box
{
if ( selected_box!=NULL && selected_box->fill!=0) // some box is already selected
{
*click_box=*selected_box;
selected_box->fill=0;
}
}
} // end if clicked on randomboard
} // end if not clicked on userboard
} // end if (button==1)
}
closegraph();
}
void graph_init(void)
{
/* request auto detection */
int gdriver = DETECT, gmode, errorcode;
/* initialize graphics and local variables */
initgraph(&gdriver, &gmode, "..\\bgi");
/* read result of initialization */
errorcode = graphresult();
/* an error occurred */
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 printblock(int x,int y,BLOCK bl)
{
rectangle(x,y,x+SIZE,y+SIZE);
setlinestyle(1,1,1);
line(x,y,x+SIZE,y+SIZE);
line(x+SIZE,y,x,y+SIZE);
if ( bl.fill!=0 )
{
char temp[5];
sprintf(temp, "%d", bl.left);
outtextxy(x+5,y+SIZE/2-2, temp);
sprintf(temp, "%d", bl.right);
outtextxy(x+SIZE-10,y+SIZE/2-2, temp);
sprintf(temp, "%d", bl.top);
outtextxy(x+SIZE/2-2,y+5, temp);
sprintf(temp, "%d", bl.bottom);
outtextxy(x+SIZE/2-2,y+SIZE-10, temp);
}
setlinestyle(0,1,1);
}
void makeboard(void)
{
for (int i=0;i0 && userboard[i][j].left!=userboard[i][j-1].right)
return 0;
if (i>0 && userboard[i][j].top!=userboard[i-1][j].bottom)
return 0;
if (j during the game displays one possible solution of the board.");
setcolor(15);
outtextxy(200,300, "Press any key to return to game");
getch();
setcolor(7);
cleardevice();
}
               (
geocities.com/smehrozalam)