博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c语言—实现扫雷游戏
阅读量:3973 次
发布时间:2019-05-24

本文共 5200 字,大约阅读时间需要 17 分钟。

文章目录

什么是扫雷游戏

基于百度百科的解释为:

《扫雷》是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。

一、实现思路

扫雷的地图大小不定,埋的雷个数也不一定。地图越大,雷的个数越多越难。

为了能够较好的调整和改变扫雷的参数,故采用宏定义的方式定义游戏参数。用多文件能够较好地实现游戏程序,也更加清晰。
因为需要在地图上埋雷和判断雷的个数,所以如果只采用一张地图难以实现,这里采用两张一模一样的地图。其中一张用来埋雷,另外一张用来显示地图和选择位置雷的个数。
但是由于判断周围雷的个数时,由于中间和最边上的区域判断雷个数的方法不一样,所以在实现代码的过程中,将地图在显示的基础上增加两行。减去上下两行和最左右两行,剩下的区域用于游戏。
关于雷计算方法的解释:

判断一个位置附近雷的个数时,需要判断八个位置的情况,由于靠近边缘的位置缺少了几个位置,所以为了统一计算方法,简单代码过程,牺牲一些内存空间。上下左右都增加一行或一列的无雷区域后,用于游戏的区域无论哪个区域其计算方法都一致,从而就只需要一种计算方式。

二、头文件

提示:

通过改变宏定义数字的大小即可改变扫雷的行列数以及炸弹数哦!
还可以改变棋盘图标的样式哈

#include
#include
#include
#include
#define ROW 10 //行数#define COL 10 //列数#define START '*' //位置的样式#define MINE 35 //雷的个数extern void game();

#include<stdlib.h>

#include<time.h>

这两个头文件是为了采用时间作为随机数所需要的库函数

三、主函数文件

1.菜单函数

void Menu()//游戏菜单{
printf("+--------------------+\n"); printf("| 扫雷游戏 |\n"); printf("| 1.PLAY 2.EXIT |\n"); printf("+--------------------+\n"); printf("请输入您的选择# ");}

2.主函数

int main(void){
Menu(); int x = 1; while (x) {
scanf("%d", &x); switch (x) {
case 1: game();//开始游戏 Menu(); break; case 2: x = 0;//结束循环 break; default: printf("您的输入有误,请重新输入# "); break; } } printf("bye~bye~\n"); system("pause"); return 0;}

四、游戏文件

1.地图初始化

memset(show_board, START, sizeof(show_board));//用START来初始化具有sizeof()个数元素的数组        memset(mine_board, '0', sizeof(mine_board));

或者用两个循环嵌套给二维数组每个元素进行赋值

void Init_Board(char arr[][COL],char x){
int row = 0; int col = 0; for (;row < ROW;row++) {
for (;col < COL; col++) {
arr[row][col] = x; } }}

2.展示地图

显示地图的函数

static void Show_Board(char arr[][COL+2])//显示扫雷图函数{
system("cls");//清屏 printf(" "); for (int i = 1;i < COL+1;i++) {
printf(" %2d", i); } Line(); for (int i = 1;i < ROW+1;i++) {
printf("%-2d |", i );//靠左的整型格式控制 for (int j = 1;j < COL+1;j++) {
printf(" %c |", arr[i][j]); } Line(); }}

输出间隔线的子函数,用于减少重复代码

static void Line()//行之间的间隔线{
printf("\n "); for (int i = 0;i < COL;i++) {
printf("----"); } printf("\n");}

3.埋雷函数

因为采用的随机数对地图进行埋雷,难免会有重复值,在对随机坐标进行赋值时,需要先判断此处是否已经有雷。没有雷才埋雷,埋雷个数才能减一。

static void Set_Board(char arr[][COL+2])//埋雷函数,用'1’表示雷,'0'表示没有雷{
int row = 0; int col = 0; int x = MINE; while (x) {
row = rand() % ROW + 1; col = rand() % COL + 1; if (arr[row][col] != '1')//判断此处没有雷才能减少循环次数 {
arr[row][col] = '1'; x--; } }}

4.判断该位置附近雷的个数

因为采用的是字符数组,在进行个数计算时,可以巧妙的运用ascii码表进行计算和最后显示个数。

static char Judge_Board(char arr[][COL+2], int row, int col)//判断此处雷的个数{
return arr[row - 1][col - 1] + arr[row - 1][col] + arr[row - 1][col + 1] + \ arr[row][col + 1] + arr[row + 1][col + 1] + arr[row + 1][col] + \ arr[row + 1][col - 1] + arr[row][col - 1] - 7*'0';//因为类型是字符,要用ascii码转换}

八个位置上的数减去‘0’的ascii码值后,只剩下一个‘0’的ascii码值。并且每有一个地雷其ascii码值就会加一,其对应的字符相应的加一。

5.主游戏函数

进行游戏进程判断时,需要讨论四个方面

  1. 玩家的输入是否合法
  2. 判断是否踩雷
  3. 没有踩雷后,判断周围雷的个数
  4. 判断是否胜利
void game(){
srand((unsigned long)time(NULL));//种随机数种子 char show_board[ROW+2][COL+2];//用来展示的二维数组 char mine_board[ROW+2][COL+2];//用来埋雷的二维数组 memset(show_board, START, sizeof(show_board));//用START来初始化具有sizeof()个数元素的数组 memset(mine_board, '0', sizeof(mine_board)); Set_Board(mine_board);//埋地雷 Show_Board(show_board);//展示地图 int x = ROW*COL-MINE;//计算除了地雷剩余的位置 int row = 0; int col = 0; while (x) {
printf("请输入选择的位置
# "); scanf("%d %d", &row, &col); if (row <= 0 || row > ROW || col <= 0 || col > COL)//验证是否是有效的位置坐标 {
printf("输入错误,"); continue;//跳过循环剩下所有的代码 } if (show_board[row][col] != START)//判断是否重复输入 {
printf("重复输入,"); continue; } if (mine_board[row][col] == '1')//判断是否踩中雷 {
Show_Board(mine_board);//踩中雷后,把雷图展示出来 printf("You lose!\n"); break; } show_board[row][col] = Judge_Board(mine_board, row, col);//记录该位置周围雷的个数 Show_Board(show_board);//显示该位置周围雷的个数 x--;//有效游戏次数,剩余位置减一 } if (x == 0) {
printf("恭喜你,挑战成功!\n"); }}

五、代码运行展示

1.开始界面

开始菜单

2.游戏开始

在这里插入图片描述

3.游戏结束

在这里插入图片描述

全部程序展示完毕,欢迎您的宝贵建议

六、游戏原码

需要原码的童鞋点击此处

转载地址:http://qatki.baihongyu.com/

你可能感兴趣的文章
sysfs&nbsp;and&nbsp;/proc/bus/usb/device
查看>>
linux工作队列(转)
查看>>
跟我一起写udev规则(译)
查看>>
sysfs&nbsp;and&nbsp;/proc/bus/usb/device
查看>>
跟我一起写udev规则(译)
查看>>
USB和sysfs文件系统
查看>>
USB和sysfs文件系统
查看>>
udev(八):实战:使用udevadm修…
查看>>
android开发环境搭建(for&nbsp;驱动开发…
查看>>
android开发环境搭建(for&nbsp;驱动开发…
查看>>
android驱动例子(LED灯控制)
查看>>
为Android内核添加新驱动,并添加…
查看>>
利用条件变量实现线程间同步
查看>>
利用条件变量实现线程间同步
查看>>
linux&nbsp;下&nbsp;C&nbsp;程序(进程)&nbsp;内存布局
查看>>
linux&nbsp;下&nbsp;C&nbsp;程序(进程)&nbsp;内存布局
查看>>
位字段
查看>>
位字段
查看>>
C语言中整型
查看>>
C语言中整型
查看>>