home *** CD-ROM | disk | FTP | other *** search
- #include <conio.h>
- #include <graphics.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #include <ctype.h>
- #include "mouse.c"
-
- #define YES 1
- #define NO 0
-
- #define XPX 15 /* X pixels by square */
- #define YPX 15 /* Y pixels by square */
-
- #define DEFCX 30 /* Default number of squares */
- #define DEFCY 28
-
- #define MINE 255-'0' /* So that when it prints, it prints char 0xff */
-
- #define STSQUARE struct stsquare
-
- STSQUARE {
- unsigned char value; /* Number of mines in the surround squares */
- unsigned char sqopen; /* Square is open */
- unsigned char sqpress; /* Square is pressed */
- unsigned char sqmark; /* Square is marked */
- } *psquare;
-
- #define value(x,y) (psquare+(x)*ncy+(y))->value
- #define sqopen(x,y) (psquare+(x)*ncy+(y))->sqopen
- #define sqpress(x,y) (psquare+(x)*ncy+(y))->sqpress
- #define sqmark(x,y) (psquare+(x)*ncy+(y))->sqmark
-
- int XST, /* Offset of first pixel X */
- YST,
- ncx, /* Number of squares in X */
- ncy,
- cmines, /* Mines discovered */
- initmines, /* Number of initial mines */
- sqclosed, /* Squares still closed */
- maxy; /* Max. number of y pixels of the screen */
-
- void Graph_init(void);
- void Read_param(int argc, char *argv[]);
- void Set_mines(int nminas);
- void Set_square(int x, int y, int status);
- void Mouse_set(void);
- void Draw_squares(void);
- int Do_all(void);
- void Blow_up(void);
- void Open_square(int x, int y);
- int Open_near_squares(int x, int y);
-
- /************************************************************************/
-
- void main(int argc, char *argv[])
- {
- if (!mouse_reset()) {
- cputs(" ERROR: I can't find a mouse driver\r\n");
- exit(2);
- }
- Graph_init();
- Read_param(argc, argv);
- Mouse_set();
- do {
- randomize();
- cleardevice();
- Set_mines(cmines=initmines);
- mouse_enable();
- Draw_squares();
- }
- while (Do_all() != '\x1b');
- closegraph();
- }
-
- /*************************************************************************
- * *
- * F U N C T I O N S *
- * *
- *************************************************************************/
-
- /*----------------------------------------------------------------------*/
-
- void Graph_init(void)
- {
- int graphdriver=DETECT, graphmode, errorcode;
-
- errorcode=registerbgidriver(EGAVGA_driver);
- if(errorcode < 0) {
- cprintf("\n\rGraphics System Error: %s\n",grapherrormsg(errorcode));
- exit(98);
- }
- initgraph(&graphdriver, &graphmode, "");
- errorcode=graphresult();
- if(errorcode!=grOk) {
- printf(" Graphics System Error: %s\n",grapherrormsg(errorcode));
- exit(98);
- }
- maxy=getmaxy();
- } /* Graph_init */
-
- /*----------------------------------------------------------------------*/
-
- void Read_param(int argc, char *argv[])
- {
- int x, y, m;
-
- x=y=m=0;
- if (argc!=1) {
- if (!isdigit(*argv[1])) {
- closegraph();
- cprintf("Usage is: %s [x] [y] [m]\r\n\n"
- "Where x is the horizontal size\r\n"
- " y is the vertical size\r\n"
- " m is the number of mines\r\n\n"
- " Left mouse button: Open the square\r\n"
- "Right mouse button: Mark the square\r\n"
- " -The first time puts a 'mine' mark\r\n"
- " -The second time puts a 'possible "
- "mine' mark\r\n"
- " -The third time unmarks the square\r\n"
- "Left+Right buttons: Open the surrounded squares only if "
- "the count of mines\r\n"
- " is equal to the number in the square",argv[0]);
- exit (1);
- }
- switch (argc) {
- case 4: m=atoi(argv[3]);
- case 3: y=atoi(argv[2]);
- case 2: x=atoi(argv[1]);
- }
- }
- XST=100;
- ncx=DEFCX;
- if (maxy==479) {
- YST=30;
- ncy=DEFCY;
- }
- else {
- YST=25;
- ncy=20;
- }
- if (x>0 && x<ncx)
- ncx=x;
- if (y>0 && y<ncy) {
- YST+=((ncy-y)*YPX)>>1;
- ncy=y;
- }
- initmines= m ? m : ncx*ncy*4/25; /* There are about 16% of mines */
- if ((psquare=calloc(ncx*ncy, sizeof(STSQUARE)))==NULL) {
- closegraph();
- cputs("ERROR: Not enought memory");
- exit(3);
- }
- } /* Read_param */
-
- /*----------------------------------------------------------------------*/
-
- void Set_mines(int nminas)
- {
- STSQUARE *p;
- int i, x, y, a, b;
-
- sqclosed=ncx*ncy-nminas;
- p=psquare;
- for (i=ncx*ncy; i>0; i--, p++)
- p->value = p->sqopen = p->sqpress = p->sqmark = NO;
- for (i=nminas; i>0; i--) {
- while (value(x=random(ncx), y=random(ncy)) == MINE)
- ;
- value(x,y)=MINE;
- }
- for (x=ncx-1; x>=0; x--) {
- for (y=ncy-1; y>=0; y--) {
- if (value(x,y) == MINE)
- continue;
- a=x-1;
- b=y-1;
- if (a>=0 && b>=0 && a<ncx && b<ncy)
- value(x,y)+=(value(a,b) == MINE);
- a++;
- if (a>=0 && b>=0 && a<ncx && b<ncy)
- value(x,y)+=(value(a,b) == MINE);
- a++;
- if (a>=0 && b>=0 && a<ncx && b<ncy)
- value(x,y)+=(value(a,b) == MINE);
- b++;
- if (a>=0 && b>=0 && a<ncx && b<ncy)
- value(x,y)+=(value(a,b) == MINE);
- a-=2;
- if (a>=0 && b>=0 && a<ncx && b<ncy)
- value(x,y)+=(value(a,b) == MINE);
- b++;
- if (a>=0 && b>=0 && a<ncx && b<ncy)
- value(x,y)+=(value(a,b) == MINE);
- a++;
- if (a>=0 && b>=0 && a<ncx && b<ncy)
- value(x,y)+=(value(a,b) == MINE);
- a++;
- if (a>=0 && b>=0 && a<ncx && b<ncy)
- value(x,y)+=(value(a,b) == MINE);
- }
- }
- } /* Set_mines */
-
- /*----------------------------------------------------------------------*/
-
- /*
- If status=1 then draw the square up, if it's 0 then draw it down
- */
- void Set_square(int x, int y, int status)
- {
- int xl, xr, yt, yb;
-
- mouse_disable();
- xl=XST+XPX*x;
- xr=xl+XPX-1;
- yt=YST+YPX*y;
- yb=yt+YPX-1;
- setfillstyle(SOLID_FILL, LIGHTGRAY);
- bar(xl, yt, xr, yb);
- if (status) {
- setcolor(WHITE);
- line(xl,yt,xl,yb-1);
- line(xl,yt,xr-1,yt);
- setcolor(DARKGRAY);
- line(xr,yb,xl,yb);
- line(xr,yb,xr,yt);
- switch (sqmark(x,y)) {
- case 2 : setfillstyle(SOLID_FILL, LIGHTBLUE);
- setcolor(LIGHTBLUE);
- break;
- case 1 : setfillstyle(SOLID_FILL, LIGHTRED);
- setcolor(LIGHTRED);
- break;
- default: setcolor(LIGHTGRAY);
- }
- fillellipse(XST+XPX*x+XPX/2, YST+YPX*y+YPX/2, 3, 3);
- switch (sqmark(x,y)) {
- case 2 :
- case 1 : setfillstyle(SOLID_FILL, YELLOW);
- setcolor(YELLOW);
- fillellipse(XST+XPX*x+XPX/2, YST+YPX*y+YPX/2, 1, 1);
- }
- }
- else {
- sqclosed--;
- setcolor(DARKGRAY);
- line(xl,yt,xl,yb);
- line(xl,yt,xr,yt);
- }
- mouse_enable();
- } /* Set_square */
-
- /*----------------------------------------------------------------------*/
-
- void Mouse_set(void)
- {
- mouse_horizontal_range(XST, XST+XPX*ncx-3);
- mouse_vertical_range(YST, YST+YPX*ncy-3);
- } /* Mouse_set */
-
- /*----------------------------------------------------------------------*/
-
- void Draw_squares(void)
- {
- int x, y;
-
- mouse_disable();
- for (x=0; x<ncx; x++)
- for (y=0; y<ncy; y++)
- Set_square(x,y,1);
- mouse_enable();
- } /* Draw_squares */
-
- /*----------------------------------------------------------------------*/
-
- /*
- Here we do all the job
- */
- int Do_all(void)
- {
- int x, y, xant=-1, yant, mlstant, mrstant, cminasant=0, ttrans, tant=0;
- long tst, tact;
- char str[] ="xxxxx: 0000",
- blk[] ="███████████";
-
- mouse_enable();
- time(&tst);
- while (!kbhit()) {
- if (!sqclosed && !mouse_status) { /* All mines discovered */
- settextjustify(LEFT_TEXT, CENTER_TEXT);
- setcolor(BLACK);
- outtextxy(0, maxy/2-10, blk);
- sprintf(str,"Mines: 0");
- setcolor(LIGHTRED);
- outtextxy(0, maxy/2-10, str);
- settextjustify(LEFT_TEXT, CENTER_TEXT);
- setcolor(BLACK);
- outtextxy(0, maxy/2+10, blk);
- sprintf(str," Time: %4d",ttrans);
- setcolor(LIGHTGREEN);
- outtextxy(0, maxy/2+10, str);
- for (x=ncx-1; x>=0; x--)
- for (y=ncy-1; y>=0; y--)
- if (value(x,y)==MINE) {
- sqmark(x,y)=1;
- Set_square(x,y,1);
- }
- break;
- }
- if (cminasant != cmines) { /* Update Mines: */
- cminasant=cmines;
- settextjustify(LEFT_TEXT, CENTER_TEXT);
- setcolor(BLACK);
- outtextxy(0, maxy/2-10, blk);
- sprintf(str,"Mines: %4d",cmines);
- setcolor(LIGHTRED);
- outtextxy(0, maxy/2-10, str);
- }
- if (tant != (ttrans=(int)(time(&tact)-tst))) { /* Update Time: */
- tant=ttrans;
- settextjustify(LEFT_TEXT, CENTER_TEXT);
- setcolor(BLACK);
- outtextxy(0, maxy/2+10, blk);
- sprintf(str," Time: %4d",ttrans);
- setcolor(LIGHTRED);
- outtextxy(0, maxy/2+10, str);
- }
- mouse_read_cursor();
- mouse_status&=3;
- x=(mouse_x-XST)/XPX;
- y=(mouse_y-YST)/YPX;
- if (xant == -1) {
- xant=x;
- yant=y;
- }
- if (x!=xant || y!=yant) { /* Position change */
- if (sqpress(xant,yant) && !sqopen(xant,yant)) {
- sqpress(xant,yant)=NO;
- Set_square(xant,yant,1);
- }
- xant=x;
- yant=y;
- }
- if (!mouse_status)
- mlstant=mrstant=0;
- if ((mouse_status == 2) &&
- !sqopen(x,y) &&
- mlstant!=mouse_status) { /* Right button pressed */
- mlstant=mouse_status;
- mouse_disable();
- switch (sqmark(x,y)=(sqmark(x,y)+1) % 3) {
- case 1 : cmines--; break;
- case 2 : cmines++;
- }
- Set_square(x,y,1);
- mouse_enable();
- }
- else if (mouse_status==1 && /* Left button pressed */
- !sqopen(x,y) &&
- !sqpress(x,y) && /* And square not pressed */
- sqmark(x,y)!=1) {
- sqpress(x,y)=YES;
- Set_square(x,y,0);
- }
- else if (!mouse_status && /* Left button released */
- !sqopen(x,y) &&
- sqpress(x,y) &&
- sqmark(x,y)!=1) { /* Open the square */
- if (value(x,y) == MINE) {
- Blow_up();
- break;
- }
- else
- Open_square(x,y);
- }
- else if (mouse_status==3 &&
- sqopen(x,y) &&
- mrstant!=mouse_status) { /* Open near squares */
- mrstant=mouse_status;
- if (Open_near_squares(x,y) == YES) {
- Blow_up();
- break;
- }
- }
- }
- mouse_disable();
- return (getch());
- } /* Do_all */
-
- /*----------------------------------------------------------------------*/
-
- void Blow_up(void)
- {
- int x, y, xl, yt, xr, yb;
-
- mouse_disable();
- for (x=0; x<ncx; x++) {
- for (y=0; y<ncy; y++) {
- if (value(x,y) == MINE) {
- settextjustify(CENTER_TEXT, CENTER_TEXT);
- setcolor(LIGHTRED);
- outtextxy(XST+XPX*x+XPX/2-1, YST+YPX*y+YPX/2, "█");
- setcolor(BLACK);
- outtextxy(XST+XPX*x+XPX/2, YST+YPX*y+YPX/2+1, "*");
- }
- else if (sqmark(x,y)==1) {
- setcolor(YELLOW);
- xl=XST+XPX*x;
- xr=xl+XPX-1;
- yt=YST+YPX*y;
- yb=yt+YPX-1;
- line(xl,yt,xr,yb);
- line(xl,yb,xr,yt);
- }
- }
- }
- } /* Blow_up */
-
- /*----------------------------------------------------------------------*/
-
- void Open_square(int x, int y)
- {
- char num[2]="0";
- int a, b, c;
-
- sqopen(x,y)=YES;
- if ((num[0]=value(x,y)) != 0) {
- num[0]+='0';
- switch(num[0]) {
- case '1' : c=LIGHTBLUE; break;
- case '2' : c=LIGHTGREEN; break;
- case '3' : c=YELLOW; break;
- case '4' : c=LIGHTRED; break;
- default : c=LIGHTMAGENTA;
- }
- mouse_disable();
- setcolor(c);
- settextjustify(CENTER_TEXT, CENTER_TEXT);
- outtextxy(XST+XPX*x+XPX/2, YST+YPX*y+YPX/2+1, num);
- mouse_enable();
- }
- else { /* Open near squares if the current number is 0 */
- a=x-1;
- b=y-1;
- if (a>=0 && b>=0 && a<ncx && b<ncy && !sqopen(a,b) && sqmark(a,b)!=1) {
- Set_square(a,b,0);
- Open_square(a,b);
- }
- a++;
- if (a>=0 && b>=0 && a<ncx && b<ncy && !sqopen(a,b) && sqmark(a,b)!=1) {
- Set_square(a,b,0);
- Open_square(a,b);
- }
- a++;
- if (a>=0 && b>=0 && a<ncx && b<ncy && !sqopen(a,b) && sqmark(a,b)!=1) {
- Set_square(a,b,0);
- Open_square(a,b);
- }
- b++;
- if (a>=0 && b>=0 && a<ncx && b<ncy && !sqopen(a,b) && sqmark(a,b)!=1) {
- Set_square(a,b,0);
- Open_square(a,b);
- }
- a-=2;
- if (a>=0 && b>=0 && a<ncx && b<ncy && !sqopen(a,b) && sqmark(a,b)!=1) {
- Set_square(a,b,0);
- Open_square(a,b);
- }
- b++;
- if (a>=0 && b>=0 && a<ncx && b<ncy && !sqopen(a,b) && sqmark(a,b)!=1) {
- Set_square(a,b,0);
- Open_square(a,b);
- }
- a++;
- if (a>=0 && b>=0 && a<ncx && b<ncy && !sqopen(a,b) && sqmark(a,b)!=1) {
- Set_square(a,b,0);
- Open_square(a,b);
- }
- a++;
- if (a>=0 && b>=0 && a<ncx && b<ncy && !sqopen(a,b) && sqmark(a,b)!=1) {
- Set_square(a,b,0);
- Open_square(a,b);
- }
- }
- } /* Open_square */
-
- /*----------------------------------------------------------------------*/
-
- /*
- Open the sorrounded squares. Returns != 0 if I activated a mine
- */
- int Open_near_squares(int x, int y)
- {
- int a, b, suma=0;
-
- a=x-1;
- b=y-1;
- if (a>=0 && b>=0 && a<ncx && b<ncy && sqmark(a,b)==1)
- suma++;
- a++;
- if (a>=0 && b>=0 && a<ncx && b<ncy && sqmark(a,b)==1)
- suma++;
- a++;
- if (a>=0 && b>=0 && a<ncx && b<ncy && sqmark(a,b)==1)
- suma++;
- b++;
- if (a>=0 && b>=0 && a<ncx && b<ncy && sqmark(a,b)==1)
- suma++;
- a-=2;
- if (a>=0 && b>=0 && a<ncx && b<ncy && sqmark(a,b)==1)
- suma++;
- b++;
- if (a>=0 && b>=0 && a<ncx && b<ncy && sqmark(a,b)==1)
- suma++;
- a++;
- if (a>=0 && b>=0 && a<ncx && b<ncy && sqmark(a,b)==1)
- suma++;
- a++;
- if (a>=0 && b>=0 && a<ncx && b<ncy && sqmark(a,b)==1)
- suma++;
- if (suma == value(x,y)) {
- suma=0;
- a=x-1;
- b=y-1;
- if (a>=0 && b>=0 && a<ncx && b<ncy && !sqopen(a,b) && sqmark(a,b)!=1) {
- suma|=(value(a,b)==MINE);
- Set_square(a,b,0);
- Open_square(a,b);
- }
- a++;
- if (a>=0 && b>=0 && a<ncx && b<ncy && !sqopen(a,b) && sqmark(a,b)!=1) {
- suma|=(value(a,b)==MINE);
- Set_square(a,b,0);
- Open_square(a,b);
- }
- a++;
- if (a>=0 && b>=0 && a<ncx && b<ncy && !sqopen(a,b) && sqmark(a,b)!=1) {
- suma|=(value(a,b)==MINE);
- Set_square(a,b,0);
- Open_square(a,b);
- }
- b++;
- if (a>=0 && b>=0 && a<ncx && b<ncy && !sqopen(a,b) && sqmark(a,b)!=1) {
- suma|=(value(a,b)==MINE);
- Set_square(a,b,0);
- Open_square(a,b);
- }
- a-=2;
- if (a>=0 && b>=0 && a<ncx && b<ncy && !sqopen(a,b) && sqmark(a,b)!=1) {
- suma|=(value(a,b)==MINE);
- Set_square(a,b,0);
- Open_square(a,b);
- }
- b++;
- if (a>=0 && b>=0 && a<ncx && b<ncy && !sqopen(a,b) && sqmark(a,b)!=1) {
- suma|=(value(a,b)==MINE);
- Set_square(a,b,0);
- Open_square(a,b);
- }
- a++;
- if (a>=0 && b>=0 && a<ncx && b<ncy && !sqopen(a,b) && sqmark(a,b)!=1) {
- suma|=(value(a,b)==MINE);
- Set_square(a,b,0);
- Open_square(a,b);
- }
- a++;
- if (a>=0 && b>=0 && a<ncx && b<ncy && !sqopen(a,b) && sqmark(a,b)!=1) {
- suma|=(value(a,b)==MINE);
- Set_square(a,b,0);
- Open_square(a,b);
- }
- return (suma);
- }
- else
- return 0;
- } /* Open_near_squares */
-