迷宫问题(一)------简单迷宫

所需知识

递归
结构体

❀思路分析

如图为一个简单的迷宫地图
简答理解为,数字1代表通路,数字0代表障碍物。
这里写图片描述

1.怎样创建迷宫地图的信息

创建一个结构体,内放二维数组来保存迷宫地图的坐标

/建立一个地图
typedef int DataType;
//迷宫
typedef struct Map
{
    DataType map[ROW][COL];
}Map;
2.怎样探路

创建一个结构体,用来保存地图中的位置(x,y)坐标,从入口开始,分别上下左右检测周边坐标元素,如果元素值为1,代表探测到了通路,则改变坐标到这一位置,以此类推。

//位置
typedef struct Position
{
    int x;
    int y;
}Point;
3.上下左右探路的时候怎么避免不走已经走过的路

将已经走过的路做一个标记,将值1改为2

4.遇到岔路口怎么办

走错路,探到了死路怎么办,如图
如果探路的优先级是,左侧和下侧在前,坐标很有可能走到该位置,此时坐标为(4,2)四面都不可走,此时说明之前某一个坐标的方向很有可能走错了,那我们就需要回到之前走错的这个路口(坐标)怎么回到前一坐标呢?定义一个栈,在开始让坐标移动的时候就用这个栈来保存走过的位置的坐标。在发现走入死胡同时,从栈中取出栈顶元素,即为上一步的位置,再次寻找其他出路
这里写图片描述

具体操作实现

#define __MAZE_H__
#ifdef __MAZE_H__
#define ROW 6 //行,纵坐标
#define COL 6 //列,横坐标

#include <stdio.h>  //打印
#include <stdlib.h>
#include <assert.h>

//建立一个地图
typedef int DataType;
//迷宫
typedef struct Map
{
    DataType map[ROW][COL];
}Map;
//位置
typedef struct Position
{
    int x;
    int y;
}Point;
//栈
typedef struct Stack
{
    Point Sta[40];
    int top;//栈顶,有效数的后一位坐标
}Stack;

//初始化栈
void InitStack(Stack * s);
//入栈
void PushStack(Stack * s, DataType d);
//出栈
void PopStack(Stack *s);
//取栈顶位置
Point StackTop(Stack * s);
//打印栈
void PrintStack(Stack * s);
//测试栈
void testStack(Stack *s);
//清空栈
void EmptyStack(Stack *s);


//初始化迷宫
void InitMaze(Map * maze);
//打印迷宫
void PrintMap(Map * maze);
//通过迷宫和入口寻找出路
void FindExit(Map * maze, Point entry);
//显示路线
void Path(Map * maze, Stack * s);




#endif //__MAZE_H__
//maze.c
#include "Maze.h"
//初始化栈
void InitStack(Stack * s)
{
    assert(s);
    s->top = 0;
}
//入栈
void PushStack(Stack * s,int x,int y)
{
    assert(s);
    if (40 == s->top )
        return;
    s->Sta[s->top].x = x;
    s->Sta[s->top].y = y;
    s->top++;
}
//出栈
void PopStack(Stack *s)
{
    assert(s);
    s->top--;
}
//取栈顶元素
Point StackTop(Stack * s)
{

    return (s->Sta [s->top-1]);
}
//打印栈
void PrintStack(Stack * s)
{
    for (int i = 0; i < s->top; i++)
    {
        printf(" x=%d ,y = %d \n", s->Sta[i].x,s->Sta[i].y);
    }
    printf("\n");
}
//清空栈 
void EmptyStack(Stack * s)
{
    s->top = 0;
}
//测试栈
void testStack(Stack * s)
{
    printf("测试栈\n");
    InitStack(s);
    printf("入栈1,1、2,1、,3,3、4,3、5,7\n");
    PushStack(s, 1,1);
    PushStack(s, 2,1);
    PushStack(s, 3,3);
    PushStack(s, 4,3);
    PushStack(s, 5,7);
    PrintStack(s);
    PopStack(s);
    printf("出栈一次\n");
    PrintStack(s);
    EmptyStack(s);
    printf("清空栈\n");
    PrintStack(s);
}
void InitMaze(Map * maze)
{
    int col = 0, row = 0;
    if (maze == NULL)//非法传参,按理这里为Map类型的指针
    {
        return;
    }
    //0 0 0 0 0 0
    //1 1 1 1 0 0
    //0 0 0 1 0 0
    //0 1 1 1 1 1
    //0 0 1 0 0 0
    //0 0 0 0 0 0
    //初始化一个数组
    DataType arr[ROW][COL] = {
        { 0, 0, 0, 0, 0, 0 },
        { 1, 1, 1, 1, 0, 0 },
        { 0, 0, 0, 1, 0, 0 },
        { 0, 1, 1, 1, 1, 1 },
        { 0, 0, 1, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0 }
    };
    //把该数组的值传递给迷宫
    for (row = 0; row < ROW; row++)
    {
        for (col = 0; col < COL; col++)
        {
            maze->map[row][col] = arr[row][col];
        }
    }   
}
void PrintMap(Map *maze)
{
    int col = 0, row = 0;
    printf("迷宫地图为\n-------------------\n");
    for (row = 0; row < ROW; row++)
    {
        for (col = 0; col < COL; col++)
        {
            printf(" %d ",maze->map[row][col]);
        }
        printf("\n");
    }
}
//检测当前节点是否有通路,优先次序为上左右下,入栈
int Pass(Map * maze, int x,int y)
{
    if (x >= ROW || y >= COL)
    {
        perror("error\n");
        return 0;
    }
    if (maze->map[x][y] == 1)
        return 1;
    return 0;
}
//检测是否走出迷宫
int YesPass(Map * maze, Point pos)
{
    if (pos.x == 0 || pos.y == 0 || pos.x == ROW - 1 || pos.y == COL - 1)
        return 1;
    return 0;
}
//通过迷宫地图和入口找出口
void FindExit(Map * maze, Point entry,Stack *s)
{
    Point cur = entry;
    Point pre = cur;
    //探路走起来
    do 
    {
        if (Pass(maze,cur.x -1,cur.y))
        {
            PushStack(s,cur.x,cur.y);//入栈
            maze->map[cur.x][cur.y] = 2;
            pre = cur;
            cur.x = cur.x - 1;
            continue;
        }
        if (Pass(maze,cur.x,cur.y-1))
        {
            PushStack(s, cur.x,cur.y);//入栈
            maze->map[cur.x][cur.y] = 2;
            pre = cur;
            cur.y = cur.y - 1;
            continue;
        }
        if (Pass(maze,cur.x,cur.y+1))
        {
            PushStack(s,cur.x,cur.y);//入栈
            maze->map[cur.x][cur.y] = 2;
            pre = cur;
            cur.y = cur.y + 1;
            continue;
        }
        if (Pass(maze,cur.x+1,cur.y))
        {
            PushStack(s,cur.x,cur.y);//入栈
            maze->map[cur.x][cur.y] = 2;
            pre = cur;
            cur.x = cur.x + 1;
            continue;
        }
        //四个方向都不通,回退
        maze->map[cur.x][cur.y] = 3;
        cur = StackTop(s);
        PopStack;   

    } while (!YesPass(maze, cur) || ((entry.x == cur.y) && (entry.y == cur.y)));
    //出口单独最后入栈
    PushStack(s, cur.x, cur.y);
}
//显示路线
void Path(Map * maze,Stack * s)
{
    while (s->top)
    {
        maze->map[StackTop(s).x][StackTop(s).y] = 8;
        PopStack(s);
    }
    printf("---------------------\n");
    for (int row = 0; row < ROW; row++)
    {
        for (int col = 0; col < COL; col++)
        {
            if (maze->map[row][col] != 8)
                maze->map[row][col] = 0;
            printf(" %d ", maze->map[row][col]);
        }
        printf("\n");
    }
}
#include "Maze.h"
int main()
{
    Map  maze;//创建地图
    Stack s;//创建保存路径的栈
    Point e;//给入口坐标
    e.x = 3;
    e.y = 5;
    testStack(&s);//测试栈的各个函数
    InitStack(&s);
    InitMaze(&maze);
    PrintMap(&maze);
    FindExit(&maze, e,&s);
    PrintStack(&s);
    PrintMap(&maze);
    //显示路线
    Path(&maze,&s);
    system("pause");
    return 0;
}

这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_24990383/article/details/81837560