扫雷游戏功能说明
- 使⽤控制台实现经典的扫雷游戏
- 游戏可以通过菜单实现继续玩或者退出游戏
- 扫雷的棋盘是9*9的格⼦
- 默认随机布置10个雷
- 可以排查雷
- 如果位置不是雷,就显⽰周围有⼏个雷
- 如果位置是雷,就炸死,游戏结束
- 把除10个雷之外的所有雷都找出来,排雷成功,游戏结束
对代码进行了优化
使用二维数组,指针和函数的知识实现地雷数和棋盘大小可变的扫雷游戏
代码运行截图
思路及代码实现
1.打印开始菜单
void menu() {
printf("***********扫雷************\n");
printf("********1. 开始游戏********\n");
printf("********0. 退出游戏********\n");
printf("***************************\n");
}
2.开始及退出游戏
int main() {
int select;
do{
menu(); //打印开始菜单
scanf("%d", &select); // 输入数字0或1判断继续游戏还是结束游戏
switch (select){
case 1://输入1时进入game函数,开始游戏
system("CLS");//每次选择时清空屏幕,保持界面干净
printf("加载中,请等待游戏开始\n");
game();
break;
case 0://输入0时结束游戏
system("CLS");
printf("游戏退出");
break;
default://输入其他数据时重新选择
printf("输入有误,重新输入");
break;
}
}while(select);
return 0;
}
3 初始化游戏数据
每次新的游戏开始时初始化游戏界面和雷的位置
- 创建4个全局变量,标记数据
int arr[9][9]; //标记每个位置周围的地雷数,探测过时显示此位置上的地雷数
int flag[9][9]; //标记已经探测过的位置,当已经探测过,显示周围地雷数,否则显示*
int mine[9][9]; // 统计地雷位置,有雷时为1,无雷时为0;
int num = 0; //统计探测次数,到达71次时退出,此时所有未探测的地方都有雷
- 使用随机数函数rand初始化10个地雷的位置
void Laymines() {
int x, y;
for (int i = 0; i < 9; i++){
//使地雷标记全为0,防止上次游戏的数据残留影响导致雷的数量大于10个
for (int j = 0; j < 9; j++) {
mine[i][j] = 0;
}
}
srand((unsigned)time(NULL));
for (int i = 0; i < 11;) {//标记10个位置有雷
x = rand() % 9;
y = rand() % 9;
if (mine[x][y]) continue;//当已经被标记过地雷时进行下次循环,地雷计数不变
else {
mine[x][y] = 1;//未被标记过未地雷时,标记为地雷
i++;//地雷计数加1,当为11时退出。保证只有10颗雷
}
}
}
- 初始化flag数组,因为初始时玩家还未有探测行为,所有全部初始化为0
void Layflag() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
flag[i][j] = 0;
}
}
}
- 初始化arr数组,用来显示每个格子的周围有多少雷
void Layarr() {//标记周围8个格子共有多少个地雷
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (mine[i][i]) continue;//此格子有雷时不需要统计
else{//每个格子周围如果有格子(数组下标未溢出)则统计是否有雷
if (mine[i - 1][j - 1] && i >= 0 && j >= 0) arr[i][j]++;
if (mine[i - 1][j] && i >= 0) arr[i][j]++;
if (mine[i - 1][j + 1] && i >= 0 && j < 9) arr[i][j]++;
if (mine[i][j - 1] && j >= 0) arr[i][j]++;
if (mine[i][j + 1] && j < 9) arr[i][j]++;
if (mine[i + 1][j - 1] && i < 9 && j >= 0) arr[i][j]++;
if (mine[i + 1][j] && i < 9 ) arr[i][j]++;
if (mine[i + 1][j + 1] && i < 9 && j <9) arr[i][j]++;
}
}
}
}
4.打印游戏界面
void interface() {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if (0 == i) printf("%d ", j); //第一行为列位置标记
else if (0 == j) printf("%d ", i); //第一列为行位置标记
else if (flag[i-1][j-1]) printf("%d ", arr[i-1][j-1]);
//如果被探测过则显示周围有几颗雷
else printf("* "); // 没探测过则显示*
}
printf("\n");
}
return 0;
}
5.进行探测行为
int detect() {
int x, y;
printf("请输入你要探测的位置>");
scanf("%d %d", &x, &y);
if (mine[x - 1][y - 1]) return 0;//如果有雷则返回0
else {
flag[x - 1][y - 1] = 1;//无雷则标记已经探测
num++;//探测计数
}
return 1;//无雷返回1
}
6.游戏主体,循环进行探测操作,直到游戏失败或成功
void game() {
int x = 1;
Lay(); //初始化游戏数据
while(x){
system("CLS");//清空屏幕
print();//测试时使用,打印arr,flag,mine数组的内容
interface(); //打印游戏界面
x = detect();
//detect函数返回值为0则表示此次探测无雷,为1则表示探测到雷,游戏结束
if (71 == num) break;
//num统计玩家探测的次数,当次数为71时,则剩下所有格子都是雷,游戏胜利
}
if (x) printf("*********扫雷完成**********\n");
else printf("*********扫雷失败*********\n");
}
7.测试
在游戏初始化数据后打印arr,flag,mine数组的内容,然后正常游戏,判断自己的程序是否有bug
void print() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
printf("%d ",arr[i][j]);
}
printf("\n");
}
printf("***************************\n");
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
printf("%d ",flag[i][j]);
}
printf("\n");
}
printf("***************************\n");
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
printf("%d ",mine[i][j]);
}
printf("\n");
}
printf("***************************\n");
}
全部代码
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
static int arr[9][9]; //标记每个位置周围的地雷数,探测时显示
static int flag[9][9]; //标记已经探测过的位置,当已经探测过,显示周围地雷数,否则显示*
static int mine[9][9]; // 统计地雷位置,有雷时为1,无雷时为0;
static int num = 0; //统计探测次数,到达71次时退出,此时所有未探测的地方都有雷
//测试用,打印三个数组
void print() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
printf("%d ",arr[i][j]);
}
printf("\n");
}
printf("***************************\n");
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
printf("%d ",flag[i][j]);
}
printf("\n");
}
printf("***************************\n");
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
printf("%d ",mine[i][j]);
}
printf("\n");
}
printf("***************************\n");
}
//打印菜单
void menu() {
printf("***********扫雷************\n");
printf("********1. 开始游戏********\n");
printf("********0. 退出游戏********\n");
printf("***************************\n");
}
//初始化arr数组
void Layarr() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (mine[i - 1][j - 1] && i >= 0 && j >= 0) arr[i][j]++;
if (mine[i - 1][j] && i >= 0) arr[i][j]++;
if (mine[i - 1][j + 1] && i >= 0 && j < 9) arr[i][j]++;
if (mine[i][j - 1] && j >= 0) arr[i][j]++;
if (mine[i][j + 1] && j < 9) arr[i][j]++;
if (mine[i + 1][j - 1] && i < 9 && j >= 0) arr[i][j]++;
if (mine[i + 1][j] && i < 9 ) arr[i][j]++;
if (mine[i + 1][j + 1] && i < 9 && j <9) arr[i][j]++;
}
}
}
//初始化flag数组
void Layflag() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
flag[i][j] = 0;
}
}
}
//初始化10个地雷的位置
void Laymines() {
int x, y;
for (int i = 0; i < 9; i++){//使地雷标记全为0
for (int j = 0; j < 9; j++) {
mine[i][j] = 0;
}
}
for (int i = 0; i < 11;) {
srand((unsigned)time(NULL));
x = rand() % 9;
y = rand() % 9;
if (mine[x][y]) continue;//当已经被标记过地雷时退出
else {
mine[x][y] = 1;//未被标记过未地雷时,标记为地雷
i++;//地雷数加1,当为11时退出.
}
}
}
//初始化游戏数据
void Lay() {
num = 0;
int a;
Laymines();//初始化10个地雷的位置
Layarr();//初始化arr数组
Layflag();//初始化flag数组
}
//进行探测
int detect() {
int x, y;
printf("请输入你要探测的位置>");
scanf("%d %d", &x, &y);
if (mine[x - 1][y - 1]) return 0;//如果有雷则退出
else {
flag[x - 1][y - 1] = 1;//无雷则标记已经探测
num++;//探测计数
}
return 1;
}
//即时打印游戏界面
void interface() {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if (0 == i) printf("%d ", j); //第一行为列位置标记
else if (0 == j) printf("%d ", i); //第一列为行位置标记
else if (flag[i-1][j-1]) printf("%d ", arr[i-1][j-1]); //如果被探测过则显示周围有几颗雷
else printf("* "); // 没探测过则显示*
}
printf("\n");
}
return 0;
}
void game() {
int x;
Lay(); //初始化游戏数据
system("CLS");
do{
print();
interface(); //打印界面
x = detect(); //进行扫雷行为
system("CLS");//清空屏幕
if (71 == num) break;
} while (x);
if (x) printf("*********扫雷完成**********\n");
else printf("*********扫雷失败*********\n");
}
int main() {
int select;
while(1){
menu(); //打印菜单
scanf("%d", &select); // 输入选择判断继续游戏还是结束游戏
if (select == 0) break;
else if (select == 1) game();
else printf("输入有误,重新输入");
}
return 0;
}