#include "graphics.h"
#include "stdio.h"
#define ROW 16
#define COL 16
#define STARTX 50
#define STARTY 50
#define SIZEX 20
#define SIZEY 20
#define UNFLAG 0
#define FLAGED 1
#define QUESTION 2
#define OPEN 3
#define EXPLORE 4
#define NULL 0
#define UP 0x4800
#define DOWN 0x5000
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define ENTER 0x1c0d
#define SPACE 0x3920
#define UPPERF 0x2146
#define LOWERF 0x2166
#define UPPERQ 0x1051
#define LOWERQ 0x1071
#define UPPERA 0x1e41
#define LOWERA 0x1e61
#define UPPERN 0x314e
#define LOWERN 0x316e
#define UPPERY 0x1559
#define LOWERY 0x1579
#define ESC 0x11b
int table[ROW][COL];
int flag[ROW][COL];
int num[ROW][COL];
int di[8]={-1,0,1,-1,1,0,1,-1};
int dj[8]={1,1,1,0,0,-1,-1,-1};
int pi,pj;
int gameRes;
void initGraph()
{
int gdriver,gmod;
detectgraph(&gdriver,&gmod);
initgraph(&gdriver,&gmod,"F://Program//TC");
}
void generateMine()
{
int i,j;
int totleMine;
int ri,rj;
int ni,nj;
totleMine=ROW*COL/6;
memset(table,0,sizeof(table));
memset(num,0,sizeof(num));
srand((unsigned)time(NULL));
for(i=0;i<totleMine;i++)
{
do{
ri=rand()%ROW;
rj=rand()%COL;
}while(table[ri][rj]);
table[ri][rj]=1;
for(j=0;j<8;j++)
{
ni=ri+di[j];
nj=rj+dj[j];
if(ni>=0&&ni<ROW&&nj>=0&&nj<COL)
{
num[ni][nj]++;
}
memset(flag,UNFLAG,sizeof(flag));
}
}
}
int autoMine(){
int i;
int ai,aj;
int autoRes=0;
if(flag[pi][pj]==OPEN){
for(i=0;i<8;i++){
ai=pi+di[i];
aj=pj+dj[i];
if(ai>=0&&ai<ROW&&aj>=0&&aj<COL&&flag[ai][aj]!=FLAGED){
if(openMine(ai,aj))
autoRes=-1;
}
}
}
return autoRes;
}
void drawBlock(int i,int j)
{
int x=0;
int y=0;
int xx=0;
int yy=0;
int tx,ty;
int color;
char ifMined,buf[3];
itoa(num[i][j],buf,10);
x=STARTX+i*SIZEX;
y=STARTY+j*SIZEY;
xx=x+SIZEX-1;
yy=y+SIZEY-1;
tx=x+5;
ty=y+5;
color=flag[i][j]==0?LIGHTGRAY:DARKGRAY;
setcolor(WHITE);
rectangle(x,y,xx,yy);
setfillstyle(SOLID_FILL,color);
floodfill(x+1,y+1,WHITE);
if(pi==i&&pj==j){
setcolor(RED);
rectangle(x+1,y+1,xx-1,yy-1);
}
switch(flag[i][j]){
case FLAGED:
outtextxy(tx,ty,"F");
break;
case QUESTION:
outtextxy(tx,ty,"Q");
break;
case OPEN:
outtextxy(tx,ty,buf);
break;
case EXPLORE:
outtextxy(tx,ty,"*");
break;
}
}
void moveDown(){
if(pj<COL-1){
pj++;
drawBlock(pi,pj);
drawBlock(pi,pj-1);
}
}
void moveUp(){
if(pj>=1){
pj--;
drawBlock(pi,pj);
drawBlock(pi,pj+1);
}
}
void moveLeft(){
if(pi>=1){
pi--;
drawBlock(pi,pj);
drawBlock(pi+1,pj);
}
}
void moveRight(){
if(pi<ROW-1){
pi++;
drawBlock(pi,pj);
drawBlock(pi-1,pj);
}
}
void flagBlock(){
if(flag[pi][pj]==FLAGED)
flag[pi][pj]=UNFLAG;
else if(flag[pi][pj]==UNFLAG)
flag[pi][pj]=FLAGED;
drawBlock(pi,pj);
}
void questBlock(){
if(flag[pi][pj]==QUESTION)
flag[pi][pj]=UNFLAG;
else if(flag[pi][pj]==UNFLAG)
flag[pi][pj]=QUESTION;
drawBlock(pi,pj);
}
int openMine(int pi,int pj){
if(flag[pi][pj]==OPEN)
return 0;
else{
if(table[pi][pj]==0){
flag[pi][pj]=OPEN;
drawBlock(pi,pj);
return 0;
}else{
flag[pi][pj]=EXPLORE;
drawBlock(pi,pj);
gameRes=-1;
return -1;
}
}
}
drawTable()
{
int i,j;
for(i=0;i<ROW;i++)
for(j=0;j<COL;j++)
drawBlock(i,j);
}
int getKey()
{
int key;
while(1)
{
key=bioskey(0);
switch(key){
case ENTER:
case UP:
case DOWN:
case LEFT:
case RIGHT:
case SPACE:
case ESC:
case LOWERF:
case UPPERF:
case LOWERA:
case UPPERA:
case LOWERQ:
case UPPERQ: return key;
}
}
}
void newGame()
{
cleardevice();
generateMine();
gameRes=0;
pi=pj=0;
drawTable();
getch();
}
int confirm(){
int k;
char *ch;
if(gameRes==1)
ch="Success! Try again?(y/n)";
else if(gameRes==-1)
ch="Failed! Try again?(y/n)";
else if(gameRes==2)
ch="Quit?(y/n)";
outtextxy(20,20,ch);
while(1){
k=bioskey(0);
switch(k){
case UPPERY:
case LOWERY:
if(gameRes!=2)
return 1;
else
return 0;
case UPPERN:
case LOWERN:
if(gameRes!=2)
return 0;
else
return 1;
}
}
}
int checkWin(){
int i,j;
for(i=0;i<ROW;i++){
for(j=0;j<COL;j++){
if(flag[i][j]==0)
return gameRes;
}
}
return 1;
}
main()
{
int key;
initGraph();
do{
newGame();
do{
key=getKey();
switch(key){
case DOWN:
moveDown();
break;
case UP:
moveUp();
break;
case LEFT:
moveLeft();
break;
case RIGHT:
moveRight();
break;
case UPPERF:
case LOWERF:
flagBlock();
break;
case UPPERQ:
case LOWERQ:
questBlock();
break;
case ENTER:
case SPACE:
gameRes=openMine(pi,pj);
break;
case ESC:
gameRes=2;
break;
case UPPERA:
case LOWERA:
gameRes=autoMine();
break;
}
gameRes=checkWin();
}while(!gameRes);
}while(confirm());
}