程序生成特定区域的建筑物


15

我和一个团队正在开发一个工厂建造者游戏,该游戏在游戏开始时为玩家提供一个随机的工厂。为了确保有一种“公平”的感觉,理想情况下,随机生成的工厂的面积应在(占位符值)30的几个单位内。

编写满足这些规范的基本随机矩形生成器相对简单,但我们的目标是使工厂变得更加复杂,可能由2个,3个甚至4个相交的矩形组成,从而产生更复杂的形状(例如L, U和O形建筑物)。

我尝试生成一个随机矩形,然后使用基本代数填充第二个矩形,但是到目前为止,我并没有实现超过2个矩形的运气,即使如此,我对仅2个矩形设计的结果也不满意。

一些更相关的信息:2D自上而下一些机制是factorio样式,因此房间应该具有合理的长度和宽度,以便为机械留出空间(目前在Java和Lua中使用)(可以根据需要使用内置的库)

提前致谢!

编辑:当我说“好”或“坏”的输出时,不良的输出将是具有播放器无法使用的空间的任何输出。工厂形状限制了玩家可以放置工厂机器(例如传送带)的位置。理想情况下,工厂的区域不应只有1-2个块的宽度,形状不应该是一个或两个大的矩形,而将1-2个块的线“垂悬”到一侧。一个好的输出是所有地板空间都是“可行的”,因此所有区域至少应为3-4块宽。好的输出并不一定总是很复杂(可以使用1或2个矩形),但如果由超过1-2个矩形组成,则输出的机会就很大。

Answers:


7

您可以使用预先生成的多米诺骨牌作为元形状来构建各种建筑物。

假设您的最小可接受距离是3个街区。那么我们将考虑的最小可接受建筑单位为3x3。为了方便起见,我将其称为一个单元格,它提供了9个块的区域。接下来,选择目标起始区域并将其除以单元格区域。使用您给定的起始值,我们得到3.333;因此3个单元格会比您想要的少一些,而4个单元格会给您更多。

在这里,您有两个选择。如果您在开始区域上很灵活,请使用最适合您的方法来选择可以接受的单元格数量(即四舍五入到最接近的值,四舍五入等)。我将其称为细胞计数。

接下来,随机选择具有所需细胞计数的多氨基酸。用建筑单元替换多米诺骨牌上的每个正方形,您便拥有了最终的形状。

为了说明,假设我们选择四舍五入。这是所有3号大小的多米诺骨牌(不包括旋转/翻转):

在此处输入图片说明

假设我们随机选择L形并应用随机旋转,您的建筑物将具有以下布局:

在此处输入图片说明

有几个问题。首先,可以使用的单元数有限制。Wikipedia将为您提供8号(octomino)以下的所有多米诺骨牌。它包含最大为12号的摘要数据,但我不知道是否有所有这些的在线清单。其次,以上解决方案仅适用于9的倍数的建筑物。有几种方法可以解决这些问题:

1)使用不同的像元大小。例如3x4、4x4等。

2)将其他单元格添加到起始的多米诺骨牌中。如果必须确保所有形状的可能性均等,这可能会很棘手,但是对于大多数游戏开发人员而言,您并不需要真正均匀分布的建筑形状。

3)淘汰建筑物以使其更大。回到该示例,如果使用3个单元,则建筑物将具有27个正方形的面积,使您短3英寸。然后,您可以扫描周边区域以粘贴1x3大小的正方形组。只要您的化妆组至少为AxB,其中A至少是您的最小可接受距离,您的结果将不会违反您的最小可接受距离约束。在以上示例的基础上,以下是可能结果的说明:

在此处输入图片说明

4)您可以修剪过大的建筑物,而不必填充过小的建筑物。确保遵循最小可接受距离约束比填充选项要复杂得多,但是会为您提供更多选择。

其他一些评论:

仅仅因为您可以使用给定大小的所有可能的多氨基酸,并不意味着您应该这样做。如果其中一些不好玩,破坏主题,冒犯听众(万字模式),或造成其他问题,请将其删除。另外,如果某些模式很有趣,但您也可以加权选择例程,但是太奇怪了,就无法例行弹出。最后,您可以将此解决方案与当前策略结合使用。生成矩形建筑物的时间可能占70%,而使用多米诺方法的时间可能占30%。或者,也许您从一个矩形建筑开始,然后将一个小的多米诺骨牌粘在外面。


16

构建过程生成器的一种简单方法是:

  1. 随机建造东西
  2. 运行一个检查输出是否良好的函数
  3. 如果输出不好,请执行步骤1

即使需要花费数千次运行才能完成,大多数简单的生成器也可以使用这种方法。优点是生成器中不需要很多智能设备,并且由于检查某件商品的良好性要比构建100%的时间好的商品容易得多,因此这种方法非常简单。

您已经列出了一些关于产出是否良好的客观指标;这样就足以创建一个快速且肮脏的生成器。将矩形随机放置在一个区域内,如果例如只有1-2个块宽的区域,则拒绝输出。

从此开始,然后进行改进和优化。


谢谢!我记得考虑过这一点,但是想到有几秒钟以上的加载时间的机会使我停了下来。我现在意识到机会很小。我将不得不尝试一下,但是我可能要等一下,看看是否有人首先有一个更直接的解决方案。
user2129189

@ user2129189当生成器运行时,您仍然可以调整其随机数范围,以避免生成不太可能通过测试的布局。通过使每个内核一次生成一个布局,还可以在多个内核上并行化这种试错生成算法。
菲利普

3
我自己不喜欢拒绝重试生成方法。当您的生成器仅做一件简单的事情时,它们足够快,但是对于游戏级别,我们通常会开始分层更多的功能和生成步骤以制作更丰富的地图。那时,命中可行地图的概率是每个步骤成功的概率的乘积,该概率可以迅速缩小。这不仅是学术上的问题-我已经与开发人员进行过交谈,他们必须实施好的/不好的种子缓存系统,以避免过多的生成时间,而这种构建时正确的单遍生成器会更容易。
DMGregory

@DMGregory是的,我绝对可以看到。对于我的情况,基本的随机数生成器将在几步内工作约99%的时间,但是如果我以后要增加更多的复杂性,它可能会大大降低速度。任何人都知道猜测和类似检查的模型在现实生活中的编程/游戏应用程序吗?
user2129189

可能会有几代人的功能和检查,要注意将条件的措辞与当前的人为水平相匹配。这样,就不必仅仅因为发现错误而将整个关卡重新整体生成,而是将其放置得有些不正确。
Pysis

7

鉴于“所有区域的宽度至少为3-4个街区”的限制,想到的第一个想法如下所示:

  1. 选择3x3、3x4、4x3或4x4之一
  2. 将该大小的块放置在网格的中心
  3. 选择一个方向(上,左,右,下)
  4. 尝试在该方向上将3x3块放置在先前放置的块旁边
  5. 如果成功,则以一定的概率尝试按照您不只是选择的方向之一将块扩展为4x3块
  6. 很有可能将a移动到填充块的随机边缘
  7. 重复步骤3到6,直到区域足够大

基本思想是,假设您希望所有区域都至少具有给定的大小,则只能在该大小的区域中工作。更一般而言,如果您希望所有生成的输出都是真实的,请查看是否可以使所有部分生成的输出都真实。


4
我总是通过从3x3块开始,然后在随机位置添加3x1块来简化事情,在这些位置中,每个正方形都与现有正方形相邻。除3x3块外,还有四个可能的位置。所有这些都为您提供了一个3x4的块,下一个块有六个可能的位置。从那里开始,情况变得更加复杂,但还不算太糟。
JollyJoker

0

考虑使用布尔值NOT和UNION并在它们之间随机选择。

  1. 放置一个随机矩形。
  2. 放置第二个随机矩形。
  3. 随机选择是将它们合并还是从第一个中减去第二个。
  4. 重复多个矩形。虽然只有两个或三个可能会给出足够合理的结果。

然后,我将计算面积并将其放大或缩小,使其更接近您要寻找的近似尺寸,然后测试尺寸是否不小于所需的最小数量。


您获得所需区域的缩放想法实际上很聪明。我可能会像这样实现一些安静的功能。
user2129189
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.