C++处理迷宫问题(创建,dfs寻路,bfs寻路)

#include<iostream>
#include<algorithm>
#include<cstring>
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#include<conio.h>
#include<graphics.h>
#include <random>
#include <functional>
#define MaxSize 10010
#define side 101

using namespace std;
typedef struct
{
    int x, y, la;
}position;
typedef struct {
    position data[MaxSize];
    int front, rear;
}Queue;
char maze[side][side] = {};
char maze1[side][side] = {};
int dy[4] = { 1,0,-1,0 };
int dx[4] = { 0,1,0,-1 };
bool fi[side][side] = { };
int m, n;
int way_proportion = 70;
bool find_ = true;
void create_Maze();//创建迷宫
void  print_maze();//输出迷宫
void reduction_maze();//还原迷宫/赋值副本
void initialize_maze();//初始化墙
void  initQueue(Queue& que);
void enQueue(Queue& q, position d);
void deQueue(Queue& q);
void dfs_find_way(int x, int y);
void bfs_find_way();
void getsize();//获取m,n
void create_maze_dfs(int x,int y);
void dfs_create(int row, int col);
void  mgpath(int xi, int yi, int xe, int ye);

struct Node {
    int x; // 当前节点的 x 坐标
    int y; // 当前节点的 y 坐标
    int dir; // 下一个坐标方向
    Node* next; // 指向下一个节点的指针
};

class LinkedStack {
private:
    Node* top; // 栈顶节点指针

public:
    LinkedStack() {
        top = nullptr;
    }

    bool isEmpty() {
        return top == nullptr;
    }

    void push(int x, int y, int dir) {
        Node* newNode = new Node;
        newNode->x = x;
        newNode->y = y;
        newNode->dir = dir;
        newNode->next = top;
        top = newNode;
    }

    void pop() {
        if (isEmpty()) {
            return;
        }
        Node* temp = top;
        top = top->next;
        delete temp;
    }

    Node* getTop() {
        return top;
    }
};
//寻路8
void mgpath(int startX, int startY, int endX, int endY) {
   
    LinkedStack stack;
    stack.push(startX, startY, 0);
    maze1[startX][startY] =maze1[endX][endY]= ' ';
    bool foundPath = false;

    while (!stack.isEmpty()) {
        Node* top = stack.getTop();
        int x = top->x;
        int y = top->y;
        int dir = top->dir;
        // 到达终点
        if (x == endX && y == endY) {
            // 打印路径
            maze1[1][1] = 'S';
            maze1[m - 2][n - 2] = 'E';
            print_maze();
            cout << "路径: ";
            while (!stack.isEmpty()) {
                Node* node = stack.getTop();
                cout << "(" << node->x << "," << node->y << ") ";
                stack.pop();
            }
            cout << endl;
            foundPath = true;
            break;
        }
        bool found = false;
        // 尝试四个方向的移动:右、下、左、上
        for (int i = dir; i < 4; i++) {
            if (i == 0 && y + 1 < n && maze1[x][y + 1] == ' ') {
                stack.push(x, y + 1, 0); // 向右走
                maze1[x][y + 1] = '@';
                found = true;
                break;
            }
            else if (i == 1 && x + 1 < m && maze1[x + 1][y] == ' ') {
                stack.push(x + 1, y, 0); // 向下走
                maze1[x + 1][y] = '@';
                found = true;
                break;
            }
            else if (i == 2 && y - 1 >= 0 && maze1[x][y - 1] == ' ') {
                stack.push(x, y - 1, 0); // 向左走
                maze1[x][y - 1] = '@';
                found = true;
                break;
            }
            else if (i == 3 && x - 1 >= 0 && maze1[x - 1][y] == ' ') {
                stack.push(x - 1, y, 0); // 向上走
                maze1[x - 1][y] = '@';
                found = true;
                break;
            }
        }
        if (!found) {
            // 如果四个方向都不能移动,回溯
            stack.pop();
            maze1[x][y] = 'V';
        }
        else {
            // 更新下一个坐标方向
            top->dir = dir + 1;
        }
        HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
        // 设置控制台窗口缓冲区大小
        COORD bufferSize = { 120, 120 };
        SetConsoleScreenBufferSize(hOut, bufferSize);
        print_maze();
    }
    if (!foundPath) {
        // 没有找到路径
        cout << "没有找到路径" << endl;
    }
}
//改比例
void change_way_proportion()
{
    while (1)
    { cout << "请输入路径比例" << endl;
        cin >> way_proportion;
        if (way_proportion <= 0 || way_proportion > 99)
        {
            cout << "数值不规范" << endl;
            continue;
        }
        break;
    }
    create_Maze();
    print_maze();
    return;
}
//初始化
void initialize_maze()//初始化
{
    for (int i = 0;i < m;i++)
    {
        for (int j = 0;j < n;j++)
        {
            maze[i][j] = '#';
        }
    }
    maze[1][1] = 'S';
    maze[m - 2][n - 2] = 'E';
}//初始化迷宫
int IsHaveNeighbor(int X_index, int Y_index)//判断是否有邻居
{
        if ((X_index >= 3 && maze[X_index - 2][Y_index] == '#') || (X_index < m - 3 && maze[X_index + 2][Y_index] == '#') || (Y_index >= 3 && maze[X_index][Y_index - 2] == '#') || (Y_index < n - 3 && maze[X_index][Y_index + 2] == '#'))
            return 1;//有邻居
        return 0;      
}
void dfs_create(int X_index, int Y_index){
    int rand_position, x, y, flag = 0;
    x = X_index;
    y = Y_index;
    //如果四个方向都没有了,返回上一步的xy,否则,继续
    while (1)
    {
        flag = IsHaveNeighbor(X_index, Y_index);
        if (flag == 0)
        {
            return;//返回该函数的上一条
        }
        else
        {
            maze[X_index][Y_index] =' ';
            while (1)
            {
                rand_position = rand() % 4;
                if (rand_position == 0 && X_index >= 3 && maze[X_index - 2][Y_index] == '#')//上
                {
                    X_index = X_index - 2;
                }
                else if (rand_position == 1 && X_index < m- 3 && maze[X_index + 2][Y_index] == '#')//下
                {
                    X_index = X_index + 2;
                }
                else if (rand_position == 2 && Y_index >= 3 && maze[X_index][Y_index - 2] == '#')//左
                {
                    Y_index -= 2;
                }
                else if (rand_position == 3 && Y_index < n - 3 && maze[X_index][Y_index + 2] == '#')//右
                {
                    Y_index += 2;
                }
                maze[(x + X_index) / 2][(y + Y_index) / 2] =' ';//当前位置,移动后位置中间位置打通,表示路径
                maze[X_index][Y_index] = ' ';
                dfs_create(X_index, Y_index);
                break;
            }
        }
    }
}
void create_maze_dfs(int rows,int columns)
{
    initialize_maze();
    random_device rd;
    mt19937 generator(rd());

    int start_row = generator() % rows;
    int start_col = generator() % columns;

    dfs_create( start_row, start_col); // 调用DFS算法生成迷宫
    maze[1][2] = ' ';
    maze[2][1] = ' ';
    maze[m-2][n-3] = ' ';
    maze[m-3][n-2] = ' ';
    maze[1][1] = 'S';
    print_maze();
}
void deQueue(Queue& q)
{
    q.front++;
}
void enQueue(Queue& q, position d)
{
    q.data[q.rear] = d;
    q.rear++;
}
void  initQueue(Queue& que) {
    que.front = que.rear = 0;
}
void reduction_maze()
{
    for (int i = 1; i < m - 1; ++i) {
        for (int j = 1; j < n - 1; ++j)
        {
            maze1[i][j] = maze[i][j];
        }
    }
    print_maze();
}
void  print_maze()
{
    Sleep(20);
    system("cls");
    int i = 0, j = 0;
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
        {
            if (maze1[i][j] == 'S'|| maze1[i][j] == 'E')
            {
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE);
                cout << "█ ";
            }
            else if (maze1[i][j] == '#')
            {
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
                cout << "█ ";
            }
            else if (maze1[i][j] == ' ')
            {
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);
                cout << "█ ";
            }
            else if (maze1[i][j] == 'V')
            {
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);
                cout << "█ ";
            }
            else if (maze1[i][j] == '@')
            {
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE);
                cout << "█ ";
            }
          // cout << maze1[i][j] << " ";
        }
        cout << endl;
    }
    cout<< "***********星树***************" << endl
        << "*  输入1重新随机生成迷宫     *" << endl
        << "*  输入2生成基于DFS迷宫      *" << endl
        << "*  输入3还原迷宫             *" << endl
        << "*  输入4深搜                 *" << endl
        << "*  输入5广搜                 *" << endl
        << "*  输入6修改迷宫大小         *" << endl
        << "*  输入7修改可行路径比例     *" << endl
        << "*  输入8非递归寻路           *" << endl
        << "*  输入q退出                 *" << endl
        << "******************************" << endl;
    //system("pause");
}
void create_Maze() {
    // 初始化迷宫为墙
    initialize_maze();
    // 随机生成路径
    srand(time(NULL));
    for (int i = 1; i < m - 1; i++) {
        for (int j = 1; j < n - 1; j++) {

            // 生成0~99之间的随机数
            int randomNumber = rand() % 100;
            if (randomNumber < way_proportion&& maze[i][j]=='#') {  // 50%的概率生成路径
                maze[i][j] = ' ';
            }
        }
    }
   
   
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j)
        {
            maze1[i][j] = maze[i][j];
        }
    }
}
void dfs_find_way(int x, int y)
{
    if (find_)
    {
        return;
    }
    else {
        for (int i = 0;i < 4;i++)
        {

            int nextx = x + dx[i], nexty = y + dy[i];
            if (maze1[nextx][nexty] == 'E')
            {
                find_ = true;
                return;
            }
            if (maze1[nextx][nexty] == ' ' && !fi[nextx][nexty] && !find_)
            {
                maze1[nextx][nexty] = '@';

                HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
                // 设置控制台窗口缓冲区大小
                COORD bufferSize = { 120, 120 };
                SetConsoleScreenBufferSize(hOut, bufferSize);

                print_maze();
                fi[nextx][nexty] = true;
                dfs_find_way(nextx, nexty);
                if (!find_)
                    maze1[nextx][nexty] = 'V';
            }

       }
    }
}
void bfs_find_way()
{
    reduction_maze();
    Queue que;
    position d;
    d.x = 1;
    d.y = 1;
    d.la = 0;
    initQueue(que);
    enQueue(que, d);
    while (que.front != que.rear)
    {
        auto fr = que.data[que.front];
        for (int i = 0;i < 4;i++)
        {
            d.x = fr.x + dx[i];
            d.y = fr.y + dy[i];
            if (maze1[d.x][d.y] == ' ')
            {
                d.la = que.front;
                enQueue(que, d);
                maze1[d.x][d.y] = 'V';
            }
            if (maze1[d.x][d.y] == 'E')
            {
                int  lt = que.front;
                while (que.data[lt].la != 0) {
                    maze1[que.data[lt].x][que.data[lt].y] = '@';
                    lt = que.data[lt].la;
                }

                maze1[que.data[lt].x][que.data[lt].y] = '@';

                HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
                // 设置控制台窗口缓冲区大小
                COORD bufferSize = { 120, 120 };
                SetConsoleScreenBufferSize(hOut, bufferSize);


                print_maze();
                cout << "已找到路径" << endl;
                return;
            }
        }
        HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
        // 设置控制台窗口缓冲区大小
        COORD bufferSize = { 120,120 };
        SetConsoleScreenBufferSize(hOut, bufferSize);
        print_maze();
        deQueue(que);
    }
    cout << "无路径" << endl;
    return;
}
void getsize()
{
    while (1)
    {
        cout << "请输入迷宫的长(5-100):" << endl;
        cin >> m;
        cout << "请输入迷宫的宽(5-100):" << endl;
        cin >> n;
        if (m <=4 || n <=4)
        {
            cout << "迷宫太小了";
            continue;
        }
        if (m >= 100 || n >= 100)
        {
            cout << "迷宫太大了";
            continue;
        }
        break;
    }
}
int main()
{ 
    while (1)
    {
        getsize();
        create_Maze();
        print_maze();
        while (true)
        {
            char c;
            cin >> c;
            switch (c)
            {
            case '1'://重新生成迷宫
                create_Maze();
                print_maze();
                break;
            case'2'://dsf生成     
                create_maze_dfs(m,n);
                reduction_maze();
                break;
            case'3'://还原迷宫
                reduction_maze();
                break;
            case'4'://dfs
                reduction_maze();
                find_ = false;
                memset(fi, false, sizeof(fi));
                dfs_find_way(1, 1);
                if (!find_)
                    cout << "无路径" << endl;
                else
                    cout << "已找到路径" << endl;
                break;
            case'5'://bfs
                bfs_find_way();
                break;
            case'6'://改尺寸
                getsize();
                create_Maze();
                print_maze();
                break;
            case'7'://改比例
                change_way_proportion();
                create_Maze();
                break;
            case'8':
                reduction_maze();
                mgpath(1,1,m - 2, n - 2);
                break;
            case'q'://退出
                return 0;
            default:
                string error_in;
                cin >> error_in;
                cout << "输入错误" << endl;
                break;
            }
        }
    }
}

‘#’为墙

‘@’为路径

‘S'E’分别为起点终点

‘V’为可到达的点

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,下面是C语言实现的图的创建DFSBFS搜索的示例代码: ```c #include <stdio.h> #include <stdlib.h> #define MAX_VERTEX_NUM 100 // 最大顶点数 typedef struct ArcNode { // 边表节点 int adjvex; // 邻接点下标 struct ArcNode *next; // 指向下一个节点的指针 } ArcNode; typedef struct VNode { // 顶点表节点 int data; // 顶点数据 ArcNode *firstarc; // 边表头指针 } VNode, AdjList[MAX_VERTEX_NUM]; typedef struct { // 图 AdjList vertices; // 顶点表 int vexnum, arcnum; // 顶点数和边数 } Graph; // 创建图 void CreateGraph(Graph *G) { int i, j, k; ArcNode *p; printf("请输入图的顶点数和边数:\n"); scanf("%d%d", &G->vexnum, &G->arcnum); printf("请输入各个顶点的数据:\n"); for (i = 0; i < G->vexnum; i++) { scanf("%d", &G->vertices[i].data); G->vertices[i].firstarc = NULL; } printf("请输入各个边的两个顶点的下标:(如0 1,表示边<0,1>)\n"); for (k = 0; k < G->arcnum; k++) { scanf("%d%d", &i, &j); p = (ArcNode *)malloc(sizeof(ArcNode)); p->adjvex = j; p->next = G->vertices[i].firstarc; G->vertices[i].firstarc = p; p = (ArcNode *)malloc(sizeof(ArcNode)); p->adjvex = i; p->next = G->vertices[j].firstarc; G->vertices[j].firstarc = p; } } // DFS搜索 void DFS(Graph G, int v, int visited[]) { ArcNode *p; visited[v] = 1; printf("%d ", G.vertices[v].data); for (p = G.vertices[v].firstarc; p; p = p->next) { if (!visited[p->adjvex]) { DFS(G, p->adjvex, visited); } } } // BFS搜索 void BFS(Graph G, int v, int visited[]) { int queue[MAX_VERTEX_NUM], front = -1, rear = -1; ArcNode *p; visited[v] = 1; printf("%d ", G.vertices[v].data); queue[++rear] = v; while (front != rear) { v = queue[++front]; for (p = G.vertices[v].firstarc; p; p = p->next) { if (!visited[p->adjvex]) { visited[p->adjvex] = 1; printf("%d ", G.vertices[p->adjvex].data); queue[++rear] = p->adjvex; } } } } int main() { Graph G; int visited[MAX_VERTEX_NUM] = {0}; CreateGraph(&G); printf("DFS搜索结果为:"); DFS(G, 0, visited); printf("\nBFS搜索结果为:"); BFS(G, 0, visited); printf("\n"); return 0; } ``` 在上述代码中,我们使用了邻接表来表示图,其中`VNode`表示顶点表节点,`ArcNode`表示边表节点,`AdjList`是一个由`VNode`组成的数组,即邻接表。在创建图时,我们先输入顶点数和边数,然后输入各个顶点的数据和各个边的两个顶点的下标,根据下标构建边表。 接着,我们分别实现了DFSBFS搜索。在DFS搜索中,我们先访问当前节点,并将其标记为已访问,然后遍历所有邻接点,若邻接点未被访问,则递归访问它。在BFS搜索中,我们使用队列来实现搜索。从起始节点开始,先访问该节点,并将其入队。然后从队列中依次取出节点,遍历其所有邻接点,若邻接点未被访问,则访问它并将其入队。 最后,在`main`函数中,我们调用`CreateGraph`函数创建图,并分别调用`DFS`和`BFS`函数进行搜索。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值