目录
一、扫雷游戏的分析
(一)扫雷游戏的功能说明
① 使用控制台实现经典的扫雷游戏
② 游戏可以通过菜单实现继续玩或者退出游戏
③ 扫雷的棋盘是 9 * 9 的格子
④ 默认随机布置10个雷
⑤ 可以排查雷:
如果位置不是雷,就显示周围有几个雷;
如果位置是雷,就炸死,游戏结束;
把除10个雷之外的所有非雷都找出来,排雷成功,游戏结束
(二)代码逻辑
1、数据结构的分析
在扫雷过程中,二维数组中需要存放【地雷】与【周围的地雷数量】,如果只创建一个二位数组来操作是非常麻烦的,不如设置两个二维数组:
① 一个二维数组给程序员显示【设置 "0" 无地雷,"1" 地雷】、排查地雷时的用来【计算周围雷的数量】
② 另一个二维数组给玩家显示【" * " 隐藏地区】,排查地雷时的用来【显示周围的雷数】;
③ 两个二维数组皆为字符数组,方便统一操作,好管理
④ 考虑到边缘的数组元素在统计周围元素的地雷数量时会出现越界的象限,设置的二维数组要大一圈,即 11 * 11的数组
2、初始化棋盘
一个二维数组全部初始化为 " 0 " ,表示没有地雷;
另一个二维数组全部初始化为 " * ",表示隐藏地区
3、打印棋盘
11 * 11 的棋盘传过去,打印出9 * 9的棋盘给玩家;
为了更加清晰的显示与方便玩家输入行和列,要打印行和列的数字
4、布置地雷
先设置雷的总数,布置一个就减一;
在存放" 0 "的二维数组中,利用【初始化随机函数srand((unsigned int)time(NULL))】与【随机函数rand()】来进行随机坐标的布置地雷;
因为是随机布雷,且要在二维数组中的1~9行布雷,那么rand()%row+1,row定义为9;
要判断:如果有雷了那就不放;可将雷的个数与难度设置挂钩
5、寻找地雷
第一个有雷的数组排查出附近有多少个雷后,把【显示附近的雷的个数的数字】存到第二个数组里面,到时候打印第二个数组的信息就行;因为会在第一个数组里面排查。把结果输出给第二个数组,因此,两个数组都要使用到;
排查逻辑:
① 输入坐标,判断是否越界 ;
② 判断是不是雷:
如果是,则炸死,且打印地雷信息的棋盘;
不是雷,就统计这个位置周围雷的个数
③ 统计周围地雷数的函数:
先搞清楚X,Y周围的坐标是什么
可以利用循环将周围的地雷数统计并转为整型输出,到时候再转回来;
【字符数字】变成【整型数字】:字符数字 - 字符'0' == 整型数字
【整型数字】变【字符数字】:整型数字 + '0' == 字符数字
④ 排雷成功:总的格子数 - 排雷数(设置一个变量,上面排成功就++) == 排查雷的个数;
利用循环来进行地雷的不断排查
二、代码实现
把游戏功能的实现放在一个函数里面,函数的声明放在一个头文件中,不用全部放在主函数里,显得凌乱:
① 游戏测试 test.c
② 游戏功能的实现:
game.c
game.h
game.h 文件
#pragma once #include<stdio.h> #include<stdlib.h> #include<time.h> # define row 9 # define col 9 # define ROWS row+2 # define COLS col+2 # define easy 10 // 函数的声明: //1.雷盘初始化函数的声明 void init_landmine(char arr[ROWS][COLS],int x,int y,char n); //2.打印雷盘函数的声明 //小雷盘9*9: void print_show_landmine(char arr[ROWS][COLS], int x, int y); //3.设置雷 void set_landmine(char arr[ROWS][COLS], int m); //4.找雷 void find_landmine(char arr1[ROWS][COLS], char arr2[ROWS][COLS], int x, int y);
game.c 文件
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" //1.雷盘初始化函数的定义 void init_landmine(char arr[ROWS][COLS], int x, int y, char n) { for (int i = 0; i < x; i++) { for (int j = 0; j < y; j++) { arr[i][j] = n; } } } //2.打印雷盘函数的定义 //2.1 给玩家显示的小雷盘的打印 void print_show_landmine(char arr[ROWS][COLS], int x, int y) { for (int i = 0; i <= x; i++) { printf("%-2d ", i);//打印横坐标0~9 } printf("\n"); for (int i = 1; i <= x; i++) { printf("%-2d ", i );//打印纵坐标1~9 for (int j = 1; j <= y; j++) { printf("%-2c ", arr[i][j]);//打印雷盘 } printf("\n"); } printf("\n"); } //3.设置雷 void set_landmine(char arr[ROWS][COLS], int m) { while (m) { int x = rand() % 9 + 1; int y = rand() % 9 + 1; if (arr[x][y] == '0') { arr[x][y] = '1'; m--; } } } //4.找雷 //4.2统计输入坐标周围的雷的个数 int count_surround_landmine(char arr[ROWS][COLS],int x, int y) { int count = 0; for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { count += arr[x + i][y + j] - '0'; //字符型变整型:字符 - '0' //整型变字符型:整型 + '0' } } return count; } //4.1找雷函数 void find_landmine(char arr1[ROWS][COLS], char arr2[ROWS][COLS], int x, int y) { //不断的找雷,是个循环过程 int win = 0; int n = 0; int m = 0; while (win < (x * y - easy)) { printf("\n"); printf("请输入排查雷的位置的【行】和【列】:"); scanf("%d %d", &n, &m); if (n > 0 && n < 10 && m>0 && m < 10) { //printf("输入成功,找雷"); //测试 if (arr1[n][m] == '1') { printf("\n"); printf("踩中地雷,游戏结束\n"); print_show_landmine(arr1, row, col); //显示地雷位置,告诉玩家哪里踩中 break; } else if(arr1[n][m] == '0') { arr2[n][m] = count_surround_landmine(arr1, n, m) + '0'; //把周围雷的结果显示给玩家看的二维数组 printf("\n"); print_show_landmine(arr2, row, col);//显示给玩家看的二维数组 win++; } } else printf("输入错误,请重新输入\n"); } //成功的情况 if (win == (x * y - easy)) printf("恭喜你,已查出所有地雷,游戏结束\n"); }
test.c 文件
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" void menu() { printf("******************************\n"); printf("******************************\n"); printf("******* 1.PLAY GAME *******\n"); printf("******* 0.EXIT GAME *******\n"); printf("******************************\n"); printf("******************************\n"); } void game() { //printf("玩游戏\n"); //游戏逻辑: // 1.创建两个二维数组,分别做两个雷盘 // 考虑到边缘八个元素的排雷统计会出现越界的象限,设置的二维数组要大一圈 char check[ROWS][COLS] = {'0'};//程序员看的 char show[ROWS][COLS] = {'0'};//用户看的 // 2.初始化雷盘 //【一个设置雷、布雷、排雷的计算"0"为无,"1"为雷】,【一个显示给玩家"*"为隐藏地区,数字为周围的雷数】,皆为字符数组(好管理) init_landmine(check,ROWS,COLS, '0'); init_landmine(show,ROWS,COLS, '*'); // 3.打印雷盘 print_show_landmine(show, row, col); //小雷盘 // 4.利用随机函数rand(),srand((unsigned int)time(NULL)),来进行随机坐标的设置雷 //在小雷盘里面设置雷【即限制下标的大雷盘,大雷盘下标:1~9】 //判断要设置雷的地方是否有雷,有则不下 set_landmine(check, easy); //print_show_landmine(check, row, col); //显示地雷位置 // 5.排雷 // ① 条件:判断用户输入的坐标在小一圈的雷盘中,然后再判断是否是雷,若是则结束游戏,若不是则统计 // ② 统计雷:周围的雷加起来 - 8*'0' == 整型字符(返回类型),变成字符型直接 + '0'即可 // ③ 结束条件:排查格子数 == 小一圈的雷盘 - 雷数(循环条件同理) find_landmine(check,show, row, col); printf("\n"); } int main() { int input = 0; srand((unsigned int)time(NULL)); do { menu(); printf("请输入你的选择 > "); scanf("%d", &input); switch (input) { case 1: printf("\n————开始游戏————\n"); game(); break; case 0: printf("\n退出游戏\n"); break; default: printf("\n输入错误,请重新输入!\n"); break; } } while (input); return 0; }
三、运行结果演示
以上博客仅供分享