摘要:展示雷盘和初始化雷盘不一样,展示雷盘只需要用即可,并不需要将都展示出来,只是为了我们更好的计算扫雷的位置周围的雷的数量。
目录
通过C语言实现简单的扫雷小游戏,由于创作者水平有限,未在该游戏中实现图形化界面,同时在真正扫雷游戏中点一个位置成功扫雷多个坐标的功能也未实现,功能较为简单,敬请原谅!
程序分为test.c、game.c两个源文件和game.h一个头文件。
test.c:主函数接口引入。
game.c:游戏的相关函数实现。
game.h:头文件引入、函数声明。
void test(){ srand((unsigned int)time(NULL)); int input = 0; do { menu(); printf("请输入->"); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("退出游戏!/n"); break; } } while (input);}int main(){ test(); return 0;}
分析:
1.主函数中引入了随机种子,生成随机数来方便后续的雷的生成
2.在通过menu()菜单呈现后,通过switch进行接口接入,当用户输入1时可以进行游戏,当用户输入0时即退出游戏。
3.总体是通过do while循环实现的,但巧妙的利用了将用户输入的数据填入while后面的括号中,即当用户输入0时while条件判断失败,游戏就终止。
异常处理:
在switch中虽然没有通过default可以进行异常处理,但当用户输入只要不为0的数据时,循环仍旧自动进行,在输入非0和非1的数据后,程序会要求玩家进行重新输入,会再次进入循环,实际上就已经相当于另类的异常处理。
void game(){ char mine[ROWS][COLS] = { 0 };//存取放置好雷的信息的雷盘 char show[ROWS][COLS] = { 0 };//存取展示给用户的信息的雷盘 Init_board(mine, ROWS, COLS, "0");//初始化雷盘 Init_board(show, ROWS, COLS, "*");//初始化展示的雷盘 Set_mine(mine, ROW, COL,EASY_COUNT);//埋雷 Display_board(show, ROW, COL);//展示想要展示雷盘 Find_mine(mine, show, ROWS, COLS);//排雷游戏开始}
分析:
1.为什么要建立两个雷盘?第一个雷盘是我们用来初始化雷的,即埋雷的,第二个雷盘是用来显示给玩家的,即显示玩家在哪个位置排雷了,并且以这个位置为中心的3*3的格子里有多少雷,也许大家会问,一个雷盘不好吗?一个雷盘当然也没有问题,但两个雷盘能够更好的对后续操作进行更好的处理,特别是我们在计算以我们要扫的格子为中心3*3范围内有多少雷时,第一个雷盘我们初始化了为1*11,这样是为了我们更好的计算我们要扫的位置处周围有多少雷。
给大家展示一下两个雷盘:
左边的雷盘为埋好雷的雷盘,右边的雷盘为呈现给玩家的雷盘。
2、初始化的第一个雷盘(11*11),我们将其全部都初始化为0,在后续的埋雷的过程中,将雷的位置的数据赋值为1,初始化展示的雷盘是将所有的位置的数据初始化为字符"*",后面我们排雷后将其赋值为我们排的地方的周围存在的雷的数量。
3.展示雷盘和初始化雷盘不一样,展示雷盘只需要用9*9即可,并不需要将11*11都展示出来,11*11只是为了我们更好的计算扫雷的位置周围的雷的数量。
void Init_board(char board[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++) { board[i][j] = set; } }}
分析:
雷盘初始化函数并不复杂,简单的运用for循环即可,需要注意的是,我们要根据初始化的雷盘不同在函数的最后一个参数的位置填入不同的字符。
void Display_board(char board[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 ", board[i][j]); } printf("/n"); }}
分析:
1.该展示函数中,第一个for循环是为了显示出列坐标来,方便玩家后续进行输出想要扫雷的坐标。
2.内层for循环前面的printf("%d",i)是为了显示出横坐标来坐标来。
3.需要注意的是不要忘了换行操作!
4.展示函数从1到9展示即可,因为不需要展示0下标和10下标的,这两个下标只是为了我们方便计算周围雷的数量,因为我们不需要考虑边缘位置的特殊性。
void Set_mine(char mine[ROWS][COLS], int row, int col,int count){ while (count) { int x = rand() % 9 + 1; int y = rand() % 9 + 1; if (mine[x][y] == "0") { mine[x][y] = "1"; count--; } }}
分析:
1.这个函数中count为我们想要埋雷的数量,每成功埋一个雷,count就会减1,当count为0时,埋雷全部结束,此时也将跳出循环。
2.这个函数中我们在生成雷的位置时之所以要+1的原因是因为,在前面我们开辟的是一个11*11的雷盘,我们想要埋雷的位置或者说我们想要在数组中对应的埋雷的位置是1到9,而对8取模得到的结果范围为0到8,加1之后为1到9。
3.为什么要将雷的位置的数据赋值为1?是为了在后面计算周围雷得数量,即将周围坐标的数据加起来即可得到周围雷的数量之和。
void Find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int rows, int cols){ int x = 0; int y = 0; int win = 0; while (win < (rows - 2) * (cols - 2) - EASY_COUNT) { printf("请输入你要排查的坐标:"); scanf("%d %d", &x, &y); if (x > ROW || x<0 || y>COL || y < 0) { printf("输入错误,请重新输入!/n"); } else { if (mine[x][y] == "1") { printf("很遗憾,你被炸死了!/n"); Display_board(mine, ROW, COL); break; } else { show[x][y] = count_num(mine, x, y)+"0"; Display_board(show, ROW, COL); win++; } } } if (win == (rows - 2) * (cols - 2) - EASY_COUNT) { printf("排雷成功!/n"); }}static int count_num(char mine[ROWS][COLS], int x, int y){ return mine[x - 1][y - 1] + mine[x - 1][y] + mine[x + 1][y] + mine[x + 1][y - 1] + mine[x + 1][y + 1] + mine[x - 1][y + 1] + mine[x][y + 1] + mine[x][y - 1]-8*"0";}
分析:
1.while后面的括号的意义:就是当我们扫完全部的雷后就跳出循环并通过后面的if条件进行判断是否将雷完全扫完,如果扫完就输出扫雷成功。
2.在输入坐标后,有两个分支,第一个分支就是如果坐标对应的位置是1,即雷,就会显示扫雷失败,,如果不是雷,就跳转到定义的count_num()计算该坐标周围雷的数量,该函数的实现就是将周围坐标所存储的值相加,减去8*‘0’,至于为什么需要减去字符0呢?因为我们在开辟雷盘时定义的数据类型是字符型,此处通过计算得到的数据是整型,减去‘0’之后得到的数据即为字符型真正对应的整型,后面存入要展示的雷盘时加上‘0’,也是为了将其由整型转换为字符型,方便存入雷盘中。
#include
#include #include #define ROW 9#define COL 9#define ROWS ROW+2#define COLS COL+2#define EASY_COUNT 10void menu();//菜单函数声明void game();//游戏主初始化函数声明void Init_board(char board[ROWS][COLS], int rows, int cols, char ch);//初始化函数声明void Set_mine(char mine[ROWS][COLS], int row, int col,int count);//埋雷函数声明void Display_board(char board[ROWS][COLS], int row, int col);//展示函数声明void Find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int rows, int cols);//扫雷函数声明 分析:
ROW即为雷盘的真正行数,COL即为雷盘的真正列数,EASY_COUNT即为雷的数量,如果大家想要提高游戏的难度,可以通过改变ROW、COL、EASY_COUNT即可。
#define _CRT_SECURE_NO_WARNINGS 1#include"game.h"//游戏函数void game(){ char mine[ROWS][COLS] = { 0 };//存取放置好雷的信息的雷盘 char show[ROWS][COLS] = { 0 };//存取展示给用户的信息的雷盘 Init_board(mine, ROWS, COLS, "0");//初始化雷盘 Init_board(show, ROWS, COLS, "*");//初始化展示的雷盘 Set_mine(mine, ROW, COL,EASY_COUNT);//埋雷 Display_board(show, ROW, COL);//展示想要展示雷盘 Find_mine(mine, show, ROWS, COLS);//排雷游戏开始}void test(){ srand((unsigned int)time(NULL)); int input = 0; do { menu(); printf("请输入->"); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("退出游戏!/n"); break; } } while (input);}int main(){ test(); return 0;}
#pragma once#include
#include #include #define ROW 9#define COL 9#define ROWS ROW+2#define COLS COL+2#define EASY_COUNT 10void menu();//菜单函数声明void game();//游戏主初始化函数声明void Init_board(char board[ROWS][COLS], int rows, int cols, char ch);//初始化函数声明void Set_mine(char mine[ROWS][COLS], int row, int col,int count);//埋雷函数声明void Display_board(char board[ROWS][COLS], int row, int col);//展示函数声明void Find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int rows, int cols);//扫雷函数声明
#define _CRT_SECURE_NO_WARNINGS 1#include"game.h"//菜单void menu(){ printf("***********************/n"); printf("******* 1.play ******/n"); printf("******* 0.exit ******/n"); printf("***********************/n");}//初始化函数void Init_board(char board[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++) { board[i][j] = set; } }}//展示函数void Display_board(char board[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 ", board[i][j]); } printf("/n"); }}//埋雷函数void Set_mine(char mine[ROWS][COLS], int row, int col,int count){ while (count) { int x = rand() % 9 + 1; int y = rand() % 9 + 1; if (mine[x][y] == "0") { mine[x][y] = "1"; count--; } }}//扫雷函数void Find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int rows, int cols){ int x = 0; int y = 0; int win = 0; while (win < (rows - 2) * (cols - 2) - EASY_COUNT) { printf("请输入你要排查的坐标:"); scanf("%d %d", &x, &y); if (x > ROW || x<0 || y>COL || y < 0) { printf("输入错误,请重新输入!/n"); } else { if (mine[x][y] == "1") { printf("很遗憾,你被炸死了!/n"); Display_board(mine, ROW, COL); break; } else { show[x][y] = count_num(mine, x, y)+"0"; Display_board(show, ROW, COL); win++; } } } if (win == (rows - 2) * (cols - 2) - EASY_COUNT) { printf("排雷成功!/n"); }}static int count_num(char mine[ROWS][COLS], int x, int y){ return mine[x - 1][y - 1] + mine[x - 1][y] + mine[x + 1][y] + mine[x + 1][y - 1] + mine[x + 1][y + 1] + mine[x - 1][y + 1] + mine[x][y + 1] + mine[x][y - 1]-8*"0";}
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/123071.html
摘要:新人小白的第一篇博客,有什么不好之处望多提意见。这个扫雷小游戏主要是基于二维数组,循环与基本的函数知识等。请输入坐标提示玩家输入坐标。换行是为了看着好看,要不然打印出来的数组会变形的。用来接收判断输赢的函数的返回值。 新人小白的第一篇博客,有什么不好之处望多提意见。 ...
摘要:设计实现扫雷游戏大致思路创建文件想法实现设计一个函数,实现建议菜单循环和分支选择游戏选项创造一个扫雷版面版面的大小最后是要可控的如何存放雷和版面的信息呢考虑排查雷时候的思路,我们要判断该位置周围个格子里面是否有雷初始化 ...
摘要:条消息语言入门三子棋语言实现详细版的博客博客条消息语言入门三子棋语言实现详细版的博客博客我们将雷盘初始化为统一的符号。 目录 1.原理简介 2.分布目标及代码实现 3.总结 1.原理简介 首先我们需要一个空的雷盘,在其中随机埋入十枚雷,当我们排这颗雷时,若此位置为雷,则游戏失败,若不...
摘要:每成功排一次雷,我们都要展示雷盘当场上剩下的格子数等于雷数时,游戏胜利,玩家踩雷时,游戏结束,所以我们这是一个判断输赢的函数。 前言:写完三子棋后,慢慢地熟悉了这种...
摘要:作者时间网站地址摘要语言实现我们小时候玩过的扫雷游戏,最近看到了一些扫雷游戏的简单实现,但是总有功能上的缺失,玩起来不那么的原汁原味,因此我增加了一些新功能确保玩家首次排雷一定不会炸死。 ...
阅读 981·2021-11-23 09:51
阅读 3468·2021-11-22 12:04
阅读 2715·2021-11-11 16:55
阅读 2919·2019-08-30 15:55
阅读 3220·2019-08-29 14:22
阅读 3348·2019-08-28 18:06
阅读 1237·2019-08-26 18:36
阅读 2126·2019-08-26 12:08