C语言 扫雷游戏

代码在一个项目里完成,分成三个.c.h文件(game.c,game.h,main.c)
在Clion软件中通过运行调试。

/大概想法/
主函数main.c里是大框架(菜单,扫雷棋盘初始化,随机函数生成雷,玩家扫雷)
game.h函数声明(除main函数和游戏函数外的一些函数声明)
game.c函数实现(除main函数和游戏函数外的一些函数实现)

/game.c实现/

①先对扫雷棋盘进行初始化(使用两个大小一样的字符数组作为扫雷棋盘
1.存储雷 2.展示给玩家的扫雷棋盘。为了避免在遍历中出现越界访问,棋盘尺寸设置为11*11,在9*9的尺寸里布置雷,展示给玩家的也是9*9的尺寸。相当于隐藏了第一行和最后一行,第一列和最后一列。)
1棋盘初始化为0 2棋盘初始化为*

②初始化完棋盘,显示棋盘
③随机函数生成雷存储到第一个字符数组里
④玩家扫雷实现包括 :玩家输入坐标位置是否是雷。坐标不是雷情况下周围一圈是否有雷。该坐标不是雷且周围也没有雷的情况下利用递归显示这些坐标为空。

以下是部分函数实现:

//判断周围多少雷(除输入坐标外一圈的八个位置获取雷数信息。
对于字符,某个字符-'0’就是整数.八个坐标减去八个’0’就是八个坐标里有几个雷)

//判断周围多少雷,返回雷数
int BombNumber(char mine[ROWS][COLS],int row,int col){return mine[row -1][col-1] + mine[row - 1][col] + mine[row - 1][col+1] + \mine[row][col-1] + mine[row][col+1] + \mine[row+1][col - 1] + mine[row+1][col] + mine[row+1][col+1] -8*'0';
}

本来在玩家输入的坐标不是雷,且周围八个坐标不是雷的情况下,想在函数里列举把九个坐标存为空再显示出来的。但是在学习视频里提到可以利用递归呈现出一片空白的棋盘。在网上查阅别人的代码学习到了如何使用递归呈现一片棋盘。

//假设是3*3的棋盘show[row - 1][col - 1] = ' ';//第一行show[row - 1][col] = ' ';show[row - 1][col + 1] = ' ';show[row][col - 1] = ' ';//第二行show[row][col] = ' ';show[row][col + 1] = ' ';show[row + 1][col - 1] = ' ';//第三行show[row + 1][col] = ' ';show[row + 1][col + 1] = ' ';

递归呈现一片棋盘
//在这个代码里递归思想是1.该坐标不是雷 2.周围的八个坐标也不是雷
对玩家输入的坐标进行九次循环 判断每个坐标是否合法且没有雷也没有展示给玩家
坐标满足条件以后就调用判断一圈是否有雷的函数 假如循环中的某个坐标一圈没有雷就再次进入递归函数 再将该坐标的一圈坐标进行循环遍历 继续以上过程 假如坐标不满足条件时会结束递归 进入else语句 直到九次循环完事。

void BlankBoard(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col){int i=0,j=0,flag=0;show[row][col] = ' ';for(i=row-1;i<=row+1;i++) {for (j = col-1; j <=col+1; j++) {if((i>0&&i<=ROW)&&(j>0&&j<=COL)&&(mine[i][j]!='1')&&(show[i][j]=='*')) {flag = BombNumber(mine, i, j);//判断一圈是否是雷,返回的是雷的数量if(!flag)BlankBoard(mine,show,i,j);//递归elseshow[i][j]=flag+'0';//将得到的非0的雷数放到展示给玩家的棋盘里}}}
}

//玩家进行游戏的核心操作

void StartBomb(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col)
{char array[5]="\0";//使用字符串接收玩家输入的信息int x,y,flag=0,win=0;while(win<(row*col-Bomb))//展示给玩家的坐标数量<整个棋盘的非雷坐标数就进入循环//直到玩家看到的非*坐标数量已经是所有非雷坐标{printf("玩家输入坐标,坐标形式为:x,y\n");gets(array);x=array[0]-'0';//字符-'0'为整数y=array[2]-'0';if((x>=1&&x<=ROW)&&(y>=1&&y<=COL)&&(show[x][y])=='*')//坐标合法且没有显示给玩家{if(mine[x][y]=='1')//在存储雷的棋盘中'1'代表是雷{printf("很遗憾,该坐标中放了雷,玩家被炸死");printf("雷分布如下:\n");Display(mine,ROW,COL);//显示存储雷的棋盘break;}else{flag=BombNumber(mine, x, y);//判断该坐标周围一圈是否是雷if(flag>0){//周围一圈有雷show[x][y]=flag+'0';Display(show,ROW,COL);}else{BlankBoard(mine,show,x,y);Display(show,ROW,COL);}winwin=Showboard(show,ROW,COL);}//判断展示给玩家的坐标数}elseprintf("坐标无效,请重新输入\n");}if(win==(row*col-Bomb)){printf("恭喜玩家排雷成功!\n");Display(mine,ROW,COL);}
}

//以下是完整代码(本人没玩过正常的扫雷游戏,对扫雷游戏的输赢理解可能不太对,但大概思路没啥问题)

//main.c


#include"game.h"//初版扫雷// 显示菜单
void menu(){printf("*********1.game***0.退出*********\n");printf("*********输入数字进行选择***********\n");
}
//游戏核心
//使用两个字符数组1->存放雷信息 2->用于输出到屏幕
//使用随机函数放置雷
//玩家排雷void game() {char Mine [ROWS][COLS]={0};char Show [ROWS][COLS]={0};;//数组初始化Init(Mine,ROWS,COLS,'0');Init(Show,ROWS,COLS,'*');//显示//Display(Mine,ROWS,COLS);//显示初始化的雷棋盘Display(Show,ROWS,COLS);//显示玩家棋盘SetBomb(Mine,ROW,COL);//随机生成雷//Display(Mine,ROW,COL);//显示雷棋盘StartBomb(Mine,Show,ROW,COL);//玩家进行扫雷
}int main()
{setbuf(stdout,NULL);//及时输出缓冲区内容int number=0;srand((unsigned int )time(NULL));//时间戳帮助生成棋盘上的随机坐标do{menu();scanf("%d",&number);getchar();//玩家输入的坐标使用字符串输入的,所以此时需要用getchar取走\nswitch(number){case 1:game();break;case 0:printf("正在退出\n");break;default:printf("选择错误,重新输入\n");break;}}while(number);}

//game.h

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>#define ROW 9
#define COL 9#define ROWS (ROW+2)
#define COLS (COL+2)#define Bomb 10#ifndef TEXT1_GAME_H
#define TEXT1_GAME_Hvoid Init(char board[ROWS][COLS],int rows,int cols,char set);
void Display(char board[ROWS][COLS],int row,int col);
void SetBomb(char board[ROWS][COLS],int row,int col);
void StartBomb(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col);
int  BombNumber(char mine[ROWS][COLS],int row,int col);
void BlankBoard(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col);
int Showboard(char board[ROWS][COLS],int row,int col);
#endif

//game.c

#include"game.h"//初始化
void Init(char board[ROWS][COLS],int rows,int cols,char set){int i=0,j=0;for(i=0;i<ROWS;i++){for(j=0;j<COLS;j++)board[i][j]=set;}
}//显示函数
void Display(char board[ROWS][COLS],int row,int col)
{int i=0,j=0;//打印列数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 ",board[i][j]);printf("\n");}
}//放置炸弹
void SetBomb(char board[ROWS][COLS],int row,int col)
{int numberBomb=1;while(numberBomb<=Bomb){int x=(rand()%ROW)+1;int y=(rand()%COL)+1;if(board[x][y]=='0') {board[x][y] = '1';numberBomb++;}}
}void StartBomb(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col)
{char array[5]="\0";int x,y,flag=0,win=0;while(win<(row*col-Bomb)){printf("玩家输入坐标,坐标形式为:x,y\n");gets(array);x=array[0]-'0';y=array[2]-'0';if((x>=1&&x<=ROW)&&(y>=1&&y<=COL)&&(show[x][y])=='*'){if(mine[x][y]=='1'){printf("很遗憾,该坐标中放了雷,玩家被炸死");printf("雷分布如下:\n");Display(mine,ROW,COL);break;}else{flag=BombNumber(mine, x, y);if(flag>0){show[x][y]=flag+'0';Display(show,ROW,COL);}else{BlankBoard(mine,show,x,y);Display(show,ROW,COL);}}win=Showboard(show,ROW,COL);}elseprintf("坐标无效,请重新输入\n");}if(win==(row*col-Bomb)){printf("恭喜玩家排雷成功!\n");Display(mine,ROW,COL);}
}//判断周围多少雷
int BombNumber(char mine[ROWS][COLS],int row,int col){return mine[row -1][col-1] + mine[row - 1][col] + mine[row - 1][col+1] + \mine[row][col-1] + mine[row][col+1] + \mine[row+1][col - 1] + mine[row+1][col] + mine[row+1][col+1] -8*'0';
}//1.该坐标不是雷 2.周围的八个坐标也不是雷
void BlankBoard(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col){int i=0,j=0,flag=0;show[row][col] = ' ';for(i=row-1;i<=row+1;i++) {for (j = col-1; j <=col+1; j++) {if((i>0&&i<=ROW)&&(j>0&&j<=COL)&&(mine[i][j]!='1')&&(show[i][j]=='*')) {flag = BombNumber(mine, i, j);if(!flag)BlankBoard(mine,show,i,j);elseshow[i][j]=flag+'0';
/*          show[row - 1][col - 1] = ' ';show[row - 1][col] = ' ';show[row - 1][col + 1] = ' ';show[row][col - 1] = ' ';show[row][col] = ' ';show[row][col + 1] = ' ';show[row + 1][col - 1] = ' ';show[row + 1][col] = ' ';show[row + 1][col + 1] = ' ';*/}}}
}int Showboard(char board[ROWS][COLS],int row,int col){int i=0,j=0,number=0;for(i=1;i<=row;i++){for(j=1;j<=col;j++){if(board[i][j]!='*')number++;}}return number;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/259244.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SIMULINK 单相半波整流电路仿真

SIMULINK 单相半波整流电路仿真 去除毛刺&#xff0c;改步长 光滑如下&#xff1a;

JS中call()、apply()、bind()改变this指向的原理

大家如果想了解改变this指向的方法&#xff0c;大家可以阅读本人的这篇改变this指向的六种方法 大家有没有想过这三种方法是如何改变this指向的&#xff1f;我们可以自己写吗&#xff1f; 答案是&#xff1a;可以自己写的 让我为大家介绍一下吧&#xff01; 1.call()方法的原理…

MVCC是什么

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

做一个类似一点洗鞋上门预约软件需要有哪些功能?

专业洗衣洗鞋店管理软件&#xff0c;轻松实现衣物和鞋子的收取、清点、分拣、清洗、监督、配送、跟踪&#xff0c;让企业管理更高效。同时&#xff0c;简化洗涤厂各个环节&#xff0c;提升洗衣洗鞋服务质量与效率&#xff0c;并且可定制功能。 互联网洗衣洗鞋小程序开发&#x…

uniapp页面跳转函数

1.在需要跳转的类加一个点击事件click 2.写一个跳转函数 ToSetting() {uni.navigateTo({url:"/pages/tabbar-5-detial/setting/setting"})} ok了。 跳转的页面是静态页面&#xff0c;即没有从上一个页面获取数据。 最初级的页面跳转。。。

带大家做一个,易上手的家常辣子鸡

先从冰箱拿出鸡肉解冻 拿小半根葱 去掉最外面一层皮 切成小段 最备好 花椒 干辣椒 准备四五个大料 起锅烧油 这道菜需要放其他菜两到三倍的油 油温上来之后 放入干辣椒和花椒进行翻炒 等它们都烧黑之后捞出来 这样 辣味就留在油里面了 然后 倒入鸡肉 葱段 大料 然后 倒…

honle电源维修UV电源控制器EVG EPS40C-HMI

好乐UV电源控制器维修&#xff1b;honle控制器维修&#xff1b;UV电源维修MUC-Steuermodul 2 LΛmpen D-82166 主要维修型号&#xff1a; EVG EPS 60/120、EVG EPS 100、EVG EPS200、EVG EPS 220、EVG EPS 340、EVG EPS40C-HMI、EVG EPS60 HONLE好乐uv电源维修故障包括&#…

0012Java程序设计-ssm医院预约挂号及排队叫号系统

文章目录 **摘** **要**目 录系统实现5.2后端功能模块5.2.1管理员功能模块5.2.2医生功能模块 开发环境 摘 要 网络的广泛应用给生活带来了十分的便利。所以把医院预约挂号及排队叫号管理与现在网络相结合&#xff0c;利用java技术建设医院预约挂号及排队叫号系统&#xff0c;实…

【js】js实现多个视频连续播放:

文章目录 一、效果&#xff1a;二、实现&#xff1a; 一、效果&#xff1a; 二、实现&#xff1a; <!DOCTYPE html> <html> <head><title>Video Player</title><style>#progressBar { width: 800px;height: 20px;background-color: #dd…

SQL数据库知识点总结归纳

前后顺序可以任意颠倒,不影响库中的数据关系 关系数据库的逻辑性强而物理性弱,因此关系数据库中的各条记录前后顺序可以任意颠倒,不影响库中的数据关系 一名员工可以使用多台计算机(1:m),而一台计算机只能被一名员工使用(1:1),所以员工和计算机两个实体之间是一对多…

驾驭苹果的人工智慧模式:克服反击与应对挑战

苹果一年一度的秋季「春晚」时间越来越近&#xff0c;但在大模型浪潮下&#xff0c;苹果何时推出自己的「苹果GPT」成了另一个关注的话题。 毕竟&#xff0c;前有华为&#xff0c;后有小米&#xff0c;在中国手机厂商争相将大模型装进移动终端的同时&#xff0c;苹果却依旧对A…

当下流行视频剪辑软件会声会影2024,让你的视频制作更精彩

大家好呀&#xff01;今天小编给大家介绍一款超赞的视频编辑软件——会声会影2024&#xff01; 当下流行视频剪辑软件会声会影2024&#xff0c;让你的视频制作更精彩&#xff0c;会声会影2024不仅提供了各种酷炫的特效和滤镜&#xff0c;还有更多令人惊叹的功能等待着你的发掘…