目录
Prim树生成迷宫
算法思想:
1. 首先生成一个20*20的网格,is_road[20][20]=0。
2. 初始化起点is_road[1][1]=1,使其加入一个集合。
3. 找集合中点周围的墙(非边界墙),选择其中任意一个判断墙两边的两个路径点是否都属于集合,若不是则打破此墙,使新路径点加入集合。
4. 重复上述操作,直至终点和起点在一个集合中。
算法实现:
- 初始化is_road[20][20]=0,起点初始化is_road[1][1]=1。
- 重复上述操作,直至终点也在集合中。
- 遍历起点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;
}
}
}
}
}