迷宫求解并输出路径,面向对象实现迷宫求解;C++

本篇文章利用递归解决迷宫求解问题.

一、迷宫求解原理及代码实现

首先迷宫求解问题中我们需要用一个二维数组来创建迷宫地图;该地图需要实现什么地方是空地,什么地方是墙体,然后我们需要创建一个点类,这个点类如何与地图相关联起来呢?我们可以通过创建一个二维数组但是二维数组中全部从放的是点类型的数据

(Point mazeMap[10][10]),这样就能通过坐标将他们关联起来,因为地图是创建在一个二维数组中的,所以他其中的每个元素我们都可以通过他的行数和列数来表示,正好与点的横纵坐标相对于,例如一个点的坐标是(0,9)那么他在地图中所对应的就是第一行第十列这个位置(因为数组是从零开始存储数据的),我们还需要标记一个点是否走过或者没走过,并且还需要判断这个点是墙体还是空地,

1、创建点类,

2、走迷宫的函数

每一步都标有注释,我们制定规则顺时针方向探索前进,在每一个点上,我们先判断右边能不能前进,能前进则前进,不能则看下方能不能前进,如此顺时针依次判断,

该函数需要我们传进两个点一个起点一个终点。

3、封装打印地图的函数,

我这里的地图使用string类型来表示的你也可以使用其他类型比如int ,0表示空地1表示墙体,

4、main函数

5、运行结果如图所示

这里直接从起点下一个点开始打印了,

6、下面是全部代码:

#include<iostream>
using namespace std;
#include<stack>
#define MAXSIZE 10;

string mazeMapValue[10][10] =
{
    {"x","x","x","x","x","x","x","x","x","x"},
    {"0","0","0","x","x","0","x","x","x","x"},
    {"x","0","x","0","0","0","0","x","x","x"},
    {"x","0","x","x","0","x","0","x","x","x"},
    {"x","0","x","x","x","x","0","x","x","x"},
    {"x","0","x","x","x","x","0","0","x","x"},
    {"x","0","x","x","0","x","0","x","x","x"},
    {"x","0","0","0","0","0","0","0","0","x"},
    {"x","x","x","x","0","x","x","x","0","0"},
    {"x","x","x","x","x","x","x","x","x","x"},
};

void PrintMazeMap(string mazeMapValue[10][10])
{

    for (int i = 0; i < 10; i++)
    {
        for (int j = 0; j < 10; j++)
        {
            cout << mazeMapValue[i][j] <<" ";
        }
        cout << endl;
    }
}

class Point
{
public:
    //默认构造
    Point()
    {

    }
    //有参构造
    Point(int x, int y)
    {
        this->m_x = x;
        this->m_y = y;
        this->yesNo = false;
    }

    //因为是自定义数据类型所以重载"=="用来判断两个点是否一样,
    // 例如判断终点和起点一样则表示已经走出迷宫,
    bool operator==(Point p1)
    {
        if (this->m_x == p1.m_x && this->m_y == p1.m_y)
        {
            return true;
        }
        return false;
    }

    //横纵坐标
    int m_x;
    int m_y;

    //"0"表示空地,"x"表示墙体
    string value;

    //true表示已访问  false表示未访问
    bool yesNo;
};

Point mazeMap[10][10];


void dfs(Point& startPoint,Point &desPoint )
{
    
    //如果起点和终点重合退出程序
    if (startPoint==desPoint)
    {
        return;
    }

    //向右探索
    //如果右边的点是空地且显示未访问的情况下我们可以向右前进
    if (mazeMap[startPoint.m_x][startPoint.m_y+1].value == "0" 
        && mazeMap[startPoint.m_x][startPoint.m_y + 1].yesNo == false)
    {
        //将该点设置为已经访问

        mazeMap[startPoint.m_x][startPoint.m_y + 1].yesNo = true;
        //前进
        startPoint.m_y++;
        
        //打印该地点的坐标
        cout << "(" << startPoint.m_x << startPoint.m_y << ")" << endl;
        
        //递归调用算法
        dfs(startPoint,desPoint);
        //将该点设置为未访问,
        // (如果我们走了一条路走不通我们需要回到上一步并把该点状态设置为未访问)
        mazeMap[startPoint.m_x][startPoint.m_y].yesNo = true;
        
    }

    //向下探索
    //如果下边的点是空地且显示未访问的情况下我们可以向下前进
    if (mazeMap[startPoint.m_x+1][startPoint.m_y].value == "0" 
        && mazeMap[startPoint.m_x+1][startPoint.m_y].yesNo == false)
    {
        
        //前进后将该点设置为已经访问
        mazeMap[startPoint.m_x+1][startPoint.m_y].yesNo = true;
        //前进
        
        startPoint.m_x++;
        cout << "(" << startPoint.m_x << startPoint.m_y << ")" << endl;
        //递归调用算法
        dfs(startPoint, desPoint);
        //将该点设置为未访问
        // (如果我们走了一条路走不通我们需要回到上一步并把该点状态设置为未访问)
        mazeMap[startPoint.m_x][startPoint.m_y].yesNo = true;
    }

    //向左探索
    //如果左边的点是空地且显示未访问的情况下我们可以向左前进
    if (mazeMap[startPoint.m_x][startPoint.m_y - 1].value == "0" 
        && mazeMap[startPoint.m_x][startPoint.m_y - 1].yesNo == false)
    {
        //前进后将该点设置为已经访问
        mazeMap[startPoint.m_x][startPoint.m_y - 1].yesNo = true;
        //前进
        startPoint.m_y--;
        cout << "(" << startPoint.m_x << startPoint.m_y << ")" << endl;
        //递归调用算法
        dfs(startPoint, desPoint);
        //将该点设置为未访问
        // (如果我们走了一条路走不通我们需要回到上一步并把该点状态设置为未访问)
        mazeMap[startPoint.m_x][startPoint.m_y].yesNo = true;
    }

    //向上探索
    //如果上边的点是空地且显示未访问的情况下我们可以向上前进
    if (mazeMap[startPoint.m_x - 1][startPoint.m_y].value == "0"
        && mazeMap[startPoint.m_x - 1][startPoint.m_y].yesNo == false)
    {
        //前进后将该点设置为已经访问
        mazeMap[startPoint.m_x - 1][startPoint.m_y].yesNo = true;
        //前进
        startPoint.m_x--;
        cout << "(" << startPoint.m_x << startPoint.m_y << ")" << endl;
        //递归调用算法
        dfs(startPoint, desPoint);
        //将该点设置为未访问
        // (如果我们走了一条路走不通我们需要回到上一步并把该点状态设置为未访问)
        mazeMap[startPoint.m_x][startPoint.m_y].yesNo = true;
    }

    return;
}

int main()
{

    Point desPoint(8, 9);
    Point startPoint(1, 0);

    PrintMazeMap(mazeMapValue);
    //初始化地图的值(墙体和空地)
    for (int i = 0; i < 10; i++)
    {
        for (int j = 0; j < 10; j++)
        {
            mazeMap[i][j].m_x = i;
            mazeMap[i][j].m_y = j;
            mazeMap[i][j].yesNo = false;
            mazeMap[i][j].value = mazeMapValue[i][j];
        }
    }
    cout << "走出迷宫路径如下" << endl;
    dfs(startPoint,desPoint);
    system("pause");
    return 0;
}

二、问题,求大神解答

每当我修改地图时我的走迷宫打印的路径就会陷入死胡同如下图

运行结果

求求各路大神帮忙看一下为什么

  • 14
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是C++的代码实现。 首先,我们需要定义一个迷宫的二维数组,用 0 表示可以通过的路,用 1 表示障碍物。接下来,我们需要定义一个函数,用来判断当前位置是否可以通过。如果当前位置已经到达迷宫的出口,则直接返回 True。否则,我们需要先判断当前位置是否越界,如果越界或者是障碍物,则返回 False。如果当前位置是可以通过的路,则将该位置标记为已经走过,并递归地调用上下左右四个方向的函数。如果四个方向都走不通,则将该位置标记为不可走,并返回 False。 以下是 C++ 代码实现: ```cpp #include<iostream> using namespace std; const int MAXN = 1010; int maze[MAXN][MAXN]; int n, m; bool dfs(int x, int y) { if (x == n - 1 && y == m - 1) { return true; } if (x < 0 || y < 0 || x >= n || y >= m || maze[x][y] == 1) { return false; } maze[x][y] = 1; if (dfs(x - 1, y) || dfs(x + 1, y) || dfs(x, y - 1) || dfs(x, y + 1)) { return true; } maze[x][y] = 0; return false; } int main() { cin >> n >> m; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> maze[i][j]; } } if (dfs(0, 0)) { cout << "Yes" << endl; } else { cout << "No" << endl; } return 0; } ``` 我们可以将迷宫表示为以下二维数组: ``` 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 ``` 最后,我们只需要调用函数并传入起点的坐标即可。 ```cpp if (dfs(0, 0)) { cout << "Yes" << endl; } else { cout << "No" << endl; } ``` 该函数返回 true 表示找到了一条从起点到出口的路径,返回 false 表示没有找到路径
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值