设计要求:
1.第一次不会被雷炸死。
2.点开如果不是雷显示周围雷的个数。
3.周围没有雷,则展开一片。
实现思路:
1.首先需要设计两个雷阵,一个是设计者用来存储布置雷场数据的雷阵,另一个是玩家用来扫雷的雷阵
2.布雷:我们需要设计一个A*A(A代表雷阵大小,根据设计者需要自行设计)的雷阵,布有X(X代表雷的个数,根据设计者与玩家需求自己设计)个雷,那我们可以用二维数组来实现雷阵,用字符‘1’表示有雷,字符‘0’表示没有雷(如果使用数字0和1表示是否有雷,那么将会产生这个数字代表的是雷还是雷的个数的歧义,所以不采用这种方式),所以将雷阵初始化为字符‘0’,进而用%c来打印。还有一个问题就是我们是否就要将雷阵设计成A*A的呢,答案是否定的,如果你在计算一个坐标周围雷的个数,就要遍历周围的A-1个坐标,如果设计成A*A的雷阵,那么最外围的坐标周围是没有8个位置的,所以我们应将雷阵设计成(A+2)*(A+2),但是布雷与扫雷仅在中间的A*A中进行,这样这个问题就得以解决了。
3.扫雷:与布雷一样,也要将雷阵设计成(A+2)*(A+2);因为此雷阵为玩家雷阵,为了增加神秘性,应将其初始化为字符‘ * ’,或是其他字符。
4.判断输赢:当雷阵中的字符‘ * ’还有10个或者排雷次数达到A*A-X次即获得胜利。
具体函数实现:
1.进入菜单:选择是否进行游戏
void mune()
{
printf("****************************\n");
printf("***** 1. play *****\n");
printf("***** 0. exit *****\n");
printf("****************************\n");
}
2.进入游戏,初始化两个雷阵.
void InitBoard(char arr[ROWS][COLS], int rows, int cols,char set) //初始化雷阵
{
int i = 0;
int j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
arr[i][j] = set;
}
}
}
3.在雷阵中布置雷
void SetMine(char mine1[ROWS][COLS], int row, int col) //设置雷阵分布
{
int count = EASY_COUNT;
while (count)
{
int x = rand()%row+1;
int y = rand()%col+1;
if (mine1[x][y] == '0')
{
mine1[x][y] = '1';
count--;
}
}
}
4.打印雷阵
void DisplayBoard(char mine1[ROWS][COLS], int row, int col) //打印雷阵
{
int i = 0;
int j = 0;
for (i = 0; i <= row; i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i);
for (j = 1; j <= col; j++)
{
printf("%c ", mine1[i][j]);
}
printf("\n");
}
}
5.如果该坐标不是雷,统计周围雷的个数
int GetMineCount(char mine1[ROWS][COLS], int x, int y) //统计雷的个数
{
return mine1[x - 1][y] +
mine1[x - 1][y - 1] +
mine1[x][y - 1] +
mine1[x + 1][y - 1] +
mine1[x + 1][y] +
mine1[x + 1][y + 1] +
mine1[x][y + 1] +
mine1[x - 1][y + 1] - 8 * '0';
}
6.避免第一次被雷炸死
void MoveMine(char mine1[ROWS][COLS], char mine2[ROWS][COLS], int row, int col)//避免第一次被雷炸死
{
int x = 0;
int y = 0;
char ch = 0;
int count = 0;
int ret = 1;
printf("输入坐标扫雷:>");
while (1)
{
scanf("%d%d", &x, &y);
if (x >= 1 && x <= row&&y >= 1 && y <= col)
{
if (mine1[x][y] == '1')
{
mine1[x][y] = '0';
char ch = GetMineCount(mine1,x, y);
mine2[x][y] = ch + '0';
OpenMine(mine1,mine2, x, y);
while (ret)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (mine1[x][y] == '0')
{
mine1[x][y] = '1';
ret--;
break;
}
}
break;
}
if (mine1[x][y] == '0')
{
char ch = GetMineCount(mine1, x, y);
mine2[x][y] = ch + '0';
OpenMine(mine1,mine2, x, y);
break;
}
}
else
{
printf("坐标错误,请重新输入!\n");
}
}
}
7.坐标周围没有雷,展开
void OpenMine(char mine1[ROWS][COLS], char mine2[ROWS][COLS], int x, int y)//坐标周围没雷,可以实现展开
{
if (mine1[x - 1][y - 1] == '0')
{
mine2[x - 1][y - 1] = GetMineCount(mine1,x - 1, y - 1) + '0';//显示该坐标周围雷数
}
if (mine1[x - 1][y] == '0')
{
mine2[x - 1][y] = GetMineCount(mine1, x - 1, y) + '0';//显示该坐标周围雷数
}
if (mine1[x - 1][y + 1] == '0')
{
mine2[x - 1][y + 1] = GetMineCount(mine1, x - 1, y + 1) + '0';//显示该坐标周围雷数
}
if (mine1[x][y - 1] == '0')
{
mine2[x][y - 1] = GetMineCount(mine1, x, y - 1) + '0';//显示该坐标周围雷数
}
if (mine1[x][y + 1] == '0')
{
mine2[x][y + 1] = GetMineCount(mine1, x, y + 1) + '0';//显示该坐标周围雷数
}
if (mine1[x + 1][y - 1] == '0')
{
mine2[x + 1][y - 1] = GetMineCount(mine1, x + 1, y - 1) + '0';//显示该坐标周围雷数
}
if (mine1[x + 1][y] == '0')
{
mine2[x + 1][y] = GetMineCount(mine1, x + 1, y) + '0';//显示该坐标周围雷数
}
if (mine1[x + 1][y + 1] == '0')
{
mine2[x + 1][y + 1] = GetMineCount(mine1, x + 1, y + 1) + '0';//显示该坐标周围雷数
}
}
8.扫雷以及判断输赢
void FindMine(char mine1[ROWS][COLS], char mine2[ROWS][COLS], int row, int col) //扫雷
{
int x = 0;
int y = 0;
int win = 0;
while (win<row*col-EASY_COUNT)
{
printf("请输入要排查的坐标:>");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= row&&y >= 1 && y <= col)
{
if (mine1[x][y] == '1')
{
printf("很遗憾,你被炸死了!\n");
DisplayBoard(mine1, row, col);
break;
}
else
{
int count = GetMineCount(mine1, x, y);
mine2[x][y] = count + '0';
DisplayBoard(mine2, row, col);
}
}
else
{
printf("坐标非法,请重新输入!\n");
}
}
if (win == row*col - EASY_COUNT)
{
printf("恭喜你,排雷成功!\n");
}
}
附上源码:
game.h(头文件)
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define EASY_COUNT 10 //设置雷的个数
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
void InitBoard(char arr[ROWS][COLS], int rows, int cols, char set); //初始化雷阵
void SetMine(char mine1[ROWS][COLS], int row, int col);//设置雷的及分布
void DisplayBoard(char mine1[ROWS][COLS], int row, int col);//打印雷阵
void MoveMine(char mine1[ROWS][COLS], char mine2[ROWS][COLS], int row, int col);//避免第一次被雷炸死
void OpenMine(char mine1[ROWS][COLS], char mine2[ROWS][COLS], int row, int col);//坐标周围没雷,实现展开
void FindMine(char mine1[ROWS][COLS], char mine2[ROWS][COLS], int row, int col);//扫雷
game.c(函数实现)
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void InitBoard(char arr[ROWS][COLS], int rows, int cols,char set) //初始化雷阵
{
int i = 0;
int j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
arr[i][j] = set;
}
}
}
void SetMine(char mine1[ROWS][COLS], int row, int col) //设置雷阵分布
{
int count = EASY_COUNT;
while (count)
{
int x = rand()%row+1;
int y = rand()%col+1;
if (mine1[x][y] == '0')
{
mine1[x][y] = '1';
count--;
}
}
}
void DisplayBoard(char mine1[ROWS][COLS], int row, int col) //打印雷阵
{
int i = 0;
int j = 0;
for (i = 0; i <= row; i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i);
for (j = 1; j <= col; j++)
{
printf("%c ", mine1[i][j]);
}
printf("\n");
}
}
int GetMineCount(char mine1[ROWS][COLS], int x, int y) //统计雷的个数
{
return mine1[x - 1][y] +
mine1[x - 1][y - 1] +
mine1[x][y - 1] +
mine1[x + 1][y - 1] +
mine1[x + 1][y] +
mine1[x + 1][y + 1] +
mine1[x][y + 1] +
mine1[x - 1][y + 1] - 8 * '0';
}
void MoveMine(char mine1[ROWS][COLS], char mine2[ROWS][COLS], int row, int col)//避免第一次被雷炸死
{
int x = 0;
int y = 0;
char ch = 0;
int count = 0;
int ret = 1;
printf("输入坐标扫雷:>");
while (1)
{
scanf("%d%d", &x, &y);
if (x >= 1 && x <= row&&y >= 1 && y <= col)
{
if (mine1[x][y] == '1')
{
mine1[x][y] = '0';
char ch = GetMineCount(mine1,x, y);
mine2[x][y] = ch + '0';
OpenMine(mine1,mine2, x, y);
while (ret)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (mine1[x][y] == '0')
{
mine1[x][y] = '1';
ret--;
break;
}
}
break;
}
if (mine1[x][y] == '0')
{
char ch = GetMineCount(mine1, x, y);
mine2[x][y] = ch + '0';
OpenMine(mine1,mine2, x, y);
break;
}
}
else
{
printf("坐标错误,请重新输入!\n");
}
}
}
void OpenMine(char mine1[ROWS][COLS], char mine2[ROWS][COLS], int x, int y)//坐标周围没雷,可以实现展开
{
if (mine1[x - 1][y - 1] == '0')
{
mine2[x - 1][y - 1] = GetMineCount(mine1,x - 1, y - 1) + '0';//显示该坐标周围雷数
}
if (mine1[x - 1][y] == '0')
{
mine2[x - 1][y] = GetMineCount(mine1, x - 1, y) + '0';//显示该坐标周围雷数
}
if (mine1[x - 1][y + 1] == '0')
{
mine2[x - 1][y + 1] = GetMineCount(mine1, x - 1, y + 1) + '0';//显示该坐标周围雷数
}
if (mine1[x][y - 1] == '0')
{
mine2[x][y - 1] = GetMineCount(mine1, x, y - 1) + '0';//显示该坐标周围雷数
}
if (mine1[x][y + 1] == '0')
{
mine2[x][y + 1] = GetMineCount(mine1, x, y + 1) + '0';//显示该坐标周围雷数
}
if (mine1[x + 1][y - 1] == '0')
{
mine2[x + 1][y - 1] = GetMineCount(mine1, x + 1, y - 1) + '0';//显示该坐标周围雷数
}
if (mine1[x + 1][y] == '0')
{
mine2[x + 1][y] = GetMineCount(mine1, x + 1, y) + '0';//显示该坐标周围雷数
}
if (mine1[x + 1][y + 1] == '0')
{
mine2[x + 1][y + 1] = GetMineCount(mine1, x + 1, y + 1) + '0';//显示该坐标周围雷数
}
}
void FindMine(char mine1[ROWS][COLS], char mine2[ROWS][COLS], int row, int col) //扫雷
{
int x = 0;
int y = 0;
int win = 0;
while (win<row*col-EASY_COUNT)
{
printf("请输入要排查的坐标:>");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= row&&y >= 1 && y <= col)
{
if (mine1[x][y] == '1')
{
printf("很遗憾,你被炸死了!\n");
DisplayBoard(mine1, row, col);
break;
}
else
{
int count = GetMineCount(mine1, x, y);
mine2[x][y] = count + '0';
DisplayBoard(mine2, row, col);
}
}
else
{
printf("坐标非法,请重新输入!\n");
}
}
if (win == row*col - EASY_COUNT)
{
printf("恭喜你,排雷成功!\n");
}
}
test.c(测试)
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void mune()
{
printf("****************************\n");
printf("***** 1. play *****\n");
printf("***** 0. exit *****\n");
printf("****************************\n");
}
void game()
{
char mine1[ROWS][COLS] = { 0 }; //布雷数组
char mine2[ROWS][COLS] = { 0 }; //展示数组
//初始化
InitBoard(mine1, ROWS, COLS, '0'); //初始化布雷数组
InitBoard(mine2, ROWS, COLS, '*'); //初始化展示数组
//1.设置雷
SetMine(mine1, ROW, COL);//设置雷阵分布
//DisplayBoard(mine1, ROW, COL);//打印布雷数组
DisplayBoard(mine2, ROW, COL);//打印展示数组
//2.扫雷
MoveMine(mine1, mine2, ROW, COL);//避免第一次被雷炸死
//DisplayBoard(mine1, ROW, COL); //打印布雷数组
DisplayBoard(mine2, ROW, COL); //打印展示数组
FindMine(mine1,mine2,ROW,COL);//扫雷
}
void test()
{
int inupt = 0;
srand((unsigned int)time(NULL));
do
{
mune();
printf("请选择:>");
scanf("%d", &inupt);
switch (inupt)
{
case 1:
game();
break;
case 0:
printf("退出游戏。\n");
break;
default:
printf("输入错误,请重新选择。\n");
break;
}
} while (inupt);
}
int main()
{
test();
return 0;
}
结果展示:
选择是否进入游戏:
进入游戏,开始扫雷
输入坐标,并展示周围雷的个数,并且展开。
扫到雷,游戏失败
总结:再写任何一个程序之前首先要做的就是分析清楚它的逻辑思路,逻辑搞清楚,接下来就是使用语法实现目的,而且需要注意细节上的问题,错了一个细节调试很久都很难发现,还要注意时间和空间上的优化;在写的过程中细心谨慎,注意参数的传递以及函数的调用,还需要注意括号的使用,保证可读性。