/* 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(); }