前言:
之前一直想实现下扫雷,偶然在贴吧里看到有人出题,于是心血来潮就写了下。
题目:
扫雷游戏是Windows里一款十分经典的单机小游戏,请你用C程序自己建立一个扫雷小游戏。
系统可以随机产生一个m行n列的雷区,包含若干颗地雷,用户可以挖开一个区域,如果是地雷,游戏结束,失败;
如果不是,显示出它周围的地雷个数,如果能把所有安全的地区找出来,获胜。 注:每个格子周围格有八个:上、下、左、右、左上、右上、左下、右下。
运行结果:
请输入雷区的范围:
3 5
X X X X X
X X X X X
X X X X X
请输入安全的位置:
2 2
X X X X X
X 3 X X X
X X X X X
请输入安全的位置:
3 4
X X X X X
X 3 X X X
X X X O X
很不幸,你踩到雷了,游戏结束!
代码:
#include<stdio.h>
#include <stdlib.h>
#include <time.h>
int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
int around[8][2] = {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
int x,y,z; //行 列 雷
int *map; //雷区
char *view; //玩家视野
//初始化雷区
void init()
{
for(int i=0;i<x*y;i++)
map[i]=0;
for(int i=0;i<x*y;i++)
view[i]='O';
srand((unsigned)time(NULL));
int n = z>x*y?x*y:z;
while(n--)
{
int r = rand()%(x*y);
while(map[r])
r = rand()%(x*y);
map[r] =1;
}
}
//周围雷数
int checkMine(int px, int py)
{
int count = 0;
for(int i=0;i<8;i++)
{
int nx = px+around[i][0];
int ny = py+around[i][1];
if(nx>=0&&nx<x&&ny>=0&&ny<y&&map[y*nx+ny]==1)
count++;
}
return count;
}
//排雷
void clearMine(int px, int py)
{
int num = checkMine(px,py);
view[y*px+py]=num==0?'.':'0'+num;
for(int i=0;num==0&&i<4;i++)
{
int nx = px+dir[i][0];
int ny = py+dir[i][1];
if(nx>=0&&nx<x&&ny>=0&&ny<y&&map[y*nx+ny]==0&&view[y*nx+ny]=='O')
clearMine(nx,ny);
}
}
//检查是否获胜
int checkWin()
{
int n=0;
for(int i=0;i<x*y;i++)
if(view[i]=='O')
n++;
return n==z;
}
//雷区视图
void mapScreen()
{
printf("\n");
for(int i=0; i<x*y;i++)
{
printf("%d ",map[i]);
if((i+1)%y==0) printf("\n");
}
}
//玩家视图
void viewScreen()
{
for(int i=0; i<x*y;i++)
{
printf("%c ",view[i]);
if((i+1)%y==0) printf("\n");
}
}
int main()
{
printf("请输入雷区参数(行 列 地雷数):\n");
scanf("%d %d %d",&x,&y,&z);
map = (int *) malloc(sizeof(int)*x*y);
view = (char *) malloc(sizeof(char)*x*y);
init(); //生成雷区
viewScreen(); //打印玩家视图
//mapScreen(); //查看雷区(作弊)
int px,py,isWin;
while(1)
{
printf("请输入安全的位置:\n");
scanf("%d %d",&px,&py);
px--; py--;
if(px<0||px>=x||py<0||py>=y)
{
printf("范围有误!\n");
continue;
}
//若踩雷游戏结束
if(map[y*px+py]){
//将所有地雷显示出来
for(int i=0; i<x*y;i++)
{
if(map[i]==1)
printf("X ");
else
printf("%c ",view[i]);
if((i+1)%y==0) printf("\n");
}
isWin = 0;
break;
}
//否则对安全座标排雷
if(view[y*px+py]=='O')
clearMine(px,py);
viewScreen(); //打印玩家视图
//判断是否获胜
if(checkWin())
{
isWin = 1;
break;
}
}
if(isWin)
printf("恭喜获胜!");
else
printf("很不幸,你踩到雷了,游戏结束!");
return 0;
}
效果图: