C语言实战——扫雷游戏

目录

  • 1. 扫雷游戏分析和设计
  • 2.扫雷游戏的代码实现

1. 扫雷游戏分析和设计

1.1扫雷游戏的功能说明

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

游戏的界面:

  • 初始界面:
    在这里插入图片描述
  • 排雷界面:
    在这里插入图片描述
  • 排雷失败界面:
    在这里插入图片描述

1.2 游戏的分析和设计
1.2.1 数据结构的分析
扫雷的过程中,布置的雷和排查出的雷的信息都需要存储,所以我们需要⼀定的数据结构来存储这些信息。
因为我们需要在9* 9的棋盘上布置雷的信息和排查雷,我们首先想到的就是创建⼀个9*9的数组来存放信息。
在这里插入图片描述

那如果这个位置布置雷,我们就存放1,没有布置雷就存放0。
在这里插入图片描述

假设我们排查(2,5)这个坐标时,我们访问周围的⼀圈8个黄色位置,统计周围雷的个数是1。
假设我们排查(8,6)这个坐标时,我们访问周围的⼀圈8个黄色位置,统计周围雷的个数时,最下面的三个坐标就会越界,为了防止越界,我们在设计的时候,给数组扩大一圈,雷还是布置在中间的9*9的坐标上,周围⼀圈不去布置雷就行,这样就解决了越界的问题。所以我们将存放数据的数组创建成11 *11是比较合适。

排雷的假设
在这里插入图片描述

周围加上⼀圈的棋盘
在这里插入图片描述

再继续分析,我们在棋盘上布置了雷,棋盘上雷的信息(1)和非雷的信息(0),假设我们排查了某⼀个位置后,这个坐标处不是雷,这个坐标的周围有1个雷,那我们需要将排查出的雷的数量信息记录存储,并打印出来,作为排雷的重要参考信息的。那这个雷的个数信息存放在哪里呢?如果存放在布置雷的数组中,这样雷的信息和雷的个数信息就可能或产生混淆和打印上的困难。

这里我们肯定有办法解决,比如:雷和非雷的信息不要使用数字,使用某些字符就行,这样就避免冲突了,但是这样做棋盘上有雷和非雷的信息,还有排查出的雷的个数信息,就比较混杂,不够方便。

这里我们采用另外⼀种方案,我们专门给⼀个棋盘(对应⼀个数组mine)存放布置好的雷的信息,再给另外⼀个棋盘(对应另外⼀个数组show)存放排查出的雷的信息。这样就互不干扰了,把雷布置到mine数组,在mine数组中排查雷,排查出的数据存放在show数组,并且打印show数组的信息给后期排查参考。

同时为了保持神秘,show数组开始时初始化为符’*‘,为了保持两个数组的类型⼀致,可以使用同⼀套函数处理,mine数组最开始也初始化为字符’0’,布置雷成’1’。如下如:

mine数组布置雷后的状态
在这里插入图片描述

show输出初始化的状态
在这里插入图片描述

对应的数组应该是:

char mine[11][11] = {0};//⽤来存放布置好的雷的信息 
char show[11][11] = {0};//⽤来存放排查出的雷的个数信息

1.2.2 文件结构设计
使用多文件的形式对函数的声明和定义,我们设计三个文件:

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

2.扫雷游戏的代码实现

game.h

#pragma once#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//初始化棋盘
void InitBoard(char arr[ROWS][COLS], int rows, int cols,char set);//打印棋盘
void DisplayBoard(char arr[ROWS][COLS], int row, int col);//布置雷
void SetMine(char mine[ROWS][COLS], int row, int col);//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

game.c

#define _CRT_SECURE_NO_WARNINGS #include "game.h"void InitBoard(char arr[ROWS][COLS], int rows, int cols,char set)
{for (int i = 0; i < ROWS; i++){for (int j = 0; j < COLS; j++){arr[i][j] = set;}}
}void DisplayBoard(char arr[ROWS][COLS], int row, int col)
{printf("------扫雷游戏------\n");//打印行号for (int i = 0; i <= col; 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 ", arr[i][j]);}printf("\n");}
}void SetMine(char mine[ROWS][COLS], int row, int col)
{int count = EASY_COUNT;while (count){int x = rand() % row + 1;int y = rand() % col + 1;if (mine[x][y]=='0'){mine[x][y] = '1';count--;}}
}int FindMineCount(char mine[ROWS][COLS], int x, int y)
{int count = 0;for (int i = x - 1;i <= x + 1; i++){for (int j = y - 1; j <= y + 1; j++){count += (mine[i][j] - '0');//(易错点)}}return count;
}void FindMine(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){//判断是否已经排查过了if (show[x][y] == '*'){if (mine[x][y] == '1'){printf("很遗憾,你被炸死了!\n");DisplayBoard(mine, ROW, COL);break;}else{//不是雷,就要统计周围的雷的个数int count = FindMineCount(mine, x, y);show[x][y] = count + '0';  //(易错点)DisplayBoard(show, ROW, COL);win++;}}else{printf("该坐标已经被排查,请重新输入。\n");}}else{printf("坐标非法,请重新输入。\n");}}if (win == row * col - EASY_COUNT) //(易错点){printf("恭喜你,扫雷成功!\n");DisplayBoard(mine, ROW, COL);}
}

test.c

#define _CRT_SECURE_NO_WARNINGS #include "game.h"void menu()
{printf("******************\n");printf("*****  1.play ****\n");printf("*****  0.exit ****\n");printf("******************\n");
}void game()
{//建立棋盘//布置雷的信息的棋盘char mine[ROWS][COLS] = { 0 };//显示雷的个数的棋盘char show[ROWS][COLS] = { 0 };//初始化棋盘//mine棋盘初始化为‘0’InitBoard(mine, ROWS, COLS,'0');//show棋盘初始化为‘*’InitBoard(show, ROWS, COLS,'*');//布置雷SetMine(mine, ROW, COL);//DisplayBoard(mine, ROW, COL);//打印棋盘DisplayBoard(show, ROW, COL);//排查雷FindMine(mine, show, ROW, COL);}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;default:printf("选择错误,请重新选择。\n");break;}} while (input);
}int main()
{test();return 0;
}

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

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

相关文章

经典数组和指针笔试题解析——C语言

【本节内容】 1. 数组和指针笔试题解析 2. 指针运算笔试题解析 1. 数组和指针笔试题解析 1.1 一维数组 #include <stdio.h> int main() {int a[] { 1,2,3,4 };printf("%zd\n", sizeof(a));printf("%zd\n", sizeof(a 0));printf("%zd\n&qu…

自动从Android上拉取指定文件

需求场景 利用Mac中的脚本编辑器实现从连接的Android设备中获取指定的文件。 环境 macOS Monterey 版本 12.7.1脚本编辑器adb环境&#xff08;如果没有的话&#xff0c;可以网上搜下Mac配置adb&#xff09; 实现方案 1、打开脚本编辑器&#xff1b; 2、新建一个脚本文件&…

【string一些函数用法的补充】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 string类对象的修改操作 我们来看 c_str 返回c格式的字符串的操作&#xff1a; 我们来看 rfind 和 substr 的操作&#xff1a; string类非成员函数 我们来看 r…

如果利用AOP/Aspect来修改方法的入参

问题描述&#xff1a; 最近项目代码过三方测试&#xff08;国企项目&#xff09;&#xff0c;在一系列代码扫描审计检查下&#xff0c;代码发现一部分修改&#xff0c;例如请求参数发生了编码/加密&#xff0c;导致后台需要对请求的参数进行解码/解密&#xff0c;后端那么接口&…

Material UI 5 学习03-Text Field文本输入框

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 Text Field文本输入框 一、最基本的本文输入框1、基础示例2、一些表单属性3、验证 二、多行文本 一、最基本的本文输入框 1、基础示例 import {Box, TextField} from "…

【嵌入式】字体极限瘦身术:Fontmin在嵌入式UI中的魔法应用(附3500常用汉字)

&#x1f9d1; 作者简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方…

C++类和对象一

#include <iostream> using namespace std;//设计一个学生类 class CStudent {public: //公有成员void InputData(){cout << "请输入学号";cin >> sno;cout << "请输入姓名";cin >> sname;cout << "请输入分…

Go——数组

Golang Array和以往认知的数组有很大的。 数组是同一种数据类型的固定长度的序列。数组定义&#xff1a;var a[len] int&#xff0c;比如&#xff1a;var a [5]int&#xff0c;数组长度必须是常量&#xff0c;且类型的组成部分。一旦定义&#xff0c;长度不能变。长度是数组类…

微服务之商城系统

文章目录 一、商城系统建立之前的一些配置1、nacos2、Mysql3、consul【暂时不使用consul注册服务】这个可以跳过4、redis 二、grpc环境搭建三、微服务架构使用的protobuf1、查看proto的版本号2、安装protoc-gen-go和protoc-gen-go-grpc3、生成protobuff以及grpc的文件 一、商城…

定档!首届百度智能云全球生态大会,4月9日成都见!

为了加快人工智能的发展步伐&#xff0c;进一步推动大模型产业的实际落地&#xff0c;促进AI原生应用的全面繁荣&#xff0c;百度智能云将于2024年4月9日在成都举办首届“百度智能云GENERATE全球生态大会”。 大会将带来百度智能云在大模型时代的全新生态战略&#xff0c;以及针…

使用 Docker 部署 Next Terminal 轻量级堡垒机

1&#xff09;Next Terminal 介绍 官网&#xff1a;https://next-terminal.typesafe.cn/ GitHub&#xff1a;https://github.com/dushixiang/next-terminal 想必经常玩服务器的都了解过 堡垒机&#xff0c;类似于跳板机&#xff0c;但与跳板机的侧重点不同。堡垒机的主要功能是…

【SSM】任务列表案例 基本CRUD SSM整合

文章目录 一、案例功能预览二、接口分析三、前端工程导入四、后端程序实现和测试4.1 准备4.2 功能实现4.2.1 分页查询显示4.2.2 添加计划4.2.2 删除计划4.2.3 修改计划 4.3 前后联调 一、案例功能预览 Github 地址 &#xff1a; ssm-integration-part 二、接口分析 学习计划…

Python 合并两张图片

发现一个很有意思的图片处理包PIL&#xff0c;可以将两张图片合并成一张&#xff0c;而且很好看。代码如下 from PIL import Image# 打开两张图片 image1 Image.open("1.jpg").convert("RGBA") image2 Image.open("2.jpg").convert("RGB…

【数据结构与算法】:插入排序与希尔排序

&#x1f525;个人主页&#xff1a; Quitecoder &#x1f525;专栏: 数据结构与算法 欢迎大家来到初阶数据结构的最后一小节&#xff1a;排序 目录 1.排序的基本概念与分类1.1什么是排序的稳定性&#xff1f;1.2内排序与外排序内排序外排序 2.插入排序2.1实现插入排序2.3稳定性…

C#操作像素替换图片中的指定颜色

待处理的图片&#xff0c;其特征是包含有限数量颜色&#xff0c;不同的颜色相互交叉使用&#xff0c;相同颜色并未完全连贯&#xff0c;需要将图片中的指定颜色替换为另一颜色。虽然很多图片处理工具都支持类似操作&#xff0c;最后还是自己动手编写简单的处理程序。   程序的…

grafana table合并查询

注&#xff1a;本文基于Grafana v9.2.8编写 1 问题 默认情况下table展示的是一个查询返回的多个field&#xff0c;但是我想要的数据在不同的metric上&#xff0c;比如我需要显示某个pod的读写IO&#xff0c;但是读和写这两个指标存在于两个不同的metirc&#xff0c;需要分别查…

Kotlin/Java中String的equals和==

Kotlin/Java中String的equals和 在Java中&#xff0c;如果定义一个常量String和new出一个String对象&#xff0c;是不同的&#xff1a; String s1 "zhang" String s2 new String("zhang") 因为在Java看来&#xff0c;s1只是一个常量&#xff0c;会放在…

ruoyi-vue插件集成websocket

链接&#xff1a;插件集成 | RuoYi WebSocketServer.java&#xff1a;补充代码 /*** 此为广播消息* param message 消息内容*/public void sendAllMessage(String message) {LOGGER.info("【websocket.sendAllMessage】广播消息:"message);try {for(String sessionI…

爬虫案例1

通过get请求直接获取电影信息 目标页面: https://spa6.scrape.center/在network中可以看到是通过Ajax发送的请求&#xff0c;这个请求在postman中也可以直接请求成功&#xff0c;这只是一个用来练习爬虫的&#xff0c;没有达到js逆向的过程&#xff0c;需要通过分析js 代码来获…

GPT出现Too many requests in 1 hour. Try again later.

换节点 这个就不用多说了&#xff0c;你都可以上GPT帐号了&#xff0c;哈…… 清除cooki 然后退出账号&#xff0c;重新登录即可