我有一个基于回溯迷宫算法的算法,删除了一些部分,从而形成了这个美妙的地牢。不幸的是,它运行非常慢这使得几乎不可能填充一个体面大小的地图。我真的不想把它扔出去,但我无法想出任何加速它的方法。我使用的是Python,所以我知道这是我的问题的一部分,但我并没有准备好抛弃我的roguelike现有的整个代码库,它现在运行得足够快。这是目前的代码:
start = (random.randint(0, self.width), random.randint(0, self.height))
self.dungeon['up_stairs'] = start
visited = [start]
while len(visited) < 300:
current = visited[-1]
apos = random.choice([(1, 0), (0, 1), (0, -1), (-1, 0)])
new = utils.tuple_add(current, apos)
if not new in visited and self.on_map(new):
self.place_cell(new, is_wall=False)
visited.append(new)
else:
visited.pop()
[编辑]
self.place_cell(new, is_wall=False)
调用会将地图上新位置的单元格更改为空单元格。< 300
条件是因为299个单元格在合理的时间范围内可以绘制得最多。 (超过299个细胞,它突然开始悬挂。)答案 0 :(得分:2)
我建议进行以下改进:
不要仅因为您在一步失败而弹出被访问的单元格。这可能导致饥饿:弹出并再次尝试,弹出......等等。您应该选择过去访问过的另一个单元格,并从那里继续。如果失败,请选择另一个......
使用set
跟踪已访问的单元格:这样可以更快地查找
使用另一个&#34;边境&#34; set
用于跟踪哪些访问过的单元格仍有未访问的邻居
访问单元格时,以随机顺序检查所有邻居是否未访问。第一个将是您的下一次访问。但如果所有这些都被访问过(或在网格外),那么从边界集中选择一个随机单元格。
以下是建议的代码:
start = (random.randint(0, self.width-1), random.randint(0, self.height-1))
self.dungeon['up_stairs'] = start
current = start
frontier = set()
visited = set([start])
while len(visited) < 400:
frontier.add(current)
self.place_cell(current, is_wall=False)
found = False
while not found:
choices = [(1, 0), (0, 1), (0, -1), (-1, 0)]
random.shuffle(choices)
for apos in choices:
new = utils.tuple_add(current, apos)
if not new in visited and self.on_map(new):
found = True
break
if not found:
# we can remove this cell from frontier as it is
# completely surrounded by visited cells
frontier.discard(current)
# pick a random other one to start from
current = random.sample(frontier, 1)[0]
current = new
visited.add(current)