C语言数组超详细讲解下篇扫雷
时间:2022-10-15 10:18:43|栏目:C代码|点击: 次
前言
本文接着复习前面所学知识,以扫雷游戏为例。
1、扫雷是什么?
百度百科:《扫雷》是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。
2、程序框架
程序整体的框架可以搬用上篇三子棋的,这种框架也可以当作一种通用的形式,加以运用。
2.1 主函数
int main() { int input = 0; srand((unsigned int)time(NULL));//产生随机数 do { menu();//菜单提示 printf("请输入 ==> ");//输入1或0, scanf("%d", &input); switch (input)//根据输入选择是否玩游戏 { case 1: game();//玩游戏的具体实现 break; case 0: printf("退出游戏\n"); break; default: printf("选择错误,重新选择!\n"); break; } } while (input); return 0; }
2.2 函数menu
输出提示菜单,提醒玩家,1是玩游戏,0是退出游戏
void menu() { printf("******************************\n"); printf("********* 1. play ********\n"); printf("********* 0. exit ********\n"); printf("******************************\n"); }
2.3 函数game
数组mine,初始化后放入字符 ‘0’
- mine数组后续放入10个雷,有雷的位置用字符 ‘1’ 表示,没有雷的位置仍然是字符 ‘0’
- 10个雷的位置随机生成
数组show,初始化后放入字符 ‘*’
- 字符 ‘*’ 是将生成雷的位置遮挡住,不让玩家看见
- show数组放入棋盘中关于具体坐标周围的雷的信息
- 如果坐标周围有雷,将统计雷的个数,并显示在这个坐标上
void game() { printf("开始玩游戏!\n"); //扫雷游戏的实现 //mine数组是用来存放布置好的雷的信息 //就10个雷在什么位置 char mine[ROWS][COLS] = { 0 };//'0' //show数组是用来存放排查出的雷的信息 //坐标周围有几个雷 char show[ROWS][COLS] = { 0 };//'*' //初始化棋盘 init_board(mine, ROWS, COLS, '0'); init_board(show, ROWS, COLS, '*'); //打印棋盘 //show_board(mine, ROW, COL);//全是字符'0' //show_board(mine, ROW, COL);//全是'*' //布置雷 set_mine(mine, ROW, COL);//雷的数组 //show_board(mine, ROW, COL);这是显示10个雷在哪里 show_board(show, ROW, COL);//输出*暂时掩盖雷在哪里 //排查雷 find_mine(mine, show, ROW, COL); }
2.3.1 函数init_board
init_board初始化参数是将棋盘初始化,让整个棋盘显示字符 ‘0’ 和 ‘*’
//初始化棋盘 参数:行数 列数 行数 列数 字符0或* void init_board(char arr[ROWS][COLS], int rows, int cols, char set) {//set表示初始化传进来的字符是0 还是 * int i = 0; int j = 0; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { arr[i][j] = set; } } }
2.3.2 函数show_board
show_board是展示棋盘的,可以看到棋盘里面雷的信息,以及后续扫雷时,棋盘的具体状态
//展示棋盘 void show_board(char arr[ROWS][COLS], int row, int col) { int i = 0; int j = 0; printf("------------扫雷------------\n"); for (i = 0; i <= col; i++) { printf("%d ", i);//列号,棋盘首先打印列数 } printf("\n"); for (i = 1; i <= row; i++) { printf("%d ", i);//行前面的数字,行号 for (j = 1; j <= col; j++) { printf("%c ", arr[i][j]);//打印棋盘每个元素 } printf("\n"); } printf("------------扫雷------------\n"); }
2.3.3 函数set_mine
函数set_mine是布置雷的,会在棋盘内随机在10个坐标位置产生雷
//布置雷 void set_mine(char mine[ROWS][COLS], int row, int col) { int count = EASY_COUNT;//布置10个雷 int x = 0;//行坐标 int y = 0;//列坐标 while (count)//直到10个雷布置完成,退出循环 { x = rand() % row + 1;//取模是0-8,加1就是1-9 y = rand() % col + 1; if (mine[x][y] == '0')//是空的,就放雷,否则重新随机产生坐标位置 { mine[x][y] = '1';//布置雷 count--; } } }
2.3.4 函数find_mine
函数find_mine是排查雷,每次玩家排雷都先输入一个坐标,然后判断坐标上的字符是否为1:
- 1为雷,游戏结束
- 不是1,统计坐标周围8个位置雷的个数,以字符放入形式显示在坐标上
//排查雷 void find_mine(char mine[ROWS][COLS], char show[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)//在1-9的坐标范围内 { if (mine[x][y] == '1')//确定坐标为字符'1',就是雷 { printf("很遗憾,被炸死了\n"); show_board(mine, ROW, COL);//显示所有雷的位置 break; } else//不是字符1,坐标就不是雷,显示坐标周围有雷的个数 { int count = get_mine_count(mine, x, y);//函数计算类的个数 show[x][y] = count + '0';//周围有雷的个数+'0'就转换成字符了 show_board(show, ROW, COL);//打印出来,每次扫雷后的棋盘 win++;//扫了一次雷就++ } } else//超过坐标范围 { printf("坐标非法,重新输入\n"); } } if (win == row * col - EASY_COUNT)//扫雷次数==9*9-10 71次就结束 { printf("恭喜你,排雷成功\n"); show_board(mine, ROW, COL);//显示雷的信息 } }
2.3.5 函数get_mine_count
函数get_mine_count统计雷的个数:
- 字符 ’1‘代表有雷,字符 ’0‘代表没有, ’1‘- ’0‘为数字1,代表1个雷
- 坐标周围8个坐标上的字符相加 - 8 * ‘0’,结果就是有雷的个数,是整形
//统计坐标周围有雷的个数 int get_mine_count(char mine[ROWS][COLS], int x, int y) {//坐标周围的8个地方减去'0',再相加的个数就是类的个数 return mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0'; }
3、头文件.h
#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_COUNT 10 //10个雷的个数 //初始化 void init_board(char arr[ROWS][COLS], int rows, int cols, char set); //打印 void show_board(char arr[ROWS][COLS], int row, int col); //布置雷 void set_mine(char mine[ROWS][COLS], int row, int col);
4、游戏试玩
运行结果见下图,基本满足了游戏功能。
完整代码放在gitee中:
总结
本文只涉及了较为基础的扫雷游戏,等后面学习更复杂的知识后,可以对扫雷游戏进行完善。扫雷游戏整体编写思路完全可以参考三子棋来实现。