#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <graphics.h>
#include <time.h>
#define LEFT 75
#define RIGHT 77
#define UP 72
#define DOWN 80
#define MAXX 30
#define MAXY 16
int curx,cury;
int grid[MAXX][MAXY];
#define BLANK 0
#define MINE 1
#define OPENED 2
#define MARKED 4
int opened;
int marked;
int totalmines;
#define XSTART 70
#define YSTART 80
#define GRID 16
#define BARX 70
#define BARY 40
#define FACEX 200
#define FACEY 50
#define NUMX 300
#define NUMY 50
int Init(void);
int Deinit(void);
int OpenGrid(int,int);
int MarkGrid(int,int);
int ShowCur(void);
int HideCur(void);
int CalcMines(int,int);
int DrawFigure(int,int,int);
int DrawBar(void);
int DrawBack(void);
int DrawMarker(int,int);
int RemoveMarker(int,int);
int Validate(int,int);
int OpenAll(void);
int OpenLeft(int,int);
int CalcMarks(int,int);
int main()
{
char ch;
Init();
while (1)
{
ch=getch();
HideCur();
switch(ch)
{
case 0:
ch=getch();
switch (ch)
{
case LEFT:
if (--curx<0)
curx=0;
break;
case RIGHT:
if (++curx==MAXX)
curx=MAXX-1;
break;
case UP:
if (--cury<0)
cury=0;
break;
case DOWN:
if (++cury==MAXY)
cury=MAXY-1;
break;
default:
break;
}
break;
case 27:
Deinit();
break;
case 13:
switch (OpenGrid(curx,cury))
{
case 1:
circle(FACEX+8,FACEY+8,8);
break;
case -1:
OpenAll();
break;
default:
break;
}
break;
case 32:
MarkGrid(curx,cury);
break;
case 'z':
OpenLeft(curx,cury);
break;
case 'i':
Init();
break;
default:
break;
}
ShowCur();
}
return 0;
}
int Init()
{
int i,j;
int gd=DETECT,gm;
initgraph(&gd,&gm,"d:\\borlandc\\bgi");
if (graphresult()!=grOk)
return 0;
totalmines=0;
randomize();
for (i=0;i<MAXX;i++)
for (j=0;j<MAXY;j++)
{
grid[i][j]=random(10)>7;
if (grid[i][j]==1)
totalmines++;
}
opened=0;
marked=0;
DrawBar();
DrawBack();
curx=0;
cury=0;
ShowCur();
return 1;
}
int DrawBar()
{
char strmarked[1];
setcolor(BROWN);
rectangle(BARX,BARY,BARX+MAXX*GRID,YSTART);
setfillstyle(SOLID_FILL,BROWN);
floodfill(BARX+1,BARY+1,BROWN);
rectangle(FACEX,FACEY,FACEX+GRID,FACEY+GRID);
setcolor(YELLOW);
outtextxy(NUMX,NUMY,itoa(marked,strmarked,10));
return 0;
}
int DrawBack()
{
int i;
setbkcolor(BLUE);
setcolor(BROWN);
for (i=0;i<=MAXX;i++)
{
line(XSTART+GRID*i,YSTART,
XSTART+GRID*i,YSTART+GRID*MAXY);
}
for (i=0;i<=MAXY;i++)
{
line(XSTART,YSTART+GRID*i,
XSTART+GRID*MAXX,YSTART+GRID*i);
}
return 0;
}
int ShowCur()
{
setcolor(GREEN);
rectangle(XSTART+GRID*curx,YSTART+GRID*cury,
XSTART+GRID*curx+GRID,YSTART+GRID*cury+GRID);
return 0;
}
int HideCur()
{
setcolor(BROWN);
rectangle(XSTART+GRID*curx,YSTART+GRID*cury,
XSTART+GRID*curx+GRID,YSTART+GRID*cury+GRID);
return 0;
}
int OpenGrid(int curx,int cury)
{
int i,mines;
static int dx[8]={1, 1,1,0,-1,-1,-1, 0};
static int dy[8]={0,-1,1,1, 0,-1, 1,-1};
if (!Validate(curx,cury))
return -1;
if (!(grid[curx][cury]&OPENED)&&!(grid[curx][cury]&MARKED))
{
if (grid[curx][cury]==MINE)
{
return -1;
}
mines=CalcMines(curx,cury);
DrawFigure(curx,cury,mines);
grid[curx][cury]|=OPENED;
if (++opened==totalmines)
{
return 1;
}
if (mines==0)
{
for (i=0;i<8;i++)
{
if (Validate(curx+dx[i],cury+dy[i]))
{
OpenGrid(curx+dx[i],cury+dy[i]);
}
}
}
}
return 0;
}
int Validate(int x,int y)
{
return (x>=0)&&(x<MAXX)&&(y>=0)&&(y<MAXY);
}
int CalcMines(int x,int y)
{
int result=0;
int i;
static int dx[8]={1, 1,1,0,-1,-1,-1, 0};
static int dy[8]={0,-1,1,1, 0,-1, 1,-1};
for (i=0;i<8;i++)
{
if (Validate(x+dx[i],y+dy[i]))
if (grid[x+dx[i]][y+dy[i]]&MINE)
result++;
}
return result;
}
int DrawFigure(int x,int y,int mines)
{
char strmines[1];
int xpos=x*GRID+XSTART;
int ypos=y*GRID+YSTART;
setfillstyle(SOLID_FILL,WHITE);
floodfill(XSTART+GRID*x+8,YSTART+GRID*y+8,BROWN);
if (mines>0)
{
setcolor(BROWN);
outtextxy(xpos,ypos,itoa(mines,strmines,10));
}
return 0;
}
int MarkGrid(int x,int y)
{
char strmarked[1];
if (grid[x][y]&OPENED)
return -1;
if (!(grid[x][y]&MARKED))
{
grid[x][y]|=MARKED;
marked++;
setcolor(BROWN);
outtextxy(NUMX,NUMY,itoa(marked-1,strmarked,10));
setcolor(YELLOW);
outtextxy(NUMX,NUMY,itoa(marked,strmarked,10));
DrawMarker(x,y);
}
else
{
grid[x][y]&=~MARKED;
marked--;
setcolor(BROWN);
outtextxy(NUMX,NUMY,itoa(marked+1,strmarked,10));
setcolor(YELLOW);
outtextxy(NUMX,NUMY,itoa(marked,strmarked,10));
RemoveMarker(x,y);
}
return 0;
}
int DrawMarker(int x,int y)
{
setcolor(YELLOW);
circle(XSTART+x*GRID+8,YSTART+y*GRID+8,6);
return 0;
}
int RemoveMarker(int x,int y)
{
setcolor(BLUE);
circle(XSTART+x*GRID+8,YSTART+y*GRID+8,6);
return 0;
}
int Deinit()
{
closegraph();
exit(0);
return 0;
}
int OpenLeft(int x,int y)
{
int mines;
int marks;
int i;
static int dx[8]={1, 1,1,0,-1,-1,-1, 0};
static int dy[8]={0,-1,1,1, 0,-1, 1,-1};
if (!(grid[x][y]&OPENED))
return -1;
mines=CalcMines(x,y);
marks=CalcMarks(x,y);
if (mines==marks)
{
for (i=0;i<8;i++)
{
OpenGrid(x+dx[i],y+dy[i]);
}
}
return 0;
}
int CalcMarks(int x,int y)
{
int result=0;
int i;
static int dx[8]={1, 1,1,0,-1,-1,-1, 0};
static int dy[8]={0,-1,1,1, 0,-1, 1,-1};
for (i=0;i<8;i++)
{
if (grid[x+dx[i]][y+dy[i]]&MARKED)
result++;
}
return result;
}
int OpenAll()
{
int i,j;
for (i=0;i<MAXX;i++)
for (j=0;j<MAXY;j++)
{
OpenGrid(i,j);
if ((grid[i][j]&MARKED)&&(!(grid[i][j]&MINE)))
{
setcolor(GREEN);
line(XSTART+i*GRID,YSTART+j*GRID,
XSTART+i*GRID+GRID,YSTART+j*GRID+GRID);
line(XSTART+i*GRID+GRID,YSTART+j*GRID,
XSTART+i*GRID,YSTART+j*GRID+GRID);
}
}
}