在具有负坐标的三角形/六边形网格上实现 A*

本文关键字:网格 六边形 实现 三角形 坐标 | 更新日期: 2023-09-27 17:55:20

遵循使用这个问题作为新问题基础的明显传统,我也有一个问题,我希望尽可能优雅地解决:

我已经实现了这样的六边形地图:

(想在这里插入图像..但由于我是新的,所以我不被允许...请看上面的链接)

但是我现在想知道如何(优雅地)使用这些类型的坐标为这种类型的地图实现 A*。我有在典型的平方网格(我认为是笛卡尔网格?)上使用 A* 的经验,我在那里处理它的方式似乎与这个坐标系不兼容。

通常我会生成一个 2D 字节数组。数组的索引将对应于网格坐标,并且该索引处的值将给出该节点的"权重"。(0 表示无法通过,较高的数字"权重"大于较低的数字)。

例: sbyte[,] pathGrid = new sbyte[5, 5] { {0,0,1,0,0}, {9,5,1,3,0}, {9,5,1,3,0}, {9,5,1,3,0}, {0,0,1,0,0} };

在 0 无法通行的地方,1 很容易遍历,而更高的数字将"花费"更多来遍历。(对格式感到抱歉..我是堆栈溢出新手:P)这个数组将根据我的地图的组成生成,然后输入到我的路径查找算法中,该算法反过来会吐出节点列表(路径)或如果未找到路径则返回 null。

但是,使用这种类型的网格,这是不可能的(至少乍一看),因为负坐标(显然在数组中不起作用)以及网格不遵循与"典型"网格相同的规则。

我认为有一些方法可以使用我的 A* 方法解决此问题,但它们都相当草率(转换网格坐标和使用空节点),我想知道是否有人想过一种优雅地做到这一点的方法。

无论如何,感谢您的阅读:)(顺便说一句,我在 C#/.net 中这样做是为了它的价值)

在具有负坐标的三角形/六边形网格上实现 A*

即使数组的索引从 0 开始,您的程序也不需要在概念上以这种方式处理数组。例如,如果你总是在使用它们在数组中查找之前将例如 3 添加到索引中,那么您实际上拥有一个索引从 3 开始的数组。为了简化以这种方式使用数组,您可以创建一个名为 例如 ArbitraryBaseArray包装数组和指定所需基索引的数字。

然后,您可以创建一个包含 ArbitraryBaseArray 数组的 HexGrid 类,每个数组都有自己的基索引(取决于十六进制区域的左边缘的外观)。该类可以有一个索引器,允许您根据两个十六进制坐标查找特定元素。它也可以有一个静态方法,该方法在十六进制网格中给定一个坐标,返回一个具有六个相邻坐标的数组;此方法可由 A* 使用。(请注意,虽然您链接到的问题中的插图对每个十六进制磁贴使用三个坐标,但两个坐标就足够了。

您可以将坐标存储在字典中:

var nodes = new Dictionary<Point, Vector[]>;

这样,您就不会局限于正坐标,也不会限制每个节点的路径数量