如何在带有加权六边形的六边形平铺中检查十六进制范围

问题

假设我有一个(无限的)六边形平铺。从一个六边形开始,我可以移动到所有相邻的六边形,但对于某些“空心”的六边形则不行。有些六边形的权重为1,而其他六边形的权重则为2。最大权重为x,如何获得所有从起始六边形开始且累积权重低于x的六边形?

背景

我正试图为游戏文明5创建一个mod。在这个mod中,我需要获取单位在10回合内可以到达的所有平铺集合,同时还需要知道这个单位每回合只能移动1个机动点,并且除了道路以外的所有地形都需要消耗1个机动点(道路消耗0.5个)。山地和海洋地形是无法到达的。 简而言之,这是一个选择的单位周围区域的扩展版本,显示所有在单位1次移动距离范围内的平铺。

当前测试

目前为止,我尝试过2种解决方案,但似乎都不太有效。我的尝试大多都无法确定要检查哪些平铺(可能是因为它们还没有被检查,或者因为它们还没有被检查过以找到最短路径),最终导致检查了范围内的多个平铺多次,并拒绝了几个看起来在范围内的平铺,但实际上因为从比必要的路径更长的路径上检查,它们被认为太远了。 包括以下两种解决方案:

  • 第一种方法非常简单,递归检查起始平铺周围的每个平铺,并删除所有累计权重超过x的平铺。
  • 对于第二种解决方案,我保留了相同的结构,但添加了一个条件过滤,即如果从原点到达平铺的距离低于计算到达该平铺的累积权重,则不应拒绝该平铺(因为不同累计权重的多个路径可以导致相同的平铺)。但是很多情况下这个断言是错误的。

我真的需要一些关于如何做到这一点的建议。

谢谢, Méta

点赞
用户5483526
用户5483526

你应该使用 Dijkstra 算法来寻找到附近方块的最短路径。由于 Dijkstra 算法按照路径长度递增的顺序寻找最短路径,当你找到的最短路径长度大于 x 时,你可以停止搜索。

参见https://en.wikipedia.org/wiki/Dijkstra_%27s_algorithm

2018-12-23 02:35:35
用户1847592
用户1847592

你不需要使用 Dijkstra 算法。

简单的“扩散”算法就足够了。

需要一个数组 dist 用于存储场地上每个六边形的数值(距离)。

还需要另一个数组 wave 用于存储最近刷新的六边形列表。

伪代码:

变量 x = 10 -- 移动点数
循环遍历场地上的每一个六边形
    dist[六边形] = 正无穷
end-loop
dist[单位六边形] = 0
wave = 空数组
将单位六边形添加到数组 wave
while array wave is not empty 循环直至 wave 数组为空
    create new empty array new_wave
    for each hexagon in array wave 循环遍历 wave 数组中的每一个六边形
        for each of 6 adjacent hexagons of hexagon 循环遍历六边形的 6 个相邻六边形
            if adjacent_hexagon is accessible (not a mountain) 相邻六边形是可行的(不是山地)
                variable adj_dist = dist[hexagon] + price(adjacent_hexagon) 距离adj_dist等于六边形的距离dist加上相邻六边形的价格
                -- 其中price=0.5表示道路,其他单元格价格为1。
                if (adj_dist < dist[adjacent_hexagon]) and (adj_dist < x) then 如果adj_dist小于相邻六边形的距离,且小于移动点数x时
                    dist[adjacent_hexagon] = adj_dist
                    将相邻六边形添加到 new_wave 数组中
                end-if
            end-if
        end-loop
    end-loop
    wave = empty array
    将 new_wave 数组中的所有元素复制到 wave 数组中
end-loop
循环遍历场地上的每一个六边形
    if dist[hexagon] < +infinity then 如果六边形的距离dist小于正无穷
        那么这个六边形在单位周围的带色区域内
    end-if
end-loop
2018-12-23 07:57:38