我已经实现了一个随机游走算法来生成类似地下城的迷宫。该算法具有多个“步行者”,每个“步行者”随机地贡献于相同的迷宫。您可以通过转到此网址了解算法的工作原理:https://thomaskerbrat.github.io/procedural-maze/ (如果动画过快,请重新加载页面以获得新的迷宫。)
迷宫逐步生成并每次渲染。红色方块表示每个步行者在地图中前进。
在这个实现中,我有一个固定大小数组,表示游戏的图块(地板,墙壁或没有)。默认情况下,网格为64 x 64。
当算法到达边缘时,我无法超越并且助行器停止生成路径。
我的问题是:有没有办法用不受初始尺寸限制的东西替换固定大小的数组?
问题在于我想执行查找以了解相邻单元格的内容。这可以通过固定大小的数组轻松完成,我只需访问适当的索引(事先检查它们是否超过网格大小)。但我没有在网上找到解决方案。
到目前为止,我想出了一个我想要放在网格中的元素列表,并为查找保留了一个双哈希映射。
考虑在10x10网格中具有以下坐标的点列表:
相应的哈希映射会将X和Y坐标映射到内存中的对象:
为了查看相邻单元格是否存在或检查其内容,我检查哈希图是否将X坐标作为键(指向其他哈希图),如果是,我会做同样的事情最终找到一个单元格的Y坐标的东西。
那么,您怎么看?您是否了解某种“标准”方法,或者至少是众所周知的方法?
答案 0 :(得分:2)
一种方法不是使用数组,而是使用一组坐标来记录所有被访问的位置,计算步行的范围,并在步行后将其映射到适当大小的网格:
该解决方案随机走动一个步行者,不受步行范围的限制,然后构建一个自动调整到数据大小的数据结构;它使用有序序列和索引。
1-在位置(0,0)开始你的助行器,一个元组,并将其插入到集合中
走路步行者:
2-1-为步进器的每个方向创建一个新的坐标元组,其新位置行+/- 1和/或列+/- 1。
2-2-通过在每一步中将其插入集中来记录这个新位置
3-继续走,直到完成。
4-从行走位置生成网格:
4-1-找到最小和最大行和列以确定跨度
4-3-为行和列创建一个大小为max-min的网格
4-4-通过将步行的坐标更改为网格的坐标来填充访问位置。
如果您需要按顺序执行这些步骤,则可以使用有序集或地图。 如果可以多次访问位置,则可以使用序列(数组,列表...),或者如果需要跟踪访问顺序,则可以使用映射到一系列时间步骤。
实现(python)可能如下所示:
"""
a 2D grid that auto adjusts its size to the data.
coordinates are tuples of integers in the range -1e9 <-> 1e9
"""
class SpanGrid:
def __init__(self, coordinates):
self.coordinates = coordinates
self.grid = None
self.rows = None
self.columns = None
self.make_grid()
def make_grid(self):
self._find_num_rows_columns()
self._populate_grid()
def _find_num_rows_columns(self):
self.minrow, self.mincol = 1e9, 1e9
self.maxrow, self.maxcol = -1e9, -1e9
for row, col in self.coordinates:
self.minrow = row if row < self.minrow else self.minrow
self.mincol = col if col < self.mincol else self.mincol
self.maxrow = row if row > self.maxrow else self.maxrow
self.maxcol = col if col > self.maxcol else self.maxcol
self.rows = self.maxrow - self.minrow + 1
self.columns = self.maxcol - self.mincol + 1
def _populate_grid(self):
self.grid = [[None for dummycol in range(self.columns)]
for dummyrow in range(self.rows)]
for r, c in self.coordinates:
self.grid[r - self.minrow][c - self.mincol] = True
def __str__(self):
result = []
for line in self.grid:
res = ''
for pos in line:
res += str(pos) if pos else ' - '
res += ' '
result.append(res)
return '\n'.join(result)
if __name__ == '__main__':
import random
visited = set()
offsets = ((1, 0), (-1, 0), (0, 1), (0, -1))
start = (0, 0)
current = start
visited.add(current)
for _ in range(100):
cur_row, cur_col = current
row_offset, col_offset = random.choice(offsets)
current = (cur_row + row_offset, cur_col + col_offset)
visited.add(current)
grid = SpanGrid(visited)
print(grid)
- True True True True True True -
- True True True True True True True
- True True True True True True -
True True True True True True - -
True True True True True True - -
- True True True True - - -
- True - - - - - -
============================================================================
- - - - - - - - - True - -
- - - - - - - - True True True -
- - - - - True True - True True True True
True True True True True True True - True True True True
- True True True True True True True True True True -
- - - True True True True True - - - -
============================================================================
- - - - - - - True True True True - - - - - - - - -
- - - - - - - True - - True True True - - True True - - -
- - - - - - - True True - True True True - True True True - - -
- - - - - - - True True True True True True True True True - - - -
- True True - - - - - True - True True True - - True True - - -
True True True True - - - - True - - True True - - True True True - -
True True True True - - True True True - - - True - - - True True - -
- - - True True True True - - - - - - - - True True - - -
- - - - - - - - - - - - - - - - True True True True
- - - - - - - - - - - - - - - - - - - True
- - - - - - - - - - - - - - - - - - True True
- - - - - - - - - - - - - - - - - - - True