【问题标题】:How to implement BFS for hexagon field (in javascript)如何为六边形字段实现 BFS(在 javascript 中)
【发布时间】:2011-07-25 12:50:01
【问题描述】:

我从事基于六边形地图的浏览器游戏。我有这个:http://www.dark-project.cz/wesnoth/map-view/1 现在我有一个问题,我想标记该单元可以进入的字段(它的移动受限)。 如果运动为 1,则没有任何问题,但如果运动更高,则无法正常工作(尝试一下)。

我使用坐标系http://www.dark-project.cz/wesnoth/coor.png

我的实际js在这里:http://www.dark-project.cz/wesnoth/js/map/base.js

在其他问题(Movement algorithm on a hexagon map)@unkulunkulu 建议我使用 BFS 算法。但是我没有像这样的算法及其在javascript中的实现以及在六边形地图上的使用经验。他说 B​​FS 算法对此更好,因为我以后可以轻松扩展它(添加一些障碍等)。

如果你有一些关于这个或类似内容的 javascript 教程的链接,那就太棒了。

【问题讨论】:

  • 我想知道从数学的角度来看,这是否是最好的坐标系。 i 的曲折在一定程度上会混淆事物,让 i 在直线对角线上增加(即向下和向右总是 +1 到 i)不会。但是,当您使用此坐标系查看地图时,可能会不太直观...

标签: javascript jquery


【解决方案1】:

建议的算法大致是这样的:

  1. 取起始方格并将其标记为距离 0。将其添加到已处理的十六进制列表中。

  2. 找到所有有效的相邻格子(即您可以移动的格子)。

  3. 将所有这些正方形标记为距离 1。将它们添加到已处理的十六进制列表中。

  4. 找到所有与距离为 1 的 hexes 相邻且不在已处理的 hexes 列表中的有效 hexes。

  5. 将所有这些正方形标记为距离 2。将它们添加到已处理的十六进制列表中。

...

X。查找距离 N hexes 相邻且不在已处理的 hexes 列表中的所有有效 hexes。

X+1。将所有这些正方形标记为距离 N+1。将它们添加到已处理的十六进制列表中。

广度优先搜索的想法是,您从内部迭代所有可能性,因此您将始终找到到每个十六进制的最短距离。

在来自 Unkulunkulu 的 cmets 之后,我重新考虑了最好的实现方式(并且可能会在进一步输入后再次更改)。您应该有一个如上所述的已处理十六进制列表,还有一个等待处理的十六进制队列。未处理的十六进制列表仅从距离为 0 的起始十六进制开始,您将遍历此列表,直到用完为止。当处理一个十六进制时,所有新发现的未处理的十六进制都被添加到这个列表中,它们的距离在里面。所以一旦你处理了距离为 0 的十六进制,你应该添加了所有距离为 1 的十六进制。他们得到处理,当他们完成时,你将在那里拥有所有距离 2 的六角形......

对于它的价值,我认为我最初的递归建议从效率的角度来看是失败的,并且取决于你想要解决潜在堆栈溢出问题的距离。 :)

【讨论】:

  • 最后一段有严重缺陷,你应该删除它或完全重写。我从来没有遇到过递归实现的 BFS。
  • @unkulunkulu:我以前从来没有真正玩过 BFS 的东西,所以我上面写的可能不是一个完美的描述。我认为我重写它的方式更好,但我非常乐意接受有关正确执行此操作的建议并酌情进行更改...如果您想用信息输入另一个答案,我非常高兴也赞成它教我更多的东西。 :)
【解决方案2】:

首先,你只需要想办法从当前六边形(i,j)——你图片中的(4,3)中得到相邻的六边形。

一旦您意识到您只需要根据当前列是偶数还是奇数来涵盖两种情况,这并不难:

如果 j 是奇数 (j%2 == 1),则邻居是,从顶部顺时针方向:

(i-1, j), (i-1, j+1), (i, j+), (i+1, j), (i, j-1), (i-1, j-1)

如果 j 是偶数 (j%2 == 0),则邻居是,从顶部顺时针方向:

(i-1, j), (i, j+1), (i+1, j+), (i+1, j), (i+1, j-1), (i, j-1)

(请注意,您不能使用 (,) 表示法在 javascript 中创建对。也许有像 {i:3, j:4} 这样的带有 i 和 j 属性的对象更合适。


这应该允许您在给定当前坐标的情况下找到相邻的方块并执行诸如着色或查找单个移动是否有效等操作。

如果您需要做一些事情,例如查找所有可在 2 个步骤中到达的 hexes 或找到到达某个 hex 的最少步数,您只需要使用更高级的算法。


顺便说一句,不要太努力地在 Javascript 中找到您需要的算法的现有实现。 Javascript 具有足够的表现力,因此很容易将某些东西从另一种语言(或伪代码)转换为它。

【讨论】:

  • 你的 j 是奇数/j 是偶数吗?对于 4,3,按顺序排列的邻居是 3,3|3,4|4,4|5,3|4,2|3,2 与您的 j 匹配的偶数代码...
  • 非常感谢。如果我想为相邻字段着色,但我想为所有可在 2(或 3、4、5)步中到达的十六进制着色,这非常有用,为此我想要更复杂的东西。你知道怎么做吗?
猜你喜欢
  • 1970-01-01
  • 2020-11-10
  • 2019-06-07
  • 2015-05-22
  • 1970-01-01
  • 1970-01-01
  • 2014-05-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多