maze C++

[C++]慕课网课后题迷宫游戏Maze 一、 前言 慕课网的免费C++课已经看到封装篇,接下来看模板篇。然后就是数据结构。目标是刷完bobo老师的算法与数据结构课程。 这次的课后题是迷宫游戏。全部完成需要涉及二维数组,对象指针,函数递归等基础知识。最终代码量160行,完全自己编写。 课后题连接:https://www.imooc.com/video/8207 二、代码逻辑介绍 代码说明:参考网上现有代码逻辑。代码完全是自己独立思考后,编码调试完成。核心是遍历,重点是如何遍历。 无所谓左右手,只是顺时针转向和逆时针转向的问题。本质上都是遍历。 迷宫 阅读详情

This week, you will write a program that generates random mazes and finds a path in there from a beginning to an end position, and then prints the maze on the screen. To give you an idea, this is how the output of your program is supposed to look like:

./mazegen 5 6
±–±–±–±–±–±–+
| . . . | |
±–±–+ ±–±–+ +
| | . . . | |

±–±–±–+ + +
| | . | |

±–±–+ + + +
| | | | . | |

±–+ + +
| | . . |
±–±–±–±–±–±–+
Your program should perform the following major steps:

Read from the program’s command line parameters either 2 or 3 integer values. The first one is the number of rows of the maze, the second one is the number of columns. The third parameter is optional. (But you must implement handling it.) If present, the third parameter must be used as seed value for the random generator. (So you can decide to always generate the same maze for testing purposes.) When called with two parameters only, the program must generate a different maze, each time it is run. Hint: you can convert a string from argv[] to an int using std::stoi.
Generate a random maze of the given size, using the algorithm called Recursive backtracker (see below). The core of this assignment is using classes in a meaningful way. Before you start implementing, first decide what are the “things” in your program, and create classes for them. (Example things are the maze, coordinates, cells in the maze, or even the command line parameters.) Your program must implement at least two classes. But more are likely helpful for achieving good structure.
Find a path inside your random maze, from the top-left corner – we refer to as position (0,0) --, to the bottom right corner. For details, see below.
Print your maze with the path to cout. (Details, see below)

Maze generation

The maze consists of walls and cells. The maze must be closed, so there must be no openings in the outer walls. Initially, all cells are separated from each other by walls. Inside the maze, some walls must be removed to connect the cells to each other. All cells must be connected to each other; from any cell it must be possible to reach any other cell by following paths that have been created by removing some of the internal walls. Cycles inside the maze are forbidden. So, the number of removed walls must be equal to the number of cells, minus 1. Fortunately, there is an algorithm, called Recursive backtracker, that does this for us. You can watch this video with a very nice explanation. You only need the first 8 minutes where he explains the algorithm. Please do not get carried away with the code he describes. While I love his explanation of the algorithm, his code is using his own graphics library and too many C++ features that are as debatable as advanced. (And if you take “too much inspiration” from his code, you will get in trouble anyways…) Not needed, but a nice read is the description of maze generation on wikipedia.

Path finding

Once you have generated your maze (and stored inside a beautiful, class-based data structure), it is time to find a path through your maze. By convention, the path must always start in the top left corner, and must end in the bottom right corner. The finally identified path must not include any detours. For path finding, not having cycles in the maze makes our lives much easier!

Path finding can be done by a (recursive) technique called backtracking. But all you need is implement the following pseudo code, using your own class data structures:

Function findPath, given a maze M, and two coordinates, from and to, returns true if a path could be found, false otherwise:

M.at(from).visited <- true
if from equals to, return true
neighbours <- list of all direct neighbours of from that can be reached (that are not blocked by walls)
for all n in neighbours:
if M.at(n).visited == false
if findPath(n,to) == true, return true
M.at(from).visited <- false
return false

Maze printing

Maze printing must be done very precisely, according to this description. Otherwise, the automated tests will fail. This means, no other characters, no extra characters, no extra spaces or newlines. Let’s consider the following 2-by-2 example maze:

±–±–+
| . . |
±–+ +
| . |
±–±–+
Each cell is 5 characters wide and 3 characters high. Walls and corners are shared among neighbouring cells. Each corner is denoted as +. A horizontal wall is denoted as 3 minus signs: — A vertical wall is denoted by |

The contents of a cell are either three spaces: ’ ’ ,

or two spaces with a . in the middle: ’ . ’ ,

the latter if the cell is part of the path from the top left corner to the bottom right corner.

Topics to exercise

classes and their interfaces
recursion, command line parameters

To use and not to use

Your program should:
use well-designed classes (at least two)

use exceptions for indicating error conditions

implement all functionality in the member functions of the classes; no other functions outside the classes

use main() as a minimalistic driver for the classes(plus error handling)

implement the recursive backtracker algorithm as outlined above (mandatory) implementing the recursive pseudocode shown above for finding the path is highly recommended

Using the following C++ features is not allowed

arrays (except argv[l)
structs
pointers
iterators
auto


#include <iostream>
#include <vector>
#include <random>
#include <ctime>
#include <string>
#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3

class Direction {
public:
    int x;
    int y;
    int dir;
    Direction(int dir) : dir(dir) {
        if (dir == 0) { // UP
            x = 0;
            y = -1;
        }
        else if (dir == 1) { // DOWN
            x = 0;
            y = 1;
        }
        else if (dir == 2) { // LEFT
            x = -1;
            y = 0;
        }
        else if (dir == 3) { // RIGHT
            x = 1;
            y = 0;
        }
    }
};


class MazeCell {
public:
    bool visited;
    bool path;
    Direction direction; // Direction for the cell
    MazeCell() : visited(false), path(false), direction(0) {} // Initialize with direction 0 (UP)
};

class Maze {
public:
    Maze(int rows, int cols, unsigned int seed = 0)
        : rows(rows), cols(cols), maze(rows, std::vector<MazeCell>(cols)) {
        if (seed == 0) {
            std::random_device rd;
            rng.seed(rd());
        }
        else {
            rng.seed(seed);
        }
    }

    void generateMaze() {
        generateMazeRecursive(0, 0);
    }

    void generateMazeRecursive(int x, int y) {
        maze[x][y].visited = true;

        std::vector<int> directions = { 0, 1, 2, 3 };
        std::shuffle(directions.begin(), directions.end(), rng);

        for (int dir : directions) {
            Direction direction(dir);
            int newX = x + direction.x;
            int newY = y + direction.y;

            if (isValid(newX, newY) && !maze[newX][newY].visited) {
                maze[x][y].direction = direction;
                generateMazeRecursive(newX, newY);
            }
        }
    }

    bool findPath() {
        return findPathRecursive(0, 0, rows - 1, cols - 1);
    }

    bool findPathRecursive(int x, int y, int targetX, int targetY) {
        maze[x][y].visited = true;

        if (x == targetX && y == targetY) {
            return true;
        }

        int dx[] = { 1, -1, 0, 0 };
        int dy[] = { 0, 0, 1, -1 };

        for (int dir = 0; dir < 4; ++dir) {
            int newX = x + dx[dir];
            int newY = y + dy[dir];

            if (isValid(newX, newY) && !maze[newX][newY].visited && maze[newX][newY].path) {
                if (findPathRecursive(newX, newY, targetX, targetY)) {
                    return true;
                }
            }
        }

        return false;
    }

    void printMaze() {
        // Define wall characters and path characters
        char horizontalWall = '-';
        char verticalWall = '|';
        char corner = '+';
        char space = ' ';
        char pathCharacter = '.';

        for (int i = 0; i < rows; ++i) {
            // Print the top row of each cell
            for (int j = 0; j < cols; ++j) {
                std::cout << corner;
                if (maze[i][j].direction.dir == UP || i == 0) {
                    for (int k = 0; k < 3; ++k) {
                        std::cout << horizontalWall;
                    }
                }
                else {
                    for (int k = 0; k < 3; ++k) {
                        std::cout << space;
                    }
                }
            }
            std::cout << corner << "\n";

            // Print the middle row of each cell
            for (int j = 0; j < cols; ++j) {
                if (maze[i][j].direction.dir == LEFT || j == 0) {
                    std::cout << verticalWall << space;
                }
                else {
                    std::cout << space << space;
                }

                if (maze[i][j].path) {
                    std::cout << pathCharacter << space;
                }
                else {
                    std::cout << space << space;
                }
            }
            std::cout << verticalWall << "\n";
        }

        // Print the bottom row of the last row of cells
        for (int j = 0; j < cols; ++j) {
            std::cout << corner;
            if (maze[rows - 1][j].direction.dir == DOWN) {
                for (int k = 0; k < 3; ++k) {
                    std::cout << horizontalWall;
                }
            }
            else {
                for (int k = 0; k < 3; ++k) {
                    std::cout << space;
                }
            }
        }
        std::cout << corner << "\n";
    }



private:
    int rows, cols;
    std::vector<std::vector<MazeCell>> maze;
    std::mt19937 rng;

    bool isValid(int x, int y) const {
        return x >= 0 && x < rows && y >= 0 && y < cols;
    }
};

class CommandLineParser {
public:
    CommandLineParser(int argc, char* argv[]) {
        if (argc != 3 && argc != 4) {
            throw std::invalid_argument("Usage: ./mazegen <rows> <cols> [seed]");
        }

        rows = std::stoi(argv[1]);
        cols = std::stoi(argv[2]);
        seed = (argc == 4) ? std::stoi(argv[3]) : 0;
    }

    int getRows() const { return rows; }
    int getCols() const { return cols; }
    unsigned int getSeed() const { return seed; }

private:
    int rows, cols;
    unsigned int seed;
};

int main(int argc, char* argv[]) {
    try {
        CommandLineParser parser(argc, argv);
        int rows = parser.getRows();
        int cols = parser.getCols();
        unsigned int seed = parser.getSeed();

        Maze maze(rows, cols, seed);
        maze.generateMaze();
        maze.findPath();
        maze.printMaze();
    }
    catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}

C/C++ rat maze老鼠迷宫算法详解及源码 Rat Maze算法的优点是可以找到从起点到终点的所有可能路径,并且它是一个完整的搜索算法。它可以解决任意大小的迷宫问题。算法的基本思想是使用递归回溯来探索迷宫中的所有路径,直到找到从起点到终点的路径或者所有可能的路径都被探索完。Rat Maze(老鼠迷宫)算法是一种解决迷宫问题的搜索算法。它模拟了一只老鼠在一个迷宫中寻找出口的过程。Rat Maze算法的缺点是由于使用了递归回溯,当迷宫比较大或者存在很多可能路径时,算法的执行时间会较长。 阅读详情

相关推荐

C++rat maze老鼠迷宫算法(附完整源码)

rat maze老鼠迷宫的算法rat maze老鼠迷宫的算法的完整源码(定义,实现,main函数测试) rat maze老鼠迷宫的算法的完整源码(定义,实现,main函数测试) #include <array> #include <iostream> #include <cassert> /** * @namespace backtracking * @brief Backtracking algorithms */ namespace backtracking

希望我的博客,能帮上你解决学习中工作中所遇到的问题 1174

maze走迷宫-C++

迷宫程序实际上是图的遍历的应用,只是在本例中迷宫的每个入口都是只有4个方向(上下左右),而在图中每个顶点可以有任意个邻接顶点,邻接顶点之间也可以有回环。在遍历时可以使用递归调用(占用系统栈空间),也可以在遍历过程中把信息存入自己建立的容器(栈适合于深度优先遍历, 后进先出的特点);从一个顶点v到他的未访问的邻接顶点有多个路径,既然深入下去一条,就需要记住其他几条路径(也就是v的其他未访问的邻接顶点...

C++ 1786

迷宫(MAZE)c语言+源码

一款简单的c语言迷宫,内含源码 有两种地图生成,一种自定义,一种DFS生成。 ×××××××××××××云海俊采×××××××××××××××

穿越迷宫c语言程序设计教程课后答案,请大虾们帮忙把这个迷宫的C++代码改为C语言...

该楼层疑似违规已被系统折叠隐藏此楼查看此楼这个程序代码分了三个文件,我想把它揉合为一个C语言文件可是面向对象类不知道怎么改成C语言//maze.h文件//Maze类的声明#ifndefMAZE_H_#defineMAZE_H_#include#include#includeusingnamespacestd;classMaze{public:Maze();...

weixin_33978451的博客 225

maze系统源代码

用C++编的一个maze系统,可以实现自动路径搜索,自动攻击等功能。

MAZE GAME(C++)

一個MAZE的C++ GAME #include 果到入唔同map去TEST佢

C++ 数据结构算法 学习笔记(18) - 栈的企业级应用案例(2)

找迷宫通路需要使用回溯法,找迷宫通路是对回溯法的一个很好的应用,实现回溯的过程用到数据结构—!:对一个包括有很多个结点,每个结点有若干个搜索分支的问题,把原问题分解为若干个子问题求解的 算法;当搜索到某个结点发现无法再继续搜索下去时,就让搜索过程回溯(回退)到该节点的前一个结点,继续 搜索该节点外的其他尚未搜索的分支;如果发现该结点无法再搜索下去,就让搜索过程回溯到这个结点的前一 结点继续这样的搜索过程;这样的搜索过程一直进行到搜索到问题的解或者搜索完了全部可搜索分支没有解存 在为止。

Choon Seng 的博客 323

maze程序c++

迷宫;慕课网;c++;中文资源; 包含源文件和头文件;

利用C++面向对象OOP思想实现迷宫maze的路径寻找问题(详解加代码)

问题题目: 用OOP完成迷宫路径的寻找问题 软件运行要求如下: 请输入迷宫的行列数: 5 5 请输入迷宫路径节点信息(1表示不能走,0表示能走) 开始寻找迷宫路径(从左上角到右下角的一个可通行的路径): 迷宫存在可通行的路径: 程序所包含的头文件和如下 #include "targetver.h" #include<iostream> #include<string.h&gt...

Lebron 2432

RK3566基于Buildroot定制QT开发环境的完整指南

本文详细介绍了如何在RK3566开发板上使用Buildroot定制QT开发环境的完整流程。从基础环境搭建、Buildroot初始配置到QT模块选择与编译验证,提供了实战经验和常见问题解决方案,帮助开发者高效完成嵌入式Linux下的QT开发环境部署。

weixin_26804345的博客 358

离线迁移 Conda 环境到 Windows 服务器:用 conda-pack 摆脱硬路径限制

在进行深度学习算法的环境部署时,由于生产服务器被彻底隔离外网,只能把conda中env文件夹中的虚拟环境文件夹从开发机直接拷到Windows 服务器,但在运行labelimg等工具时可能报错,因此用conda-pack来解决。

weixin_44115575的博客 1427

maze 搜索路径 c++

第二周作业 maze 题目: 东东有一张地图,想通过地图找到妹纸。地图显示,0表示可以走,1表示不可以走,左上角是入口,右下角是妹纸,这两个位置保证为0。既然已经知道了地图,那么东东找到妹纸就不难了,请你编一个程序,写出东东找到妹纸的最短路线。 输入: 输入是一个5 × 5的二维数组,仅由0、1两数字组成,表示法阵地图。 输出: 输出若干行,表示从左上角到右下角的最短路径依次经过的坐标,格式如样例...

qq_45639151的博客 366

SAP-HR 模块 PPOSE 的详细信息标签页增强

步骤1:T-CODE : SE11 创建一个名为 HRI9106 的结构 命名:HRI + 91 + 两位数字。人事管理 - 组织管理 - 集成新信息类型 - 将信息类型添加为明细范围中的标签页。步骤6:SE51 查看 7000屏幕,修改屏幕属性 让其更美观。步骤3:T-CODE : SM30维护 T777I 表。步骤5:PPCI 新建 7000屏幕用于显示。标签页 IT 开头 + 信息类型 9106。步骤2:T-CODE : PPCI。步骤4:T-CODE : SPRO。

常回来看看呀!! 1628

Sound Maze - 基于 SFML+C++14 的音效迷宫开源游戏 | MIT 协议

本项目是我在学习图形渲染、音频交互与跨设备适配过程中开发的轻量级游戏。核心设计理念是结合视觉迷宫与音效反馈,为玩家提供沉浸式体验;同时,项目针对老旧安卓设备(如红米 S2、荣耀 9A)的 x86/ARM 架构进行了性能优化测试,验证 SFML 游戏在低配置设备上的运行可行性,最初仅作为学习项目,目前已完成核心功能并开源。

2401_89682176的博客 759

【碳排放数据集】全球近实时网格化二氧化碳排放数据集GRACED

【碳排放数据集】全球近实时网格化二氧化碳排放数据集GRACED

WW、forever的博客 146

基于YOLOv8n的FPGA无PS端PL部署完整实现方案

本文提出了一种将YOLOv8n目标检测模型完整部署到FPGA纯PL端的实现方案。通过PyTorch训练和INT8量化技术,结合Vitis AI工具链,将模型转换为适合FPGA实现的硬件描述。方案详细阐述了从模型训练、量化校准到FPGA硬件设计的全流程,重点解决了无PS端部署的架构设计、资源优化和实时性保障等关键技术挑战。实验结果表明,该方案在Xilinx Virtex-690T FPGA上实现了30FPS以上的实时目标检测性能,为边缘计算场景提供了高效的硬件加速解决方案。

huanghm88的专栏 507

arduino开发过程中编译问题undefined reference to `setup'的解决办法

今天遇到这个问题,搜了很久也没有找到真正的答案。后来灵光乍现,原来是出现了相同的目标文件,既有maze.h和maze.cpp,又有maze.ino,于是编译连接的时候就会出现ld错误了。将maze.ino重命名为任意不重复的名字,重新编译,问题解决!yeah! 转载于:https://blog.51cto.com/346454/1719767...

weixin_34051201的博客 4148

OpenClaw赚钱实录:从“养龙虾“到可持续变现的实践指南——OpenClaw的赚钱底层逻辑与“记忆”革命

AI 的商业价值不在于替代思考,而在于沉淀关系。当 Agent 记住你的偏好、你的历史、你的目标,它就不再是冷冰冰的软件,而是成为数字化的关系资产。这种资产的稀缺性不在于技术复杂度,而在于时间无法被压缩——你无法用更好的算法替代 3 个月的协作记忆。在这场“记忆革命”中,护城河不是模型参数,而是用户与 AI 共同书写的历史。OpenClaw 用一套优雅的文件系统架构,将这种历史转化为可积累、可复用、可变现的数字资产。从“计算即服务”(CaaS)到“记忆即服务”(MaaS)。

冯·诺依曼 1341

有没有哪位来帮我看看,我的游戏为什么不能运行

cout

快乐星空Maker的博客 190

VS2019项目使用CGAL6.1配置教程详细步骤

在VS2019项目中使用CGAL详细步骤

插件开发 331

在 SAP 系统中设置成本中心(Cost Center)和利润中心(Profit Center)需在管理会计(CO)模块中完成,涉及主数据创建、组织结构配置等步骤

本文详细介绍了SAP系统中成本中心和利润中心的设置流程。成本中心设置包括:配置成本控制范围、定义标准层次结构、创建主数据(KS01/KS02/KS03)等步骤。利润中心设置需先激活利润中心会计功能,再定义标准层次并创建主数据(KE01/KE02/KE03)。关键是将成本中心与利润中心关联,实现成本数据自动流向利润中心。最后可通过相关报表验证设置是否生效。整个流程强调主数据创建和组织结构关联,以实现成本归集和利润分析功能。

金牌架构师 2222

超经典C++益智游戏Number Maze

超经典C++益智游戏Number Maze

yaosichengalpha的博客 702

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Windows-appsample-marble-maze 项目教程

Windows-appsample-marble-maze 项目教程 1. 项目的目录结构及介绍 Windows-appsample-marble-maze/ ├── Assets/ │ ├── ... (各种资源文件,如图片、音频等) ├── Common/ │ ├── ... (通用代码文件) ├── DirectX/ │ ├── ... (DirectX相关代码文件) ├── M...

gitblog_00566的博客 620

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Simulated maze模拟迷宫(C++实现)

假设有一个迷宫,用Maze(1...M,1...N)表示迷宫,数组元素为1表示死路,为0表示通路,Maze(x1,y1)为迷宫的入口,Maze(x2,y2)为迷宫的出口。试设计一个算法求出一个可能的出口。 深度优先遍历,对每条可能的路径进行一一判断,若为可能的路径则将当前路径节点加入路径栈,若走到死胡同,则回溯至上一个路口在进行判断。 #include<stack> #include<iostream> #define ROW 6 #define COL 6 using nam

m0_62466789的博客 993

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

[USACO11OPEN] Corn Maze S C++

本题使用BFS进行搜索,不对BFS进行具体讲解。

LJC345924084的博客 451

打卡信奥刷题(2866)用C++信奥 P4651 [BalticOI 2005] Maze (Day1)

题目摘要:在平行四边形迷宫中寻找最短路径。给定平行四边形的长和高(1-500),以及入口、出口坐标。每条边有黑、白或无色的标记。要求找到一条路径,使得走过的边颜色交替(黑白相间)且路径最短。输入包含边长、坐标和颜色矩阵,输出最短路径长度。示例展示了路径需交替颜色行走的情况。解决方案使用C++实现,通过图的遍历(类似BFS)处理颜色交替约束,记录两种颜色状态的最短距离。

Loge谈信奥--一个专注于信奥人的博客 720
上一篇: MSBA7001 Assignment 1
下一篇: comp2123 Assignment 5
todcode
博客等级 码龄7年 359粉丝 108原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值