迷宫生成算法(二)(C++)

        二、最小生成树算法之Prim算法

        数据结构中的Prim算法是先将一个顶点加入集合,寻找与其最近的顶点加入集合,然后依次寻找与这两个顶点中最近的顶点加入集合,以此类推直到所有顶点都被访问到。

        由于迷宫中所有边的权都相同,且生成迷宫需要随机性,所以寻找最近顶点这一步就变为:        

        随机选取集合中某一顶点,检索其相邻顶点是否被访问过,如果全部被访问过,将这个顶点移除集合,如果尚存在未被访问过的顶点,就随机选择其中一个并连接它们。

        最终形成的迷宫如图

 由于准备阶段在上一篇文章中已阐述过,本篇只列出算法函数

void Prim()
{
	int x = 0, y = 0;
	vector<Map*>rode;//使用向量容器作为集合
	rode.push_back(start);//start作为根
	map[x][y]->val = 1;//标记访问过的顶点

	while (!rode.empty())
	{
		Sleep(0);
		int select = rand() % rode.size();//从集合中随机选取一个顶点
		x = rode[select]->x;
		y = rode[select]->y;
		int v = visit(x, y);
		if (v == 0)
		{
			rode.erase(rode.begin()+select);//如果该顶点的相邻顶点全部被访问过,移除它
		}
		else
		{//以下代码为从可访问的顶点中随机选取一个
			vector<int>put;
			if (v % 10 == 1)
				put.push_back(UP);
			if (v % 100 >= 10)
				put.push_back(DOWN);
			if (v % 1000 >= 100)
				put.push_back(LEFT);
			if (v >= 1000)
				put.push_back(RIGHT);

			int choose = rand() % put.size();
            //以下代码把要移除的墙涂白
			if (put[choose] == UP)
			{
				solidrectangle(x*(RODE + WALL) - RODE / 2, y*(RODE + WALL) - RODE / 2 - WALL, x*(RODE + WALL) + RODE / 2, y*(RODE + WALL) - RODE / 2);
				y--;
			}
			else if (put[choose] == DOWN)
			{
				solidrectangle(x*(RODE + WALL) - RODE / 2, y*(RODE + WALL) + RODE / 2, x*(RODE + WALL) + RODE / 2, y*(RODE + WALL) + RODE / 2 + WALL);
				y++;
			}
			else if (put[choose] == LEFT)
			{
				solidrectangle(x*(RODE + WALL) - RODE / 2 - WALL, y*(RODE + WALL) - RODE / 2, x*(RODE + WALL) - RODE / 2, y*(RODE + WALL) + RODE / 2);
				x--;
			}
			else if (put[choose] == RIGHT)
			{
				solidrectangle(x*(RODE + WALL) + RODE / 2, y*(RODE + WALL) - RODE / 2, x*(RODE + WALL) + RODE / 2 + WALL, y*(RODE + WALL) + RODE / 2);
				x++;
			}
            //将它们互相加入对方的相连顶点集合中
			rode[select]->push(map[x][y]);
			map[x][y]->push(rode[select]);
            //把新顶点加入集合
			rode.push_back(map[x][y]);
			map[x][y]->val = 1;
		}
	}
}

可以看到最后寻到的路并不曲折

 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值