坐标系有替代固定大小的数组吗?

时间:2018-06-18 22:49:40

标签: algorithm coordinates

情况

我已经实现了一个随机游走算法来生成类似地下城的迷宫。该算法具有多个“步行者”,每个“步行者”随机地贡献于相同的迷宫。您可以通过转到此网址了解算法的工作原理:https://thomaskerbrat.github.io/procedural-maze/ (如果动画过快,请重新加载页面以获得新的迷宫。)

迷宫逐步生成并每次渲染。红色方块表示每个步行者在地图中前进。

在这个实现中,我有一个固定大小数组,表示游戏的图块(地板,墙壁或没有)。默认情况下,网格为64 x 64。

问题

当算法到达边缘时,我无法超越并且助行器停止生成路径。

我的问题是:有没有办法用不受初始尺寸限制的东西替换固定大小的数组?

问题在于我想执行查找以了解相邻单元格的内容。这可以通过固定大小的数组轻松完成,我只需访问适当的索引(事先检查它们是否超过网格大小)。但我没有在网上找到解决方案。

我提出的解决方案的例子

到目前为止,我想出了一个我想要放在网格中的元素列表,并为查找保留了一个双哈希映射。

考虑在10x10网格中具有以下坐标的点列表:

  • A(4,5)
  • B(8,2)
  • C(4,2)
  • D(8,5)
  • E(3,7)
  • F(3,2)

相应的哈希映射会将X和Y坐标映射到内存中的对象:

  • 3
    • 2 - > ˚F
    • 7 - > ë
  • 4
    • 2 - > ç
    • 5 - > A
  • 8
    • 2 - >乙
    • 5 - > d

为了查看相邻单元格是否存在或检查其内容,我检查哈希图是否将X坐标作为键(指向其他哈希图),如果是,我会做同样的事情最终找到一个单元格的Y坐标的东西。

那么,您怎么看?您是否了解某种“标准”方法,或者至少是众所周知的方法?

1 个答案:

答案 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