规则:
1、最后的结果中的雷用*表示,当用!标记出所有雷则胜利;
2、手动标注地雷用!手动选择格子用0;
3、数字表示该格子周围雷的数量;
4、0表示用户选择的无雷无数字提示的格子(也就是周围无雷的格子);
5、没有选择的格子用-表示;
本程序的问题:
1、对打开一片的代码还需要完善;
2、要对当用户输入规则外字符进行处理;
3、不光用!标记完雷是胜利,还需要改成当用户翻开所有格子后为胜利;
备注:
1、本程序在osx与linux下测试通过;
2、本程序会持续进行代码与流程的完善;
3、程序中的map[m][n]=-1表示已经打开的格子,为后面改进代码打下基础;
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 10
#define L 10
//计算选的格子周围雷的数量
int sl_lei(int m ,int n,int (*map)[N])
{
int x=0,y=0,count=0;
for(x=m-1;x<=m+1;x++)
{
for(y=n-1;y<=n+1;y++)
{
if(x<0 || x>N-1 || y<0 || y>N-1)
{
continue;
}
if(x==m && y==n)
{
continue;
}
if(1==map[x][y])
{
count++;
}
}
}
return count;
}
//打开一片,这里假设[m][n]位置周围无雷,周围无雷才调用这个函数
void sl_open(int m,int n,int (*map)[N],char (*GAME)[N])
{
int x=0,y=0;
//[m][n]的左上区域
for(x=m,y=n;x>=0 && sl_lei(x,y,map)==0;x--)
{
for(y=n;y>=0 && sl_lei(x,y,map)==0;y--)
{
GAME[x][y]='0';
map[x][y]=-1;
}
}
//[m][n]的左下区域
for(x=m,y=n;x<=N-1 && sl_lei(x,y,map)==0;x++)
{
for(y=n;y>=0 && sl_lei(x,y,map)==0;y--)
{
GAME[x][y]='0';
map[x][y]=-1;
}
}
//[m][n]的右上区域
for(x=m,y=n;x>=0 && sl_lei(x,y,map)==0;x--)
{
for(y=n;y<=N-1 && sl_lei(x,y,map)==0;y++)
{
GAME[x][y]='0';
map[x][y]=-1;
}
}
//[m][n]的右下区域
for(x=m,y=n;x<=N-1 && sl_lei(x,y,map)==0;x++)
{
for(y=n;y<=N-1 && sl_lei(x,y,map)==0;y++)
{
GAME[x][y]='0';
map[x][y]=-1;
}
}
return;
}
//初始化游戏,并产生L个雷并始化map雷分布图
void sl_init(char (*GAME)[N],int (*map)[N])
{
int i=0,j=0,l=0,m=0,n=0;
//初始化游戏
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
{
GAME[i][j]='-';
}
}
//产生L雷,并防止重复
printf("雷的分布位置为:\n");
for(l=0;l<L;l++)
{
m=rand()%N;
n=rand()%N;
//测试代码,打印雷的位置信息
printf("m:%d n:%d\n",m,n);
if(0==map[m][n])
{
map[m][n]=1;
}else
{
do{
m=rand()%N;
n=rand()%N;
}while(1==map[m][n]);
map[m][n]=1;
}
}
return;
}
//显示游戏
void sl_show(char (*GAME)[N])
{
int i=0,j=0;
printf("\n++++扫+雷+棋+盘++++\n");
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
{
printf("%c ",GAME[i][j]);
}
printf("\n");
}
return;
}
int main()
{
int i=0,j=0,m=0,n=0,x=0,y=0,count=0,num=0;
int map[N][N]={0};
char GAME[N][N]={0};
char ttt='\0';
char k='\0';
srand((unsigned)time(NULL));
sl_init(GAME,map);
printf("\n");
sl_show(GAME);
printf("\n");
while(1)
{
printf("请输入选择格的坐标(例如0 3或者1 3回车):");
scanf("%d%d",&m,&n);
setbuf(stdin,NULL);
if(m<0)
{
m=-1*m;
}
if(n<0)
{
n=-1*n;
}
printf("请输入操作方式0或者!:");
scanf("%c",&k);
//用于吃掉回车
scanf("%c",&ttt);
//测试代码:
printf("您输入的操作行为是:%d%d%c\n",m,n,k);
if('0'==k)
{
if(1==map[m][n])
{
printf("\nGAME OVER!YOU LOST!\n\n");
//把最后的结果显示出来
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
{
if(1==map[i][j])
{
GAME[i][j]='*';
}
}
}
printf("扫雷棋盘的实际情况是:\n");
sl_show(GAME);
return 0;
}
//计算周围雷的数量,然后显示雷的数量
count=sl_lei(m,n,map);
GAME[m][n]=count+'0';
//在地雷图中标记已经打开的格子
map[m][n]=-1;
}
//当无雷时则显示用户标识的0或者!
if(0==count)
{
GAME[m][n]=k;
//这里写打开一片的代码
sl_open(m,n,map,GAME);
}
//如果用户标识的位置确实是雷则进行一次计算
if('!'==k && 1==map[m][n])
{
num++;
}
if(L==num)
{
printf("\nNICE!YOU WIN!\n\n");
sl_show(GAME);
return 0;
}
sl_show(GAME);
}
}