在十六进制图中生成相等的区域


13

以一个大的(X乘Y)的十六进制地图为例,如何将其划分为N个相连的十六进制区域以模拟国家?

目标是生成一个看起来像真实世界地图的十六进制地图,其中的国家/地区形状不同但大小相同。

Answers:


13

您是否尝试过劳埃德算法?该过程非常简单,并且会生成相当规则的外观区域(取决于您运行的迭代次数)。

  1. 使用空白十六进制将地图平铺以开始。
  2. 随机选择N个十六进制。这些将代表每个国家的“群众中心”。
  3. 用最接近的中心十六进制标记每个十六进制(Voronoi图)。国家i是最接近第i个中心十六进制的所有十六进制的集合。
  4. 计算每个国家的新群众中心。
  5. 重复第3步和第4步,以使生成的区域平滑。

您不必运行很长时间即可生成美观的地图。 这个例子只需要三个迭代。


非常好,特别是举了一个例子,我为+1,但我有点担心它们规律了!话虽如此,结果的确确实如此,特别是在那种规模下,它还是种其他方法的绝佳方法。
Steven Stadnicki

1
我的示例的灵感来自有关多边形地图生成的博客文章。作者在每个区域的边缘添加了一些噪点,以使外观更加锯齿(滚动至底部即可看到)。要使该选项可行,您需要使用比我更多的十六进制,但这当然是可行的。
Michael Kristofik 2013年

3

您可以尝试的一种简单方法。

  1. 随机选择n十六进制。每个人都会开始一个小组。
  2. 对于每个组,尝试在随机方向上扩展初始十六进制。
  3. 如果所选十六进制周围的所有十六进制均被占用,则标记为已攻丝,请更改十六进制。
  4. 重复直到每个组的长度为20个十六进制或没有更多的空间可以扩展(轻按所有的十六进制)。

我没有进行测试,但这会产生孤岛,并在某种程度上避免了长而细的牙套。另外,极有可能会有邻居边界,但不一定每个人都会互相联系,密度取决于的值n
有些组还可能被另一些组困住了,并达到了20个以下的大小,您可以通过以彼此之间的最小距离生成启动器六边形来确保增加的空间。
根据需要进行测试和调整。


另外,与该问题无关,但对于使用十六进制非常非常有用,请访问以下页面:http : //www.redblobgames.com/grids/hexagons/#basics
它在一个位置将一堆完整的十六进制信息汇总在一起很好的视觉效果。


如果组B与组A相邻并且没有其他可乘之处,则应该为组A提供一个将节点分配给组B的机制。只要组A有空的空间即可扩展到替换丢失的节点。然后,无论从哪里开始都没关系。因为这有点像“撤退”。
MichaelHouse

我在想也许一次创建一个国家,先形成边角小组,然后边边小组将提供我想要的东西。到家后我会尝试的。
MadCatPT 2013年

@ Byte56是的,实际上我在午餐时想到了这样的事情。如果陷入困境的小组无处可去,则只用一个十六进制的另一个小组,让该小组在下一次迭代中找到一个空白空间。它应该有一些保护措施来避免2个陷入困境的群体无限欺负对方。
petervaz 2013年

真实国家通常在河流或山脉上有边界。在沿随机方向扩展时,如果下一个十六进制位于河流或山脊的另一侧,则可以尝试降低扩展的可能性。
amitp

@amitp如果OP期望考虑这些因素,他可能会提到它们。我不假设,只是在原始的前提下工作。
petervaz 2013年

2

我绝对认为某种类型的图结构将使这成为可能。如果两个Hex节点彼此相邻,则基本上可以在它们之间创建一条边来模拟整个地图。但是,我不确定在该地图内生成“国家”的确切算法。问题是,取决于您希望该国家“看起来”如何,您将需要不同的算法。

我建议,从我的头顶上移开一个点,然后从那里向外移动,在您的“成长国家”中随机选择一个图块,该图块具有一个不属于该国家的相邻图块。

根据您想要的国家类型,可以使用一种策略模式来切换算法。http://en.wikipedia.org/wiki/Strategy_pattern,例如 ,您想要一个像智利这样的纤细海岸线国家吗?还是您想要更全面,更全面的东西?

图形属性还可以让您调整所需的“国家”的外观:http : //en.wikipedia.org/wiki/Eccentricity_(graph_theory)

想要一个大国?调整图形属性,并强制生成的国家/地区(仅是图形)具有使您想要的“外观”的属性。

最后但并非最不重要的一点是,图形对于定义国家之间的边界也非常有用。如果国家/地区彼此毗邻,则可以构建一个在两个节点之间具有连接的图形。这可能对游戏中的某些分区类型很有用,并且可以让您在开发过程中进一步优化某些功能。


2

一个小注意事项:您说“看起来像一张真实的生活地图,形状不同但大小相同的国家/地区),但是即使在某些地区内,“真实”国家/地区的规模也大不相同-甚至欧洲的“大型”国家/地区也可能相差很大,例如法国是意大利的两倍多。话虽如此,显然有一些游戏区域可以尝试保持大小大致相同-请注意,这里的一些变化可能是一件好事!

我最初解决此问题的方法是“演变”(而不是“增长”)您的地区:

  • 首先将地图按直线分成大致相等的大小(例如,如果要6个国家/地区,则可以将地图分为三个水平切片,然后在“对角线”上将每个切片分开)一分为二)。这显然很容易以编程方式完成,尤其是因为它不必非常精确(实际上,可能不应该非常精确)。
  • 对分区进行初始传递,建立一个“边界”数据结构:一组十六进制,其中一些邻居当前属于另一个国家。这也是计算每个国家的十六进制数的好时机。

现在,只要需要,就运行以下伪代码:

Pick a random hex A from the boundary list;
Pick a random neighbor B of this hex from a different country;
if (A's country has more hexes than B's country has) {
  change hex A to belong to B's country;
} else if (B's country has more hexes than A's country has) {
  change hex B to belong to A's country;
} else {
  flip a coin to decide which to change;
}
if ( the changed hex's old country has become disconnected ) {
  undo and reject this move;
} else {
  update the boundary list around the changed hex and its neighbors;
}

这将在任何两个邻国的规模之间保持一个粗略的平衡,并且“断开连接”检查(可以通过简单的洪水填充算法来完成)确保没有任何国家会分裂。更新边界列表是一项固定时间的操作-更改后的十六进制将始终始终位于边界上,并且您可以仅检查其六个邻居以查看它们中的任何一个是否已成为边界单元(因为其邻居现在位于或不再是边界单元(因为它的邻居现在在同一国家/地区),因此可以根据需要修改边界集。

为了改进此方法,您甚至可以使要更改的十六进制的条件稍微随机化-而不是始终“平衡”这两个国家,您可以始终以一定的概率进行掉期,甚至逐渐降低该概率。时间(类似于“ 模拟退火”算法中的冷却过程)开始迫使它们大小大致相同。

请注意,这不能保证所有区域的大小都完全相同(除非N总是将网格大小完美地划分,否则这是不可能的),甚至不能保证所有国家/地区的面积都在一个十六进制之内。但是,它应该保证(进行足够的迭代)每个国家与其邻国的距离不大于或小于十六进制。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.