随机迷宫生成算法——prime算法

本以为Prime迷宫生成算法和图论的Prime算法有什么关联,貌似并没有。

Prime迷宫生成算法的原理:

(1)初始地图所有位置均设为墙

(2)任意插入一个墙体进墙队列

(3)判断此时墙体是否可以设置为路(判断依据在于上下左右四个位置是否只有一个位置是路)

(4)若设置为路,则将该位置周围(上下左右)的所有插入队列,接着执行(5);若无法设置为路,直接执行(5)

(5)从墙队列中删去当前位置所在节点

(6)若墙队列不为空,则从队列中随机选取一面墙重新执行(3),直到墙队列为空

看代码,非常简单:

static const int L = 44;

void CreateMaze() {
	int Maze[L][L] = { 0 };

	//最外围设置为路,可以有效的保护里面一层墙体,并防止挖出界
	for (int i = 0; i < L; i++) {
		Maze[i][0] = 1;
		Maze[0][i] = 1;
		Maze[L - 1][i] = 1;
		Maze[i][L - 1] = 1;
	}

	//墙队列,包括X , Y
	vector<int> X;
	vector<int> Y;

	//任取初始值
	X.push_back(2);
	Y.push_back(2);

	//当墙队列为空时结束循环
	while (X.size()) {
		//在墙队列中随机取一点
		int r = rand() % X.size();
		int x = X[r];
		int y = Y[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 && Maze[i][j] > 0) {
					++count;
				}
			}
		}

		if (count <= 1) {
			Maze[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 && Maze[i][j] == 0) {
						X.push_back(i);
						Y.push_back(j);
					}
				}
			}
		}

		//删除当前墙
		X.erase(X.begin() + r);
		Y.erase(Y.begin() + r);
	}

	//设置迷宫进出口
	Maze[2][1] = 1;
	for (int i = L - 3; i >= 0; i--) {
		if (Maze[i][L - 3] == 1) {
			Maze[i][L - 2] = 1;
			break;
		}
	}

	//画迷宫
	for (int i = 0; i < L; i++){
		for (int j = 0; j < L; j++) {
			if (Maze[i][j] == 1) printf("  ");
			else printf("国");
		}
		printf("\n");
	}
}

代码要简单不少,但是个人觉得效果还不如深度优先迷宫算法,但是不得不承认prime迷宫赛诺菲生成的迷宫更让人眼花缭乱。

附:

一、回答 abs(x - i) + abs(y - j) == 1 看不懂的问题。

已知此时所在位置(x,y),我需要通过上下左右四个方向所在位置的状态来判断是否需要打通(x,y)位置的墙壁。

上下左右意味着(x-1,y);(x+1,y);(x,y-1);(x,y+1),意味着 abs(x - i) + abs(y - j) == 1

发布了63 篇原创文章 · 获赞 73 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/jjwwwww/article/details/82891213