xiaohf 发表于 2019-1-1 16:10

【C++】生成迷宫的图的深度优先算法和prim算法,还有寻路算法

1、需要安装easyx图形库(官网下载,超级简单)
2、代码有详细注释,有些函数命名不规范
3、代码如下
#include<iostream>
#include<stdlib.h>
#include<time.h>
#include <graphics.h>

using namespace std;

/**************************/
/*栈的函数*/
struct Stack
{
        int *stack;
        int base;
        int top;
};

Stack* CreateStack(int Capacity)//创建栈
{
        Stack *S = new Stack;
        S->stack = new int;
        S->base = 0;
        S->top = -1;
        return S;
}

void DestroyStack(Stack *S)    //销毁栈
{
        delete S;
        S = NULL;
}

bool EmptyStack(Stack *S)   //判断栈是否为空
{
        if (S->top == -1)
                return false;
        else
                return true;
}

void PushStack(Stack *S, int elem)    //出栈
{
        S->top++;
        S->stack = elem;
}

void PopStack(Stack *S)    //入栈
{
        if (EmptyStack(S))
                S->top--;
}

int TopStack(Stack *S)   //返回栈顶元素
{
                return S->stack;
}
/************************/
/************************/

/************************/
/****辅助深度优先算法判断是否是死的函数***/
struct BBS
{
        int right = 0;
        int upside = 1;
        int left = 2;
        int below = 3;
};

void CCC(BBS *S, int n)
{
        if (n == 0)
                S->right = -1;
        if (n == 1)
                S->upside = -1;
        if (n == 2)
                S->left = -1;
        if (n == 3)
                S->below = -1;
}

bool AA(BBS *S)
{
        if (S->below == -1 && S->left == -1 && S->right == -1 && S->upside == -1)
                return 0;
        else
                return 1;
}

void BB(BBS *S)
{
        S->right = 0;
        S->upside = 1;
        S->left = 2;
        S->below = 3;
}
/******************/
/******************/

struct Coordinate//迷宫点类
{
        bool Judgment = 1;   //判断是否为墙,1为是,0为不是
        bool Judgemet_2 = 0;//prim算法用到,深度优先算法没用
};

struct Coordinated//prim算法用到,深度优先算法没用
{
        int adress;
};

/*********************/
/********prime算法***********/
void Sequence(Coordinated *Arry, int n, int &sum)   //把元素从数组删除
{
        int i;
        for (i = n; i < sum; i++)
        {
                Arry = Arry;
        }
        sum--;
}

void Store(Coordinated *map_1, Coordinate *map_2, int map, int &k, int n)   //把元素储存进数组
{
        if (((map + 2) % n != 0)&&map_2.Judgemet_2 == 0)
        {
                map_1.adress = map + 1;
                map_2.adress].Judgemet_2 = 1;
                k++;
        }
        if (((map - 1) % n != 0) && map_2.Judgemet_2 == 0)
        {
                map_1.adress = map - 1;
                map_2.adress].Judgemet_2 = 1;
                k++;
        }
        if (((map - n) / n != 0) && map_2.Judgemet_2 == 0)
        {
                map_1.adress = map - n;
                map_2.adress].Judgemet_2 = 1;
                k++;
        }
        if (((map + n) / n != n - 1) && map_2.Judgemet_2 == 0)
        {
                map_1.adress = map + n;
                map_2.adress].Judgemet_2 = 1;
                k++;
        }
}

void PrimeMap(Coordinate *map, int n)
{
        Coordinated *map2 = new Coordinated[(n*n-3*n-2)/2];
        srand((unsigned)time(0));

        int k = 2;
        map2.adress = n + 2;
        map2.adress = 2 * n + 1;
        map.Judgemet_2 = 1;
        map.Judgemet_2 = 1;

        int b;
        while(k!=0)
        {
                b = rand() % k;
                if ((map2.adress / n) % 2 == 0)
                        if (map.adress + n].Judgment + map.adress - n].Judgment > 0)
                        {
                                map.adress + n].Judgment = 0;
                                map.adress].Judgment = 0;
                                map.adress - n].Judgment = 0;
                                Store(map2, map, map2.adress + n, k, n);
                                Store(map2, map, map2.adress - n, k, n);
                                Sequence(map2, b, k);
                                continue;
                        }
                        else
                        {
                                Sequence(map2, b, k);
                                continue;
                        }
                if ((map2.adress / n) % 2 == 1)
                        if (map.adress + 1].Judgment + map.adress - 1].Judgment > 0)
                        {
                                map.adress + 1].Judgment = 0;
                                map.adress].Judgment = 0;
                                map.adress - 1].Judgment = 0;
                                Store(map2, map, map2.adress + 1, k, n);
                                Store(map2, map, map2.adress - 1, k, n);
                                Sequence(map2, b, k);
                                continue;
                        }
                        else
                        {
                                Sequence(map2, b, k);
                                continue;
                        }
        }
        map.Judgment = 0;
        map.Judgment = 0;
        delete map2;
}
/*******prim算法**********/
/***********************/

/***********************/
/***图的深度优先算法***/
void CreateMap(Coordinate *map,int n)       //生成迷宫数组的函数,map为指向数组的指针,n为迷宫大小
{
        /*初始化数据*/
        int k = 0;
        int b;
        int Num = (n - 1) / 2;
        enum Direction { right, upside, left, below };    //方向

        BBS *Q = new BBS;
        Stack *ABS = CreateStack(Num*Num);

        srand((unsigned)time(0));      //随机数种子

        PushStack(ABS, n+1);
        map.Judgment = 0;

        //生成一个储存迷宫信息的数组
        while (EmptyStack(ABS))
        {
                //如果栈为空,则退出
                if (!AA(Q))
                {
                        PopStack(ABS);
                        BB(Q);
                        continue;
                }

                b = rand() % 4;   //随机数

                CCC(Q, b);

                //生成迷宫算法
                switch (b)
                {
                case right:
                        if ((TopStack(ABS) + 2) % n != 0)
                        {
                                if (map.Judgment == 1)
                                {
                                        map.Judgment = 0;
                                        map.Judgment = 0;
                                        PushStack(ABS, TopStack(ABS) + 2);
                                        BB(Q);
                                        break;
                                }
                                else
                                        break;
                        }
                        else
                                break;
                case upside:
                        if (TopStack(ABS) - 2 * n > 0)
                        {
                                if (map.Judgment == 1)
                                {
                                        map.Judgment = 0;
                                        map.Judgment = 0;
                                        PushStack(ABS, TopStack(ABS) - 2 * n);
                                        BB(Q);
                                        break;
                                }
                                else
                                        break;
                        }
                        else
                                break;
                case left:
                        if ((TopStack(ABS) - 1) % n != 0)
                        {
                                if (map.Judgment == 1)
                                {
                                        map.Judgment = 0;
                                        map.Judgment = 0;
                                        PushStack(ABS, TopStack(ABS) - 2);
                                        BB(Q);
                                        break;
                                }
                                else
                                        break;
                        }
                        else
                                break;
                case below:
                        if (TopStack(ABS) + 2 * n < n*n-1)
                        {
                                if (map.Judgment == 1)
                                {
                                        map.Judgment = 0;
                                        map.Judgment = 0;
                                        PushStack(ABS, TopStack(ABS) + 2 * n);
                                        BB(Q);
                                        break;
                                }
                                else
                                        break;
                        }
                        else
                                break;
                }
        }

        //设置起点和出口
        map.Judgment = 0;
        map.Judgment = 0;

        DestroyStack(ABS);
        delete Q;
}

/***********************/
/***图的深度优先算法***/

Stack* Pathfinding(Coordinate *map,int n)   //寻找迷宫路径的函数,返回一个储存路径的栈,map为指向迷宫数组的指针,n为迷宫大小
{
        int k = 1;
        Stack *x = CreateStack(n*n);
        Stack *v = CreateStack(n*n);
        PushStack(x, 1);
        PushStack(x, n + 1);

        while (1)
        {
                map].Judgment = 1;
                if (map.Judgment == 0)
                {
                        map].Judgment = 0;
                        PushStack(x, TopStack(x) + 1);
                        k++;
                        continue;
                }
                else if (map.Judgment == 0 && TopStack(x) + n < (n*n - 1))
                {
                        map].Judgment = 0;
                        PushStack(x, TopStack(x) + n);
                        k++;
                        continue;
                }
                else if (map.Judgment == 0)
                {
                        map].Judgment = 0;
                        PushStack(x, TopStack(x) - 1);
                        k++;
                        continue;
                }
                else if (map.Judgment == 0 && TopStack(x) - n > 0)
                {
                        map].Judgment = 0;
                        PushStack(x, TopStack(x) - n);
                        k++;
                        continue;
                }
                else if (TopStack(x) == n * n - 2)
                {
                        map].Judgment = 0;
                        while (EmptyStack(x))
                        {
                                PushStack(v, TopStack(x));
                                PopStack(x);
                        }
                        DestroyStack(x);
                        return v;
                }
                else
                {
                        map.Judgment = 1;
                        PopStack(x);
                        map.Judgment = 0;
                        k--;
                }
        }
}

void picture_one(Coordinate *map, int n)      //画迷宫的函数,map为指向储存迷宫数组的指针,n为迷宫大小
{
        // 初始化图形模式
        initgraph(n*10, n*10);

        //画图,黑色为墙,白色为通路
        for (int x = 0; x < n; x++) {
                for (int y = 0; y < n; y++) {               
                        if (map.Judgment == 0) {
                                setfillcolor(WHITE);
                                solidrectangle(x * 10, y * 10, x * 10 + 10, y * 10 + 10);
                        }
                        else
                        {
                                //Sleep(10);
                                setfillcolor(BLACK);
                                solidrectangle(x * 10, y * 10, x * 10 + 10, y * 10 + 10);
                        }
                }
        }
       
        getchar();                                // 按任意键继续
}

void picture_two(Stack *s,int n)//画迷宫路径的函数,s为储存迷宫路径的函数,n为迷宫大小
{
        int num;
        int x, y;
        setfillcolor(RED);   //颜色
        while (EmptyStack(s))
        {
                num = TopStack(s);
                PopStack(s);
                x = num / n;
                y = num % n;
                solidrectangle(x * 10, y * 10, x * 10 + 10, y * 10 + 10);//画矩阵
                Sleep(10);
        }
        getchar();         //按任意键继续
        closegraph();      //关闭幕布
}

int main()
{
        int n = 2;
        int b;
        while (n % 2 == 0)
        {
                cout << "请输入迷宫大小(大小为奇数):";
                cin >> n;
                cout << endl;
        }

        Coordinate*s = NULL;
        while (s == NULL)
                s = new Coordinate;

        cout << "1:深度遍历" << endl;
        cout << "2:prim算法" << endl;
        cin >> b;

        switch (b)
        {
        case 1:CreateMap(s, n); break;
        case 2:PrimeMap(s, n); break;
        }
        cin.ignore();

        picture_one(s, n);
        Stack *Q = Pathfinding(s, n);
        picture_two(Q, n);
        delete s;
        DestroyStack(Q);
        return 0;
}

wangqiustc 发表于 2019-1-1 17:07

估计要学一个星期

peng_11718 发表于 2019-11-17 15:10

提醒下,我看了作者的代码,作者的在生成地图上下左右那一块是反的,大家注意
我贴出相关代码,因为这一点我都有点看不懂代码了

61行   struct BBS
{
        /*int right = 0;
        int upside = 1;
        int left = 2;
        int below = 3;*/

        int right = 3;
        int upside = 2;
        int left = 1;
        int below = 0;
   };
213行   enum Direction { below,left,upside,right};    //方向
                //生成迷宫算法
        239行        switch (b)//在设置成挖掘过的路方向b进行挖掘2个方块操作
                {
                        //下方向0
                case below:
                        if ((TopStack(ABS) + 2) % n != 0)
                        {
                                if (map.Judgment == 1)
                                {
                                        map.Judgment = 0;
                                        map.Judgment = 0;
                                        PushStack(ABS, TopStack(ABS) + 2);
                                        BB(Q);
                                        break;
                                }
                                else
                                        break;
                        }
                        else
                                break;
                        //左方向1
                case left:
                        if (TopStack(ABS) - 2 * n > 0)
                        {
                                if (map.Judgment == 1)
                                {
                                        map.Judgment = 0;
                                        map.Judgment = 0;
                                        PushStack(ABS, TopStack(ABS) - 2 * n);
                                        BB(Q);
                                        break;
                                }
                                else
                                        break;
                        }
                        else
                                break;
                        //上方向2
                case upside:
                        if ((TopStack(ABS) - 1) % n != 0)
                        {
                                if (map.Judgment == 1)
                                {
                                        map.Judgment = 0;
                                        map.Judgment = 0;
                                        PushStack(ABS, TopStack(ABS) - 2);
                                        BB(Q);
                                        break;
                                }
                                else
                                        break;
                        }
                        else
                                break;
                        //右方向3
                case right:
                        if (TopStack(ABS) + 2 * n < n * n - 1)
                        {
                                if (map.Judgment == 1)
                                {
                                        map.Judgment = 0;
                                        map.Judgment = 0;
                                        PushStack(ABS, TopStack(ABS) + 2 * n);
                                        BB(Q);
                                        break;
                                }
                                else
                                        break;
                        }
                        else
                                break;
                }

裴冰夏 发表于 2019-1-1 16:39

可以可以学习

a48602 发表于 2019-1-1 17:27

以前就有能生成迷宫這個想法,這個值得學習,收下來慢慢研究看看,謝謝樓主的分享。

山河一号 发表于 2019-1-2 19:03

感谢分享

msccreater 发表于 2019-1-4 10:36

看到这种技术帖子热血沸腾,就是有点看不懂,保存下来慢慢学习

河北网友 发表于 2019-1-4 17:42


感谢分享

yourwit 发表于 2019-4-1 22:18

谢了楼主,

yourwit 发表于 2019-4-1 22:25

那我分享下easyX
http://t.cn/EiMrAXC
页: [1] 2
查看完整版本: 【C++】生成迷宫的图的深度优先算法和prim算法,还有寻路算法