C++迷宫游戏详解
个人主页:[PingdiGuo_guo]
收录专栏:[C++干货专栏]
大家好呀,我是PingdiGuo_guo,今天我们来学习用C++实现一个迷宫游戏。
目录
1.迷宫的具体步骤
1.1.迷宫的初始化
1.2.寻路算法
1.DFS算法
2.BFS算法
1.3.移动
2.总结
C++迷宫游戏的实现需要考虑迷宫的表示方式、寻路算法以及代码实现。在本篇博客中,我们将逐步实现一个C++迷宫游戏。
1.迷宫的具体步骤
1.迷宫的初始化:包括选择难度,随机生成迷宫,以及玩家移动后的迷宫
2.寻路算法:在迷宫中,我们需要一个正确的算法来判断当前路径是否正确
3.移动:玩家可以按w,a,s,d键来实现移动
1.1.迷宫的初始化
迷宫的初始化具体实现步骤如下:
1. 包含所需的头文件 <bits/stdc++.h>。
2. 使用命名空间 std。
3. 声明迷宫的相关常量,如空格、墙、路径、起点和终点的字符。
4. 声明随机数生成器 gen。
5. 声明迷宫的宽度和高度变量。
6. 声明迷宫的二维字符向量 cells。
7. 声明起点和终点的位置变量。
8. 实现函数 generateMaze() 用于生成随机迷宫。
- 使用随机数生成器生成起点和终点的随机位置。
- 遍历迷宫的每个位置,根据一定的概率生成墙或路径,并将起点和终点的字符设置为对应的字符。
9. 实现函数 printMaze() 用于打印迷宫。
- 遍历迷宫的每个位置,打印对应的字符。
10. 在 main() 函数中:
- 提示用户输入迷宫的宽度和高度。
- 调整 cells 的大小为指定的宽度和高度,并初始化为空格字符。
- 生成随机迷宫。
- 打印迷宫。
11. 返回 0,表示程序成功执行完毕。
以下是具体的代码实现:
#include <bits/stdc++.h>using namespace std;// Maze cell types
const char EMPTY = ' ';
const char WALL = '#';
const char PATH = '.';
const char START = 'S';
const char MEND = 'G';// Random number generator
random_device rd;
mt19937 gen(rd());// Maze dimensions
int width, height;// Maze grid
vector<vector<char>> cells;// Start and end positions
pair<int, int> start, mend;// Generate random maze
void generateMaze() {// Set start and end points randomlyuniform_int_distribution<> dis(0, width - 1);start = make_pair(dis(gen), dis(gen));mend = make_pair(dis(gen), dis(gen));// Generate empty cells with 40% wallsuniform_real_distribution<double> prob(0.0, 1.0);for (int i = 0; i < width; i++) {for (int j = 0; j < height; j++) {if (make_pair(i, j) == start) {cells[i][j] = START;} else if (make_pair(i, j) == mend) {cells[i][j] = MEND;} else {if (prob(gen) <= 0.4) {cells[i][j] = WALL;} else {cells[i][j] = PATH;}}}}
}// Print maze
void printMaze() {for (int i = 0; i < width; i++) {for (int j = 0; j < height; j++) {cout << cells[i][j] << " ";}cout << endl;}
}int main() {// Set maze dimensionscout << "宽度: ";cin >> width;cout << "高度: ";cin >> height;// Initialize maze cells with empty spacescells.resize(width, vector<char>(height, EMPTY));// Generate random mazegenerateMaze();// Print mazeprintMaze();return 0;
}
1.2.寻路算法
接下来,我们需要选择一个最优的寻路算法。在迷宫游戏中,常用的寻路算法有深度优先搜索(DFS)和广度优先搜索(BFS)。这两种算法都可以用于寻找迷宫的路径,但适用的场景和复杂度略有不同。
1.DFS算法
DFS算法通过递归的方式进行搜索,每次都先选择一个方向前进,直到无法前进为止,然后回溯到上一个节点继续搜索。DFS算法的复杂度为O(V + E),其中V是节点的数量,E是边的数量。我们可以分析出具体步骤:
1. 定义一个名为DFS的函数,接收当前位置的坐标x和y作为参数,并返回一个布尔值。
2. 首先,判断当前位置是否超出了迷宫的边界,如果是,则返回false。
3. 接着,判断当前位置是否为墙壁(用'#'表示),如果是,则返回false。
4. 然后,判断当前位置是否为终点(用'G'表示),如果是,则返回true,表示已经找到了一条通路。
5. 如果以上条件都不满足,说明当前位置是可走的空地(用'.'表示),将当前位置标记为已访问(用'#'代替原来的空地)。
6. 通过递归调用DFS函数,按照上、下、左、右的顺序尝试前进,即DFS(x + 1, y)、DFS(x - 1, y)、DFS(x, y + 1)、DFS(x, y - 1)。
7. 如果在某个方向上的递归调用返回true,表示找到了通路,则返回true。
8. 如果以上递归调用都没有找到通路,则说明当前位置不是通路,将当前位置标记为未访问(用' '代替原来的'#'),进行回溯。
9. 最后,返回false,表示没有找到通路。
通过以上步骤,使用DFS算法可以在迷宫中寻找通路。
以下是具体的代码实现:
bool DFS(int x, int y) {if (x < 0 || x >= N || y < 0 || y >= N) {return false;}if (maze[x][y] == '#') {return false;}if (maze[x][y] == 'G') {return true;}maze[x][y] = '#'; // 标记为已访问if (DFS(x + 1, y) || DFS(x - 1, y) || DFS(x, y + 1) || DFS(x, y - 1)) {return true;}maze[x][y] = '.'; // 回溯,标记为未访问return false;
}
2.BFS算法
BFS算法使用队列来存储待访问的节点,每次都从队列中取出一个节点进行访问,并将其周围的节点加入队列。BFS算法的复杂度为O(V + E),其中V是节点的数量,E是边的数量。我们可以分析出以下步骤:
1. 定义一个名为BFS的函数,接收起始位置的坐标x和y作为参数,并返回一个布尔值。
2. 创建一个队列(queue),并将起始位置加入队列中。
3. 使用while循环,当队列不为空时执行循环。
4. 在循环中,首先从队列中取出队首元素,即当前位置的坐标。
5. 接着,判断当前位置是否超出了迷宫的边界,如果是,则继续下一次循环。
6. 然后,判断当前位置是否为墙壁(用'#'表示),如果是,则继续下一次循环。
7. 接着,判断当前位置是否为终点(用'G'表示),如果是,则返回true,表示已经找到了一条通路。
8. 若以上条件都不满足,说明当前位置是可走的空地(用'.'表示),将当前位置标记为已访问(用'#'代替原来的空地)。
9. 将当前位置的上、下、左、右四个方向的相邻坐标加入队列中,即({x + 1, y})、({x - 1, y})、({x, y + 1})、({x, y - 1})。
10. 循环结束后,说明队列已经为空且没有找到通路,返回false。
通过以上步骤,使用BFS算法可以在迷宫中寻找通路。
bool BFS(int x, int y) {queue<pair<int, int>> q;q.push({x, y});while (!q.empty()) {pair<int, int> curr = q.front();q.pop();int x = curr.first;int y = curr.second;if (x < 0 || x >= N || y < 0 || y >= N) {continue;}if (maze[x][y] == '#') {continue;}if (maze[x][y] == 'G') {return true;}maze[x][y] = '#'; // 标记为已访问q.push({x + 1, y});q.push({x - 1, y});q.push({x, y + 1});q.push({x, y - 1});}return false;
}
1.3.移动
在迷宫游戏中,玩家需要根据输入的指令来移动。常见的移动指令有上、下、左、右四个方向。我们可以通过更新玩家的坐标来实现移动。我们可以分析出以下步骤:
1. 定义一个名为movePlayer的函数,接收玩家当前位置的坐标x和y的引用,以及移动的方向direction作为参数,并返回一个布尔值。
2. 根据输入的方向指令,使用条件判断来判断移动的方向。如果是"W"或"w",则判断玩家上方的位置是否为墙壁,如果不是,则更新玩家的坐标x减1;如果是"S"或"s",则判断玩家下方的位置是否为墙壁,如果不是,则更新玩家的坐标x加1;如果是"A"或"a",则判断玩家左边的位置是否为墙壁,如果不是,则更新玩家的坐标y减1;如果是"D"或"d",则判断玩家右边的位置是否为墙壁,如果不是,则更新玩家的坐标y加1。
3. 如果输入的方向指令不是以上四种有效指令,则返回false,表示无效指令。
4. 在玩家移动后,返回true,表示移动成功。
在主函数中,使用DFS算法找到了一条路径后,可以进入游戏循环。循环中,首先打印迷宫,然后提示玩家输入移动指令(W上,S下,A左,D右)或者Q退出。根据玩家输入的指令调用movePlayer函数来移动玩家,并判断是否成功找到出口。如果玩家输入Q,则跳出循环,游戏结束。
通过以上步骤,玩家可以在迷宫中根据输入指令进行移动,并且在找到出口时会进行相应的提示。
具体代码实现:
bool movePlayer(int& x, int& y, char direction) {// 根据指令更新玩家的坐标if (direction == 'W' || direction == 'w') { // 上if (maze[x - 1][y] != '#') {x--;}} else if (direction == 'S' || direction == 's') { // 下if (maze[x + 1][y] != '#') {x++;}} else if (direction == 'A' || direction == 'a') { // 左if (maze[x][y - 1] != '#') {y--;}} else if (direction == 'D' || direction == 'd') { // 右if (maze[x][y + 1] != '#') {y++;}} else {return false; // 无效指令}return true;
}在主函数中,我们可以在寻路算法之后添加以下代码,以实现玩家的移动:
// 使用DFS算法寻找路径
bool found = DFS(startX, startY);
if (found) {cout << "找到了一条路径!" << endl;cout << "请开始游戏!" << endl;char direction;while (true) {printMaze(startX, startY); // 打印迷宫cout << "请输入指令(W上, S下, A左, D右)或者Q退出:" << endl;cin >> direction;if (direction == 'Q' || direction == 'q') {break;}movePlayer(startX, startY, direction); // 移动玩家if (startX == endX && startY == endY) {cout << "恭喜你成功找到出口!" << endl;break;}}
} else {cout << "没有找到路径!" << endl;
}
上述代码通过循环接受玩家的输入指令,并根据指令更新玩家的坐标,实现玩家在迷宫中的移动。当玩家到达终点时,游戏结束。
2.总结
本篇博客讲解了实现迷宫的几个步骤与代码,希望大家有所收获。感谢大家的支持与观看,如果有好的建议欢迎留言!
相关文章:

C++迷宫游戏详解
个人主页:[PingdiGuo_guo] 收录专栏:[C干货专栏] 大家好呀,我是PingdiGuo_guo,今天我们来学习用C实现一个迷宫游戏。 目录 1.迷宫的具体步骤 1.1.迷宫的初始化 1.2.寻路算法 1.DFS算法 2.BFS算法 1.3.移动 2.总结 C迷宫游…...
java下载网络文件
/*** 下载文件** param fileId* param response* throws Exception*/ GetMapping("/downLoadFile") public void downLoadFile(Long fileId, HttpServletResponse response) throws Exception{// 根据文件ID查询文件路径FileDO fileDO fileService.get(fileId);// 定…...

大数据信用报告查询费用一般要多少钱?
一些不少朋友在申贷的时候被拒贷之后,得到的原因就是因为大数据不良被拒,这时候很多人都反过来查询自己的大数据信用报告,而查询的价格也是不少朋友都比较关注的,那大数据信用报告查询费用一般要多少钱呢?下面本文就为你介绍一下…...

【操作宝典】IntelliJ IDEA新建maven项目详细教程
目录 🌼1. 配置maven环境 🌼2. 创建maven项目 🌼3. 创建maven项目完整示例 a. 导入spring boot环境 b. 修改maven配置 c. 下载jar包 d. 创建Java类 🌼1. 配置maven环境 【安装指南】maven下载、安装与配置详细教程-CSDN博客…...

【Java程序设计】【C00196】基于(JavaWeb+SSM)的旅游管理系统(论文+PPT)
基于(JavaWebSSM)的旅游管理系统(论文PPT) 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于ssm的旅游平台 本系统分为前台、管理员2个功能模块。 前台:当游客打开系统的网址后,首先看到的…...

pdmodel从动态模型转成静态onnx
1.下载项目 git clone https://github.com/jiangjiajun/PaddleUtils.git 2.新建两个新的文件夹 第一个文件夹放两个必要文件 第二个文件夹可以设置为空,用来存放转换后的模型 如图: 3.在终端运行 python paddle/paddle_infer_shape.py --model_dir …...

git 如何修改仓库地址
问题背景:组内更换大部门之后,代码仓的地址也迁移了,所以原来的git仓库地址失效了。 虽然重新建一个新的文件夹,再把每个项目都git clone一遍也可以。但是有点繁琐,而且有的项目本地还有已经开发一半的代码,…...

基于springboot篮球论坛系统源码和论文
首先,论文一开始便是清楚的论述了系统的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,更进一步明确系统的需求。然后在明白了系统的需求基础上需要进一步地设计系统,主要包罗软件架构模式、整体功能模块、数据库设计。本项…...

【三维重建】运动恢复结构(SfM)
运动恢复结构是通过三维场景的多张图像,恢复出该场景的三维结构信息以及每张图片对应的摄像机参数。 欧式结构恢复(内参已知,外参未知) 欧式结构恢复问题: 已知:1、n个三维点在m张图像中的对应点的像素坐标 2、相机内参 求解&…...

Android Studio非UI线程修改控件——定时器软件
目录 一、UI界面设计 1、UI样式 2、XML代码 二、功能编写 1、定义 2、实现方法 3、功能实现 一、UI界面设计 1、UI样式 2、XML代码 <?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android…...

canvas的一些基础
在 Canvas 中,基本图形有两种:直线图形和曲线图形 直线图形:直线、矩形(描边矩形和填充矩形)、多边形 曲线图形:曲线和弧线(弧线是圆的一部分,曲线则不一定,弧线上的每个点都具有相同的曲率&…...

C++(10)——类与对象(最终篇)
目录 static成员 概念 特性 友元 友元函数 友元类 内部类 匿名对象 经过这么多天的分享,C的类与对象终于要结束了。结束也意味着C快要入门了。 static成员 概念 声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之…...
NetApp FAS2750 和 FAS2820 简化分布式企业的存储
拥有分布式企业和多个办公位置的客户希望使用这些系统进行虚拟化,以及为大型 FAS 和 AFF 系统提供简单且经济高效的备份和灾难恢复。 NetApp FAS2750 的规格 非常适合需要轻松部署和简化运维的中小型企业。 • 每个 HA 对的最大原始容量:1.2 PB • 每个…...

Geogebra设置函数定义域
曲线方程设置范围 y 4x 0 / (-4 < y < 4) 函数设置范围 函数(e^x*(2x-1),-2.5,3/4)...

代码随想录刷题笔记 DAY 18 | 找树左下角的值 No.513 | 路经总和 No.112 | 从中序与后序遍历序列构造二叉树 No.106
Day 18 01. 找树左下角的值(No. 513) 题目链接 代码随想录题解 1.1 题目 给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: root [2,1,3] 输出: 1 示例 2: 输入…...

【algorithm】一个简单的PID工程 base 用于手生时候快速复习 用于设计模式 cpp语法八股 快速复习校验
写在前面 最近项目一直用matlab,防止手生整一个回忆工具使用的简单的pid demo,走一边流程,包括配工程debug看结果,复用之前记录的配置见我的bloghttps://blog.csdn.net/weixin_46479223/article/details/135082867?csdn_share_t…...

Python处理图片生成天际线(2024.1.29)
1、天际线简介 天际线(SkyLine)顾名思义就是天空与地面的边界线,人站在不同的高度,会看到不同的景色和地平线,天空与地面建筑物分离的标记线,不得不说,每天抬头仰望天空,相信大家都可…...

jsp服装穿搭推荐系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
一、源码特点 JSP 游戏网上商城系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0…...

Opencv(C++)学习 之RV1126平台的OPENCV交叉编译
本文特点:网上已经有了很多opencv移植RV1106的文章,本文主要记录基于cmake-gui编译,碰到的报错,及解决报错问题的方法,同时简单总结一些配置项相关的知识。 一、环境: ubuntu18 x64 RV1126交叉编译工具链 …...
http和https区别
HTTP协议以明文方式发送内容,不提供任何方式的数据加密。HTTP协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。https则是具有安全性的ssl加密传输协议。http和https使用的是完全不同的连接方式,用的端口也不一样&…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...

【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...

MySQL:分区的基本使用
目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区(Partitioning)是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分(分区)可以独立存储、管理和优化,…...