Recursive solution of maze with loops

A labyrinth with multiple paths and loops is shown in the figure:

write picture description here

If we adopt the solution of the maze with only one path, https://blog.csdn.net/virgofarm/article/details/80081804 , we will walk out of the maze directly from the red line as shown in the figure below

write picture description here

However, since there are other routes and the exits are the same, the road closure method cannot be adopted. We can do this. Before taking each step, add one to the value of the current position to mark the position to be taken next, and determine whether the next step is In addition to the path, the value is one, or the value of the current position is less than the value of the next position. The mind map for solving the maze problem is as follows. write picture description hereThe specific code is implemented as follows, and the dependent stack can be referred to https://blog.csdn.net/virgofarm/article/details/80065574 :

Maze.h

#pragma once
#define MAX_ROW 4
#define MAX_COL 4

typedef struct Position
{
    int _x;
    int _y;
}Position;

typedef struct Maze
{
    int _map[MAX_ROW][MAX_COL];

}Maze, *PMaze;

void InitMaze(PMaze pm, int map[][MAX_COL]);//初始化
int _PassMaze(PMaze pm, Position entry, Position cur, PStack PPath, PStack PShortPath);//真正走迷宫
int IsExit(PMaze pm, Position cur, Position entry);//检测是否是出口
int IsValidEntry(PMaze pm, Position entry);//检测入口是否合法
void PassMaze(PMaze pm, Position entry, PStack ps);//提供给用户的走迷宫函数
void PrintMaze(PMaze pm, int map[][MAX_COL]);//打印迷宫

Maze.c

#include "stack.h"
#include "Maze.h"


//打印迷宫
void PrintMaze(PMaze pm)
{
    int i = 0;
    assert(pm);

    for (; i < MAX_ROW; ++i)
    {
        int j = 0;
        for (; j < MAX_COL; ++j)
        {
            printf("%d ", pm->_map[i][j]);
        }
        printf("\n");
    }

}

//迷宫初始化,就是将地图中的值赋给迷宫
void InitMaze(PMaze pm, int map[][MAX_COL])
{
    int i = 0;
    assert(pm);

    for (; i < MAX_ROW; ++i)
    {
        int j = 0;
        for (; j < MAX_COL; ++j)
        {
            pm->_map[i][j] = map[i][j];
        }
    }
}


//检测迷宫入口是否合法
int IsValidEntry(PMaze pm, Position entry)
{
    assert(pm);

    //必须位于迷宫边界且值为1
    if ((entry._x == 0 || entry._y == 0 || entry._x == MAX_ROW - 1
        || entry._y == MAX_COL - 1) && (pm->_map[entry._x][entry._y] == 1))
        return 1;
    return 0;
}

int IsPass(PMaze pm, Position cur, Position next)
{
    assert(pm);

    //next值为1且不能越界
    if ((next._x >= 0 && next._x <= MAX_ROW - 1) &&
        (next._y >= 0 && next._y <= MAX_COL - 1) &&
        pm->_map[next._x][next._y] == 1)
        return 1;
    //next值大于cur值且不能越界
    if ((cur._x >= 0 && cur._x <= MAX_ROW - 1) &&
        (cur._y >= 0 && cur._y <= MAX_COL - 1) &&
        pm->_map[cur._x][cur._y] < pm->_map[next._x][next._y])
        return 1;

    return 0;

}

//检测是否是出口
int IsExit(PMaze pm, Position cur, Position entry)
{
    assert(pm);

    //因为之前已经走过了,所以只要处于边界且不是入口肯定是出口
    if ((cur._x == 0 || cur._x == MAX_ROW - 1 ||
        cur._y == 0 || cur._y == MAX_COL - 1) &&
        ((cur._x != entry._x) || (cur._y != entry._y)))
        return 1;
    return 0;

}

void UpdatePath(PStack PPath, PStack PShortPath)
{
    int i = 0;
    int size = 0;
    assert(PPath);
    assert(PShortPath);

    PShortPath->size = PPath->size;
    size = PPath->size;

    for (; i < size; i++)
        PShortPath->arr[i] = PPath->arr[i];
}

int _PassMaze(PMaze pm, Position entry, Position cur, PStack PPath, PStack PShortPath)
{
    Position next;

    assert(pm);
    assert(PPath);
    assert(PShortPath);

    //栈如果为空说明进来的是入口
    if (!StackSize(PPath))
        pm->_map[cur._x][cur._y] = 2;
    StackPush(PPath, cur);

    //判断是否为出口
    if (IsExit(pm, cur, entry))
    {
        //更新最短路径:1.PShortPath为空2.PShortPath的size大于PPath的size
        if (StackEmpty(PShortPath))
            UpdatePath(PPath, PShortPath);
        if (StackSize(PPath) < StackSize(PShortPath))
            UpdatePath(PPath, PShortPath);

        //将PPath中的栈顶元素出栈,继续找路径
        StackPop(PPath);
    }

    //上
    next = cur;
    next._x -= 1;
    if (IsPass(pm, cur, next))
    {
        //先用cur的值加1标记next位置,再走next
        pm->_map[next._x][next._y] = pm->_map[cur._x][cur._y] + 1;
        _PassMaze(pm, entry, next, PPath, PShortPath);
    }

    //左
    next = cur;
    next._y -= 1;
    if (IsPass(pm, cur, next))
    {
        pm->_map[next._x][next._y] = pm->_map[cur._x][cur._y] + 1;
        _PassMaze(pm, entry, next, PPath, PShortPath);
    }

    //右
    next = cur;
    next._y += 1;
    if (IsPass(pm, cur, next))
    {
        pm->_map[next._x][next._y] = pm->_map[cur._x][cur._y] + 1;
        _PassMaze(pm, entry, next, PPath, PShortPath);
    }

    //下
    next = cur;
    next._x += 1;
    if (IsPass(pm, cur, next))
    {
        pm->_map[next._x][next._y] = pm->_map[cur._x][cur._y] + 1;
        _PassMaze(pm, entry, next, PPath, PShortPath);
    }

    //说明cur走错了
    StackPop(PPath);
    return 0;
}

void PassMaze(PMaze pm, Position entry, PStack ps)
{
    Stack PShortPath;

    assert(pm);
    assert(ps);

    //先判断迷宫入口是否合法
    if (!IsValidEntry(pm, entry))
    {
        printf("迷宫入口非法!!!\n");
        return;
    }
    //开始真的走进入口
    _PassMaze(pm, entry, entry, ps, &PShortPath);
}

test.c

#include "stack.h"
#include "Maze.h"
#include <windows.h>


void TestMaze(PStack ps)
{
    int i = 0;
    Position entry;
    Maze m;
    PMaze pm = &m;
    StackInit(ps, 10);
    int map[4][4] = { { 0, 0, 0, 0 },
                      { 0, 1, 1, 0 },
                      { 0, 1, 1, 1 },
                      { 0, 1, 0, 0 }};
    InitMaze(pm, map);
    PrintMaze(pm, map);
    entry._x = 3;
    entry._y = 1;
     PassMaze(pm, entry, ps);//带环迷宫递归
    printf("\n");
    PrintMaze(pm, map);


}
int main()
{
    Stack s;
    PStack ps = &s;

   TestMaze(ps);//测试迷宫
    system("pause");
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325944661&siteId=291194637