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.总结

本篇博客讲解了实现迷宫的几个步骤与代码,希望大家有所收获。感谢大家的支持与观看,如果有好的建议欢迎留言!

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

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

相关文章

[晓理紫]每日论文分享(有中文摘要,源码或项目地址)--强化学习、模仿学习、机器人

专属领域论文订阅 关注{晓理紫|小李子}&#xff0c;每日更新论文&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持 如果你感觉对你有所帮助&#xff0c;请关注我&#xff0c;每日准时为你推送最新论文。 为了答谢各位网友的支持&#xff0c;从今日起…

SpringCloud-创建多模块项目

在微服务架构中&#xff0c;项目的组织结构对于代码的维护和团队的协作至关重要。Spring Cloud作为一个强大的微服务框架&#xff0c;提供了丰富的功能和组件&#xff0c;同时也支持多模块项目的创建&#xff0c;使得代码结构更加清晰、易于管理。本文将介绍如何使用 Spring Cl…

PiflowX新增Apache Beam引擎支持

参考资料&#xff1a; Apache Beam 架构原理及应用实践-腾讯云开发者社区-腾讯云 (tencent.com) 在之前的文章中有介绍过&#xff0c;PiflowX是支持spark和flink计算引擎&#xff0c;其架构图如下所示&#xff1a; 在piflow高度抽象的流水线组件的支持下&#xff0c;我们可以…

推理系统学习笔记

一些学习资料 最近对MLsys比较感兴趣&#xff0c;遂找些资料开始学习一下 https://fazzie-key.cool/2023/02/21/MLsys/https://qiankunli.github.io/2023/12/16/llm_inference.htmlhttps://dlsyscourse.orghttps://github.com/chenzomi12/DeepLearningSystem/tree/main/04Infe…

【Flink入门修炼】1-2 Mac 搭建 Flink 源码阅读环境

在后面学习 Flink 相关知识时&#xff0c;会深入源码探究其实现机制。因此&#xff0c;需要现在本地配置好源码阅读环境。 本文搭建环境&#xff1a; Mac M1&#xff08;Apple Silicon&#xff09;Java 8IDEAFlink 官方源码 一、 下载 Flink 源码 github 地址&#xff1a;h…

记录一次su 普通用户报错的事件

故障信息&#xff1a; 使用root用户可以登录服务器&#xff0c;但是使用普通用户不能登录。报错截图信息如下&#xff1a; 经仔细排查发现&#xff1a;/bin 的权限发生了更改&#xff0c;更改为555 ls -ld /bin/ 查看权限 再次尝试su 发现成功。

【图像文本化】Base64编解码OpenCV4中 Mat 对象

学习《OpenCV应用开发&#xff1a;入门、进阶与工程化实践》一书 做真正的OpenCV开发者&#xff0c;从入门到入职&#xff0c;一步到位&#xff01; 前言 很多时候在开发中&#xff0c;需要保存图像为文本形式&#xff0c;以便于存储与传输。最常见的就是把图像文件编码为Ba…

五、机器学习模型及其实现1

1_机器学习 1&#xff09;基础要求&#xff1a;所有的数据全部变为了特征&#xff0c;而不是eeg信号了 python基础已经实现了特征提取、特征选择&#xff08;可选&#xff09;进行了数据预处理.预处理指对数据进行清洗、转换等处理&#xff0c;使数据更适合机器学习的工具。S…

thinkphp6入门(19)-- 中间件向控制器传参

可以通过给请求对象赋值的方式传参给控制器&#xff08;或者其它地方&#xff09;&#xff0c;例如 <?phpnamespace app\middleware;class Hello {public function handle($request, \Closure $next){$request->hello ThinkPHP;return $next($request);} } 然后在控制…

ubuntu 上安装和配置Apache2+Subversion

目录 一、安装Apache2和SVN 二、Apache2设置 三、subversion配置 四、创建仓库和设置权限 五、仓库备份和恢复 系统环境 Ubuntu Linux (20.04) apache2 Subversion(1.13.0) 一、安装Apache2和SVN 通过命令在线安装apache2和subversion apt-get install apache2 libap…

06 MP之自动填充+SQL执行的语句和速度分析

1. 自动填充 在项目中有一些属性&#xff0c;比如常见的创建时间和更新时间可以设置为自动填充。 1.1 实例 需求: 将创建时间和更新时间设置为自动填充, 这样每次插入数据时可以不用理会这两个字段 1.1.1 在数据库增加字段 默认开启驼峰映射 createTime --> create_time…

回归预测 | Matlab实现OOA-CNN-LSTM-Attention鱼鹰算法优化卷积长短期记忆网络注意力多变量回归预测(SE注意力机制)

回归预测 | Matlab实现OOA-CNN-LSTM-Attention鱼鹰算法优化卷积长短期记忆网络注意力多变量回归预测&#xff08;SE注意力机制&#xff09; 目录 回归预测 | Matlab实现OOA-CNN-LSTM-Attention鱼鹰算法优化卷积长短期记忆网络注意力多变量回归预测&#xff08;SE注意力机制&…

[NOIP2017 提高组] 宝藏

[NOIP2017 提高组] 宝藏 题目背景 NOIP2017 D2T2 题目描述 参与考古挖掘的小明得到了一份藏宝图&#xff0c;藏宝图上标出了 n n n 个深埋在地下的宝藏屋&#xff0c; 也给出了这 n n n 个宝藏屋之间可供开发的 m m m 条道路和它们的长度。 小明决心亲自前往挖掘所有宝…

JWT令牌 | 一个区别于cookie/session的更安全的校验技术

目录 1、简介 2、组成成分 3、应用场景 4、生成和校验 5、登录下发令牌 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;擅长web应用开发、数据结构和算法&#xff0c;初步涉猎Pyth…

Apache Zeppelin 整合 Spark 和 Hudi

一 环境信息 1.1 组件版本 组件版本Spark3.2.3Hudi0.14.0Zeppelin0.11.0-SNAPSHOT 1.2 环境准备 Zeppelin 整合 Spark 参考&#xff1a;Apache Zeppelin 一文打尽Hudi0.14.0编译参考&#xff1a;Hudi0.14.0 最新编译 二 整合 Spark 和 Hudi 2.1 配置 %spark.confSPARK_H…

re:从0开始的CSS学习之路 3. CSS三大特性

0. 写在前面 很多的学习其实并不知道在学什么&#xff0c;学一个新东西学着学着就变成了抄代码&#xff0c;背概念。把看视频学习变成了一个赶进度的任务&#xff0c;到头来只学到了一些皮毛。 文章目录 0. 写在前面1. CSS三大特性——层叠性2. CSS三大特性——优先级3. CSS三…

记录关于node接收并解析前端上传excel文件formData踩的坑

1.vue2使用插件formidable实现接收文件&#xff0c;首先接口不可以使用任何中间件&#xff0c;否则form.parse()方法不执行。 const express require(express) const multipart require(connect-multiparty); const testController require(../controller/testController)/…

vue2学习笔记(2/2)

vue2学习笔记&#xff08;1/2&#xff09; vue2学习笔记&#xff08;2/2&#xff09; 文章目录 1. 初始化脚手架2. 分析脚手架&render函数文件结构图示及说明main.jsindex.htmlApp.vueSchool.vueStudent.vue 关于不同版本的Vue修改默认配置vue.config.js配置文件 3. ref属…

GPT3.5\GPT4系列计算完整prompt token数的官方方法

前言: ChatGPT如何计算token数&#xff1f;https://wtl4it.blog.csdn.net/article/details/135116493?spm1001.2014.3001.5502https://wtl4it.blog.csdn.net/article/details/135116493?spm1001.2014.3001.5502 GPT3.5\GPT4系列计算完整prompt token数的官方方法&#xff1…

AR特效自研AI算法技术解决方案

在当今这个高速发展的数字化时代&#xff0c;增强现实&#xff08;AR&#xff09;技术已经成为企业创新和市场竞争的重要手段。美摄科技凭借对AI技术的深厚积累&#xff0c;为企业提供了一套创新的AR特效自研AI算法技术解决方案&#xff0c;旨在满足企业在AR领域的多元化需求。…