C语言函数(三):数组和函数实现扫雷游戏

目录

  • 1.扫雷游戏的分析和设计
    • 1.1.扫雷游戏的功能说明
    • 1.2.游戏的分析与设计
      • 1.2.1 数据结构的分析
      • 1.2.2 文件结构设计
  • 2.扫雷游戏的代码实现

1.扫雷游戏的分析和设计

1.1.扫雷游戏的功能说明

  • 使用控制台实现经典的扫雷游戏
  • 游戏可以通过菜单实现继续玩游戏或者退出游戏
  • 扫雷的棋盘是9*9的格子
  • 默认随机排布10个雷
  • 排查雷
    • 如果位置不是雷,则显示周围有几个雷
    • 如果是雷,则炸死游戏结束
    • 把除10个雷之外的所有雷都找出来,排雷成功,游戏结束

游戏界面
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

1.2.游戏的分析与设计

1.2.1 数据结构的分析

扫雷的过程中,布置的雷和排出的雷都需要被存储,因为如果将两种都放在一起,就分别不出这个位置是雷的位置还是周围8个格子的雷的总数。

因为我们需要在99的棋盘上布置雷的信息和排查雷,首先想到的是创建一个99的数组来实现棋盘。在这里插入图片描述

那如果这个位置布置雷,就存放1,没有布置雷就存放0。
当这个位置不是雷的时候,就需要统计周围8个位置的和,然后存放到当前位置。
那如果在计算边角时进行计算,就会发生数组越界的问题,为了解决这个问题,我们可以再在周围加一圈构成11*11的棋盘,这样就不会发生数组越界了。
解决了这个问题,就可以关注两个数组的问题了,因为我们的展示界面全是由 *构成的,而排查雷需要使用数字来表示,那我们可以使用数字字符来表示数值,最后将字符转化为数字就行了

1.2.2 文件结构设计

这里我们设置3个文件

1.test.c 文件中写游戏的逻辑测试
2.game.c 文件中写游戏的函数实现
3.game.h 文件中写游戏需要的数据类型和游戏声明

2.扫雷游戏的代码实现

第一步:菜单设置

test.c

void menu(void) {printf("******************\n");printf("******1.play******\n");printf("******0.exit******\n");printf("******************\n");int main() {int input = 0;//srand((unsigned int)time(NULL));//使用时间种子do {menu();printf("请选择:>");scanf("%d", &input);if (input == 1) {//printf("ready\n");game();}else if(input == 0) {printf("end\n");}else {printf("输入错误,重新输入\n");}} while (input);return 0;
}
}

这样就可输出菜单,选择1的话就可以开始游戏,选择0退出游戏,选择错误重新选择

第二步:游戏函数

test.c

void game(void) {//设置棋盘的格数,,11*11的棋盘不会出现越界问题char mine[ROWS][COLS];//11char show[ROWS][COLS];//11//初始化棋盘InitBoard(mine, ROWS, COLS,'0');InitBoard(show, ROWS, COLS,'*');}

game.h

#include<stdio.h>#define COL 9
#define ROW 9#define ROWS ROW+2
#define COLS COL+2//初始化棋盘函数
void InitBoard(char borad[ROWS][COLS], int rows, int cols,char type);

game.c

#include"game.h"
void InitBoard(char borad[ROWS][COLS], int rows, int cols,char type) {for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {borad[i][j] = type;}}
}

这个函数的作用是创建数组,初始化棋盘,分别将数据类型和函数实现写在头文件中

第三步:打印棋盘

test.c

void game(void) {//设置棋盘的格数,,11*11的棋盘不会出现越界问题char mine[ROWS][COLS];//11char show[ROWS][COLS];//11//初始化棋盘InitBoard(mine, ROWS, COLS,'0');InitBoard(show, ROWS, COLS,'*');//打印棋盘Printborad(show, ROW, COL);Printborad(mine, ROW, COL);
}

game.h


#define COL 9
#define ROW 9#define ROWS ROW+2
#define COLS COL+2
//初始化棋盘函数
void InitBoard(char borad[ROWS][COLS], int rows, int cols,char type);
//打印棋盘函数
void Printborad(char borad[ROW][COL], int row,int col);

game.c

void Printborad(char borad[ROW][COL],int row,int col) {for (int i = 0; i <= row; i++) {printf("%d ", i);}printf("\n");for (int i = 1; i <= row; i++) {printf("%d ", i);for (int j = 1; j <= col; j++) {printf("%c ",borad[i][j]);}printf("\n");}
}

这个函数用以打印棋盘,可以看出棋盘的规划是否正确,当然我们只用打印show棋盘,不用打印mine棋盘,因为mine棋盘可以看到的全是0,这里为了不多写一个函数用来分别打印’*‘和’0’,所有我们再传一个一个参数type,告诉Printboard函数应该打印什么字符。

第四步:布置雷

test.c

void game(void) {//设置棋盘的格数,,11*11的棋盘不会出现越界问题char mine[ROWS][COLS];//11char show[ROWS][COLS];//11//初始化棋盘InitBoard(mine, ROWS, COLS,'0');InitBoard(show, ROWS, COLS,'*');//打印棋盘Printborad(show, ROW, COL);	//Printborad(mine, ROW, COL);//布置雷SetMine(mine, ROW, COL);Printborad(mine, ROW, COL);//查看是否将雷布置好了
}
int main() {int input = 0;srand((unsigned int)time(NULL));//使用时间种子do {menu();printf("请选择:>");scanf("%d", &input);if (input == 1) {//printf("ready\n");game();}else if(input == 0) {printf("end\n");}else {printf("输入错误,重新输入\n");}} while (input);return 0;
}

game.h

#include<time.h>//使用时间种子
#include<stdlib.h>//使用随机数#define COUNT 10//10个雷//布置雷函数
void SetMine(char borad[ROW][COL], int row, int col);

game.c

void SetMine(char borad[ROW][COL], int row, int col) {//产生随机数int count = COUNT;while (count) {int x = rand() % row + 1;int y = rand() % col + 1;if (borad[x][y] == '0') {borad[x][y] = '1';count--;}}}

这里使用随机数设置雷的位置坐标,需要包含头文件#include<time.h>和
#include<stdlib.h>,使用语句srand((unsigned int)time(NULL));确定时间种子,这样就可以将雷布置进去了,可以使用Printborad(mine, ROW, COL);打印棋盘看看雷布置的正确与否。

第五步:排查雷

test.c

void game(void) {//设置棋盘的格数,,11*11的棋盘不会出现越界问题char mine[ROWS][COLS];//11char show[ROWS][COLS];//11//初始化棋盘InitBoard(mine, ROWS, COLS,'0');InitBoard(show, ROWS, COLS,'*');//打印棋盘Printborad(show, ROW, COL);	//Printborad(mine, ROW, COL);//布置雷SetMine(mine, ROW, COL);Printborad(mine, ROW, COL);//查看是否将雷布置好了//排查雷FindMine(mine, show, ROW, COL);}

game.h

void FindMine(char mine[ROW][COL], char show[ROW][COL], int row, int col);

game.c

int GetMineCount(char mine[ROWS][COLS], int x, int y) {return (mine[x - 1][y] + mine[x - 1][y - 1] +mine[x-1][y+1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x][y + 1] + mine[x + 1][y + 1] - 8 * '0');
}void FindMine(char mine[ROW][COL], char show[ROW][COL], int row, int col) {int x = 0;int y = 0;int win = 0;while (win < row * col- COUNT) {printf("输入要查看的坐标:>");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col) {if (mine[x][y] == '1') {printf("很遗憾,你被炸死了\n");Printborad(show, ROW, COL);break;}else {//说明此处不是雷,则统计周围8个雷int count = GetMineCount(mine, x, y);show[x][y] = count + '0';Printborad(show, ROW, COL);win++;}}else {printf("坐标非法,重新输入\n");}}if (win == row * col - COUNT) {printf("恭喜,排雷成功\n");Printborad(mine, ROW, COL);}
}

使用FindMine函数排查雷,先输入要查看的坐标,如果坐标符合规定,则看这个坐标是否是雷,如果不是则计算周围8个位置的和并输出在棋盘上,当排查完71个没有雷的位置后,游戏成功。如果该位置非法,则重新输入。

以上涉及到一个重要的知识点,那就是:如何将数字字符转化为数字
可以直接使用数字字符减去字符0,比如:
‘0’ - ‘0’ = 0
‘1’ - ‘0’ = 1
‘55’ - ‘0’ = 55
这是因为字符之间的减法是减的ASCII码值,所以ASCII值相减就可以得到数字。

完整代码:
game.h

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<time.h>//使用时间种子
#include<stdlib.h>//使用随机数#define COUNT 10//10个雷#define COL 9
#define ROW 9#define ROWS ROW+2
#define COLS COL+2
//初始化棋盘函数
void InitBoard(char borad[ROWS][COLS], int rows, int cols,char type);
//打印棋盘函数
void Printborad(char borad[ROW][COL], int row,int col);
//布置雷函数
void SetMine(char borad[ROW][COL], int row, int col);
//排查雷
void FindMine(char mine[ROW][COL], char show[ROW][COL], int row, int col);

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void InitBoard(char borad[ROWS][COLS], int rows, int cols,char type) {for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {borad[i][j] = type;}}
}void Printborad(char borad[ROW][COL],int row,int col) {for (int i = 0; i <= row; i++) {printf("%d ", i);}printf("\n");for (int i = 1; i <= row; i++) {printf("%d ", i);for (int j = 1; j <= col; j++) {printf("%c ",borad[i][j]);}printf("\n");}
}void SetMine(char borad[ROW][COL], int row, int col) {//产生随机数int count = COUNT;while (count) {int x = rand() % row + 1;int y = rand() % col + 1;if (borad[x][y] == '0') {borad[x][y] = '1';count--;}}}int GetMineCount(char mine[ROWS][COLS], int x, int y) {return (mine[x - 1][y] + mine[x - 1][y - 1] +mine[x-1][y+1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x][y + 1] + mine[x + 1][y + 1] - 8 * '0');
}void FindMine(char mine[ROW][COL], char show[ROW][COL], int row, int col) {int x = 0;int y = 0;int win = 0;while (win < row * col- COUNT) {printf("输入要查看的坐标:>");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col) {if (mine[x][y] == '1') {printf("很遗憾,你被炸死了\n");Printborad(show, ROW, COL);break;}else {//说明此处不是雷,则统计周围8个雷int count = GetMineCount(mine, x, y);show[x][y] = count + '0';Printborad(show, ROW, COL);win++;}}else {printf("坐标非法,重新输入\n");}}if (win == row * col - COUNT) {printf("恭喜,排雷成功\n");Printborad(mine, ROW, COL);}
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu(void) {printf("******************\n");printf("******1.play******\n");printf("******0.exit******\n");printf("******************\n");
}void game(void) {//设置棋盘的格数,,11*11的棋盘不会出现越界问题char mine[ROWS][COLS];//11char show[ROWS][COLS];//11//初始化棋盘InitBoard(mine, ROWS, COLS,'0');InitBoard(show, ROWS, COLS,'*');//打印棋盘Printborad(show, ROW, COL);	//Printborad(mine, ROW, COL);//布置雷SetMine(mine, ROW, COL);Printborad(mine, ROW, COL);//查看是否将雷布置好了//排查雷FindMine(mine, show, ROW, COL);}
int main() {int input = 0;srand((unsigned int)time(NULL));//使用时间种子do {menu();printf("请选择:>");scanf("%d", &input);if (input == 1) {//printf("ready\n");game();}else if(input == 0) {printf("end\n");}else {printf("输入错误,重新输入\n");}} while (input);return 0;
}

感谢观看!

/考研势在必行/

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

网课:数独挑战——牛客(题解与疑问)

题目描述 数独是一种填数字游戏&#xff0c;英文名叫 Sudoku&#xff0c;起源于瑞士&#xff0c;上世纪 70 年代由美国一家数学逻辑游戏杂志首先发表&#xff0c;名为 Number Place&#xff0c;后在日本流行&#xff0c;1984 年将 Sudoku 命名为数独&#xff0c;即 “独立的数…

刘谦春晚纸牌魔术背后的数学—海明码原理简介

在昨天2024年的春晚舞台上&#xff0c;魔术大师刘谦以一场令人拍案叫绝的纸牌魔术再度震撼全场。他巧妙地利用了数学原理&#xff0c;精准无误地让观众“随机”选择的纸牌完成了配对&#xff0c;尤其是令人忍俊不禁的是主持人尼格买提的纸牌却没有如愿配对&#xff0c;小尼碎了…

机器学习复习(8)——逻辑回归

目录 逻辑函数&#xff08;Logistic Function&#xff09; 逻辑回归模型的假设函数 从逻辑回归模型转换到最大似然函数过程 最大似然函数方法 梯度下降 逻辑函数&#xff08;Logistic Function&#xff09; 首先&#xff0c;逻辑函数&#xff0c;也称为Sigmoid函数&#…

安全之护网(HVV)、红蓝对抗

文章目录 红蓝对抗什么是护网行动&#xff1f;护网分类护网的时间 什么是红蓝对抗红蓝对抗演练的目的什么是企业红蓝对抗红蓝对抗价值参考 红蓝对抗 什么是护网行动&#xff1f; 护网的定义是以国家组织组织事业单位、国企单位、名企单位等开展攻防两方的网络安全演习。进攻方…

C++ 贪心 区间问题 区间选点

给定 N 个闭区间 [ai,bi] &#xff0c;请你在数轴上选择尽量少的点&#xff0c;使得每个区间内至少包含一个选出的点。 输出选择的点的最小数量。 位于区间端点上的点也算作区间内。 输入格式 第一行包含整数 N &#xff0c;表示区间数。 接下来 N 行&#xff0c;每行包含两…

洛谷p4391 无限传输

考察字符串周期的题 题目链接 结论 要求字串 s s s的最短循环字串长就是&#xff1a; a n s n − p m t [ n ] ansn-pmt[n] ansn−pmt[n] 证明如下&#xff1a; 这是最大的前缀和后缀 现在我们做如下操作&#xff1a; 补全字段 a a a和字段 b b b&#xff0c;按子段 a a a的…

Linux操作系统基础(五):Linux的目录结构

文章目录 Linux的目录结构 一、Linux目录与Windows目录区别 二、常见目录介绍&#xff08;记住重点&#xff09; Linux的目录结构 一、Linux目录与Windows目录区别 Linux的目录结构是一个树型结构 Windows 系统 可以拥有多个盘符, 如 C盘、D盘、E盘 Linux 没有盘符 这个概…

AJAX——AJAX入门

1 什么是AJAX&#xff1f; Ajax&#xff08;Asynchronous JavaScript and XML&#xff09;是一种用于在Web应用程序中实现异步通信的技术。 简单点说&#xff0c;就是使用XMLHttpRequest对象与服务器通信。它可以使用JSON、XML、HTML和test文本等格式发送和接收数据。 AJAX最吸…

机器学习系列——(十一)回归

引言 在机器学习领域&#xff0c;回归是一种常见的监督学习任务&#xff0c;它主要用于预测数值型目标变量。回归分析能够通过对输入特征与目标变量之间的关系建模&#xff0c;从而对未知数据做出预测。 概念 回归是机器学习中的一种监督学习方法&#xff0c;用于预测数值型目…

一个坐标系查询网站python获取所有坐标系

技术路线选择 我是使用的vue 3开发的网页界面&#xff0c;element-plus构建网页组件&#xff0c;openlayer展示地图&#xff0c;express提供后端API&#xff0c;vercel进行在线部署。 python获取所有坐标系 想要展示所有坐标系&#xff0c;那需要先获取坐标系&#xff0c;怎么…

Openwifi 开源项目解读(一)

Openwifi 是一个关于wifi 系统的开源项目&#xff0c;是一个少有的优秀的关于wifi的开源项目&#xff0c;项目中包括了wifi的基带、lowmac、linux驱动 等三部分&#xff0c;其中基带、lowmac部分是在FPGA中实现&#xff0c;wifi驱动部分是运行在Linux下&#xff0c;因此openwif…

【资料分享】基于单片机大气压监测报警系统电路方案设计、基于飞思卡尔的无人坚守点滴监控自动控制系统设计(程序,原理图,pcb,文档)

基于单片机大气压监测报警系统电路方案设计 功能&#xff1a;实现的是大气压检测报警系统&#xff0c;可以通过传感器实时检测当前大气压值&#xff0c;可以设定大气压正常范围&#xff0c;当超过设定范围进行报警提示。 资料&#xff1a;protues仿真&#xff0c;程序&#x…

【教学类-47-01】UIBOT+IDM下载儿童古诗+修改文件名

背景需求&#xff1a; 去年12月&#xff0c;我去了其他幼儿园参观&#xff0c;这是一个传统文化德育教育特色的学校&#xff0c;在“古典集市”展示活动中&#xff0c;小班中班大班孩子共同现场念诵《元日》《静夜思》包含了演唱版本和儿歌念诵版本。 我马上也要当班主任了&a…

C++ 贪心 区间问题 最大不相交区间数

给定 N 个闭区间 [ai,bi] &#xff0c;请你在数轴上选择若干区间&#xff0c;使得选中的区间之间互不相交&#xff08;包括端点&#xff09;。 输出可选取区间的最大数量。 输入格式 第一行包含整数 N &#xff0c;表示区间数。 接下来 N 行&#xff0c;每行包含两个整数 ai…

基于鲲鹏服务NodeJs安装

准备工作 查看当前环境 uname -a查看鲲鹏云CPU架构 cat /proc/cpuinfo# 查看CPU architecture项&#xff0c;8表示v8&#xff0c;7表示v7下载Node.js NodeJs 选择 Linux Binaries (ARM) ARMv8 wget -c https://nodejs.org/dist/v12.18.3/node-v12.18.3-linux-arm64.tar.xz…

WWW 万维网

万维网概述 万维网 WWW (World Wide Web) 并非某种特殊的计算机网络。 万维网是一个大规模的、联机式的信息储藏所。 万维网用链接的方法能非常方便地从互联网上的一个站点访问另一个站点&#xff0c;从而主动地按需获取丰富的信息。 这种访问方式称为“链接”。 万维网是分…

【Kubernetes】在k8s1.24及以上版本基于containerd容器运行时测试pod从harbor拉取镜像

基于containerd容器运行时测试pod从harbor拉取镜像 1、安装高版本containerd2、安装docker3、登录harbor上传镜像4、从harbor拉取镜像 1、安装高版本containerd 集群中各个节点都要操作 yum remove containerd.io -y yum install containerd.io-1.6.22* -y cd /etc/containe…

Docker 有哪些常见的用途?

Docker 是一种容器化技术&#xff0c;它允许应用程序在不同的环境之间具有一致的运行环境。这使得 Docker 在开发和运维领域中非常受欢迎&#xff0c;因为它简化了应用程序的部署和管理。以下是 Docker 的一些常见用途&#xff1a; 快速部署应用程序 Docker 允许开发人员和运…

[NSSCTF]-Web:[SWPUCTF 2021 新生赛]easy_sql解析

查看网页 有提示&#xff0c;参数是wllm&#xff0c;并且要我们输入点东西 所以&#xff0c;我们尝试以get方式传入 有回显&#xff0c;但似乎没啥用 从上图看应该是字符型漏洞&#xff0c;单引号字符注入 先查看字段数 /?wllm2order by 3-- 没回显 报错了&#xff0c;说明…

Java编程构建高效二手交易平台

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…