怪蛋迷宫的实现算法

目录

Prim树生成迷宫

BFS寻找最佳路径


Prim树生成迷宫

算法思想:

        1. 首先生成一个20*20的网格,is_road[20][20]=0。

        2. 初始化起点is_road[1][1]=1,使其加入一个集合。

        3. 找集合中点周围的墙(非边界墙),选择其中任意一个判断墙两边的两个路径点是否都属于集合,若不是则打破此墙,使新路径点加入集合。

        4. 重复上述操作,直至终点和起点在一个集合中。

算法实现:

  1. 初始化is_road[20][20]=0,起点初始化is_road[1][1]=1。
  2. 重复上述操作,直至终点也在集合中。
  3. 遍历起点is_road[1][1]的四周,若是全是墙则把该点置为1,并加入集合。
void Widget::initFirst(){
    srand((unsigned)time(0));
    for(int i=0;i<row;i++){
        for(int j=0;j<col;j++){
            isroad[i][j]=0;
            block[i][j]=new Block;
            block[i][j]->label=new QLabel(this);
            block[i][j]->label->setGeometry(i*40,j*40,40,40);
            block[i][j]->label->setStyleSheet("border-image:url(:/res/wall.png)");
            block[i][j]->label->lower();
            block[i][j]->label->show();
        }
    }
    for(int i=0;i<row;i++){
        isroad[i][0]=0;
        isroad[0][i]=0;
        isroad[row-1][i]=0;
        isroad[i][row-1]=0;
    }
    pathX.push_back(1);
    pathY.push_back(1);

    while(pathX.size()){
        int r=rand()%pathX.size();
        int x=pathX[r];
        int y=pathY[r];

        int count=0;
        for(int i=x-1;i<x+2;i++){
            for(int j=y-1;j<y+2;j++){
                if(abs(x-i)+abs(y-j)==1&&isroad[i][j]>0&&i>=1&&i<row-1&&j>=1&&j<col-1)
                    count++;
            }
        }
        if(count<=1){
            isroad[x][y]=1;
            for(int i=x-1;i<x+2;i++){
                for(int j=y-1;j<y+2;j++){
                    if(abs(x-i)+abs(y-j)==1&&isroad[i][j]==0&&i>=1&&i<row-1&&j>=1&&j<col-1){
                        pathX.push_back(i);
                        pathY.push_back(j);
                    }
                }
            }
        }
        pathX.erase(pathX.begin()+r);
        pathY.erase(pathY.begin()+r);
    }
    //设置进出口
    for(int i=row-1;i>0;i--){
        if(isroad[i][row-2]==1){
            block[i][row-1]->label->setStyleSheet("border-image:url(:/res/end.png)");
            break;
        }
    }
    for(int i=0;i<row;i++){
        for(int j=0;j<row;j++){
            if(isroad[i][j]==1){
                block[i][j]->label->setStyleSheet("border-image:url(:/res/road.png)");
            }
        }
    }
    for(int i=row-1;i>0;i--){
        if(isroad[i][row-2]==1){
             isroad[i][row-1]=1;
             trow=i;
            break;
        }
    }
}

BFS寻找最佳路径

算法思想:

以起点为一开始的点,依次遍历距离起点只有一格的点,并观察是否为路,如果为路即将这个点加入队列,反之则停止,直至到达终点,则队列中的点就是最佳路径。

举例说明:

从黑色起点出发,记录所有的岔路口,并标记为走一步可以到达的。然后选择其中一个方向走进去,走黑点方块上面的那个,然后将这个路口可走的方向记录下来并标记为2,意味走两步可以到达的地方。

接下来,回到黑色方块右手边的1方块上,并将它能走的方向也记录下来,同样标记为2,因为也是走两步便可到达的地方。

这样走一步以及走两步可以到达的地方都搜索完毕了,下面同理,可以迅速把三步的格子给标记出来。

依次重复上述操作,得到的最后结果为

void Widget::BFS(){

   int dx[4]={-1,0,1,0},dy[4]={0,-1,0,1};
   QPair<int,int> ischeck[row][col];
   memset(ischeck,-1,sizeof(ischeck));
   QPair<int, int> q[row * col];
   int hh = 0, tt = 0;
   q[tt] = {people->x,people->y};
   ischeck[people->x][people->y]={-2,-2};
   while(hh <= tt){
       auto t=q[hh++];
       for(int i=0;i<4;i++){
           int tx=t.first+dx[i],ty=t.second+dy[i];
           if(tx>=0&&tx<row&&ty>=0&&ty<col&&isroad[tx][ty]==1&&ischeck[tx][ty].first==-1){
               q[++tt] = {tx,ty};
               ischeck[tx][ty]={t.first,t.second};
               if(tx==trow&&ty==col-1){
                   s.push({trow,col-1});
                   while(ischeck[tx][ty].first!=-2){
                       s.push(ischeck[tx][ty]);
                       int pp=tx;
                       tx=ischeck[tx][ty].first;
                       ty=ischeck[pp][ty].second;
                   }

                   return;
               }
           }
       }
   }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值