使用递归的迷宫最短路径

时间:2015-05-26 18:41:20

标签: c++ recursion depth-first-search breadth-first-search maze

首先,我想要注意的是,我之前发布了同样的问题,并没有找到正确的答案,很抱歉重复提问。

请注意,我需要在这里使用递归。我知道通常使用BFS找到最短路径,这不是递归的,但我需要知道如何以递归方式完成。

我正在制作一个胭脂游戏,我的一个怪物表现得像这样。在迷宫中,如果怪物可以在15步或更少的步骤中到达玩家,则可以实现最佳移动。为了实现这一点,我写了一个小程序,模仿我游戏中将要发生的事情。我的程序的工作方式是能够检查x量的移动是否会使他到达目的地。我不确定的唯一部分是如何获得第一步,所以我可以将该信息传递给我的怪物移动功能。这是我到目前为止写的程序。

我的一位同学建议用不同的价值填补空白空间并找到那条道路,但我无法理解他的意思。有人可以向我解释如何做到这一点吗?

#include <iostream>

using namespace std;



bool pathExists(char maze[][10], int sr, int sc, int er, int ec, int distance) {
    if (maze[sr][sc] != '.')
        return false;

    if (sr == er  &&  sc == ec)
        return true;

    if(distance == 15) {
        cout<<"Cant make it in 15 steps"<<endl;
        return false;
    }
    maze[sr][sc] = '@';  // anything non-'.' will do

    if (pathExists(maze, sr-1, sc, er, ec, distance+1))
        return true;
    if (pathExists(maze, sr+1, sc, er, ec,distance+1))
        return true;
    if (pathExists(maze, sr, sc-1, er, ec, distance+1))
        return true;
    if (pathExists(maze, sr, sc+1, er, ec, distance+1))
        return true;

    return false;
}

int main() {
    char maze[10][10] = {
        { 'X','X','X','X','X','X','X','X','X','X'},
        { 'X','.','.','.','.','.','.','.','.','X'},
        { 'X','.','X','X','X','X','.','X','X','X'},
        { 'X','.','.','X','.','X','.','.','.','X'},
        { 'X','.','.','X','.','.','.','X','.','X'},
        { 'X','.','X','X','.','X','X','X','.','X'},
        { 'X','.','X','.','.','.','.','X','X','X'},
        { 'X','.','.','X','X','.','X','X','.','X'},
        { 'X','.','.','x','.','.','.','.','.','X'},
        { 'X','X','X','X','X','X','X','X','X','X'}
    };

    if (pathExists(maze, 8,8, 1,1,0))
        cout << "Solvable!" << endl;
    else
        cout << "Out of luck!" << endl;
}

2 个答案:

答案 0 :(得分:4)

您的算法效果很好。如果测试路径不成功,唯一缺少的是恢复'.'中的pathExist()

    ...
    if(pathExists(maze, sr, sc + 1, er, ec, distance + 1))
        return true;

    maze[sr][sc] = '.'; //<===========  add this to restore the maze state

    return false;
    }

如果没有这一行,找不到正确路径的失败尝试将使用'@'填充数组,以便随后的探索不会找到任何可行的&#39;。&#39;了。

顺便说一句,由于位置'x' [8][3],您在问题中发布的迷宫在不到15次尝试中无法解决。

其他评论:

你也问过这项工作。事实上,你的递归算法没有&#39; @&#39;没有记忆。所以在递归调用中,它不记得它是否来自,这将导致无限递归累积到以下模式: enter image description here
将当前位置暂时更改为&#39; @&#39;就像你标记当前正在探索的路径的不同单元格一样: enter image description here

请注意,如果您最后打印出网格,则会看到找到的完整路径(有问题的&#39; x&#39;已移除):
enter image description here

答案 1 :(得分:0)

我不确定的唯一部分是如何获得第一步,所以我可以将该信息传递给我的怪物移动功能。这是我到目前为止编写的程序。

如果路径存在,可能的方法是从函数返回下一步的代码,否则为0(尽管这可能不是可读代码的推荐方法,但只是提出想法)

int pathExists(char maze[][10], int sr, int sc, int er, int ec, int distance) {
    if (maze[sr][sc] != '.')
        return 0; //

    if (sr == er  &&  sc == ec)
        return 5; // we are there

    if(distance == 15) {
        cout<<"Cant make it in 15 steps"<<endl;
        return 0;
    }
    maze[sr][sc] = '@';  // anything non-'.' will do

    if (pathExists(maze, sr-1, sc, er, ec, distance+1))
        return -1; // move north
    if (pathExists(maze, sr+1, sc, er, ec,distance+1))
        return 1; // move south
    if (pathExists(maze, sr, sc-1, er, ec, distance+1))
        return -2; // move west
    if (pathExists(maze, sr, sc+1, er, ec, distance+1))
        return 2; // move east

    maze[sr][sc] = '.'; // restore the maze, as in the previous answer
    return 0;
}