迷宫生成-递归除法(它是如何工作的?)
Maze generation - recursive division (how it works?)
我想学习如何生成完美的迷宫。我正在努力理解递归除法算法。我不明白如何实现这个算法。这是我的代码:
bool maze[20][20];
void initMaze()
{
for(int i = 0; i < 20; i++)
for(int j = 0; j < 20; j++)
maze[i][j] = false;
for(int i = 0; i < 20; i++)
maze[0][i] = true;
for(int i = 0; i < 20; i++)
maze[19][i] = true;
for(int i = 0; i < 20; i++)
maze[i][0] = true;
for(int i = 0; i < 20; i++)
maze[i][19] = true;
}
int randNum(int min, int max)
{
return rand()%(max-min+1)+min;
}
void drawVWall(int minY, int maxY, int x)
{
int passage = randNum(minY, maxY);
for(int i = minY; i <= maxY; i++)
if(i != passage)
maze[i][x] = true;
}
void drawHWall(int minX, int maxX, int y)
{
int passage = randNum(minX, maxX);
for(int i = minX; i <= maxX; i++)
if(i != passage)
maze[y][i] = true;
}
void divison(int x, int y, int maxx, int maxy, int h)
{
if(h)
{
if(maxx <= 2)
return;
int wallY = randNum(y, maxy);
drawHWall(x, maxx, wallY);
if(wallY < maxy - wallY)
divison(x, wallY, maxx, maxy, !h);
else if(wallY > maxy - wallY)
divison(x, y, maxx, wallY, !h);
}
else
{
if(maxy <= 2)
return;
int wallX = randNum(x, maxx);
drawVWall(y, maxy, wallX);
if(wallX < maxx - wallX)
divison(wallX, y, maxx, maxy, !h);
else if(wallX > maxx - wallX)
divison(x, y, wallX, maxy, !h);
}
}
initMaze();
divison(2, 2, 18, 18, true);
这段代码有问题,因为它经常冻结程序(某个地方的无限循环),但如果它有效,它会生成这样的"迷宫":生成的"迷宫">
我不想问你我的代码。我只想了解如何实现这个算法,我错在哪里,我应该做什么。我需要生成一个没有封闭区域的完美迷宫。
首先,您必须决定如何设计迷宫。使用整个单元格来表示墙或通道。这意味着你对选择作为新墙和通道的数字有一些限制。在您的示例中,不应该创建厚墙,其中两个垂直墙相邻,它们之间没有通道。
用你的方法,一个N
×CCD_ 2迷宫由CCD_;(2*N + 1)
。"迷宫"坐标从0到N
,"栅格"坐标从零到2*N + 1
。在迷宫坐标中执行算法,并在创建墙时使用栅格坐标。
在网格坐标中,墙必须在偶数索引处,畜栏必须在奇数索引处。两个指数偶数总是最后迷宫中的一堵墙,两个指数奇数总是一个自由细胞。一个偶数一个奇数意味着可能穿过一堵墙。
举例来说,这里有a4×4迷宫:
X 0 1 2 3
x 0 1 2 3 4 5 6 7 8
# # # # # # # # # 0
# + + + # 1 0
# + # + # + # # # 2
# + + + # 3 1
# + # + # + # # # 4
# + + + # 5 2
# + # + # + # # # 6
# + + + # 7 3
# # # # # # # # # 8
y Y
小写字母(x
、y
)为网格坐标;大写字母(X
、Y
)是迷宫坐标。散列标记#
总是墙,但加号+
最终要么是通道,要么是墙。
第二个问题是递归本身。建造墙后,已将活动空间细分为两个区域。现在必须将算法应用于两个新区域。
所以不是:
if (wallY < maxy - wallY)
divison(x, wallY, maxx, maxy, !h);
else if (wallY > maxy - wallY)
divison(x, y, maxx, wallY, !h);
你应该这样做:
divison(x, wallY, maxx, maxy, !h);
divison(x, y, maxx, wallY, !h);
当然,你必须有一个条件来停止递归,但你已经有了:当空间太小时,你不会再建造更多的墙。
你的例子中的大房间表明你只进入了迷宫的一个新的部分。那些大房间是你不会经常去的。
相关文章:
- QSqlquery prepare()和bindvalue()不工作
- 导入库可以跨dll版本工作吗
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- C++为线程工作动态地分割例程
- 为什么我的 std::ref 无法按预期工作?
- 布尔比较运算符是如何在C++中工作的
- SampleConsensusPrerejective(ext.RANSAC)是如何真正工作的
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- <<操作员在下面的行中工作
- 有人能解释一下为什么下界是这样工作的吗C++的
- ExtractIconEx:可以工作,但偶尔会崩溃
- C++中的memset函数工作不正常
- 当我在第一个循环中使用"auto"时,它工作正常,但是使用"int"它会给出错误,为什么?
- 链表c++插入,所有情况都已检查,但没有任何工作
- 当 int 方法工作正常时,void 方法有何不同,或者为什么我不能调用 void 方法?