矮人要塞的命令排序体系结构


21

实现AI命令排序系统的最优雅的方法是什么?例如,在矮人堡垒中,当您标记一个森林区域进行砍伐时,矮人将按照以下顺序进行操作:

  1. 去树上
  2. 砍树
  3. 将木材运送到库存中
  4. 去另一棵树
  5. 等等..

我已经有一个不起作用的堆栈命令。从空闲状态到到达树的目标图块的1。

我担心的是,当我创建更多这样的订单时,这会变得混乱吗:

造房子

  1. 去储存
  2. 将木材带到建筑面积
  3. 回到库存
  4. 将石头带到建筑面积
  5. 动画建筑精灵

种植

  1. 去储存
  2. 将种子带到农场

酿造

  1. 去储存
  2. 使植物静止
  3. 动画酿造精灵

所以我的问题是,如何实现矮人堡垒之类的命令排序系统并同时避免使用意大利面条式代码?我需要研究任何数据结构吗?我需要将命令序列放在单独的xml文件中吗?


1
矮人要塞实际上没有这样的系统。矮人一次被分配一项任务,而空闲的矮人将寻找需要做的事情。(“嘿,有一棵砍伐的树-我应该砍掉它!” /“嘿,有一些木头不在库存中-我应该把它
砍成

1
玩家不会为矮人分配任何东西,而是由系统“分配”任务,这正是Jed T.上面描述的体系结构。创建订单,系统将分配各个组件任务以完成该订单。
Attackfarm,2015年

2
请注意,这称为“任务分配和计划”,并且在几个工程领域中进行了广泛的研究。您会发现很多讨论此问题的论文,可能会引起您的兴趣。
TonioElGringo 2015年

@Attackfarm系统无法预先确定所有任务;也不会将多个任务分配给同一个矮人。最初分配了一个任务,当它完成时,其后果是使另一个任务可用。
user253751

Answers:


27

刚开始,您会看到命令是以list的形式出现的,因此您的第一个直觉可能是重新创建该结构,并且每个小矮人将依次遍历该列表。但是我建议将列表分成几步,每步都有先决条件,然后以相反的顺序运行整个命令。让我用一个例子演示:

木材切割

  • 我是否携带木材并有储备?:放下
  • 我在搬运木头吗?是的:去储存
  • 我在树上吗?是的:切碎
  • 否以上所有:去树上

这样做的优点是:

  • 实施非常简单
  • 灵活-您可以自由地分解此列表,添加项目,删除项目,合并项目
  • 无状态-您可以从顶部开始针对任何状态下的任何矮人运行此列表,并且该矮人只会做正确的事TM

缺点:

  • 由于没有状态且没有被卡住的意识,因此很容易卡在循环中

从逻辑上讲,您可以将这些命令表示为流程图,该流程图每次都从顶部开始运行,并且执行的操作取决于在每个步骤中是否回答是/否。究竟以代码形式还是以XML之类的外部文件来实现,都取决于您自己。


2
这还有一个让状态覆盖命令生效的好处,我饿了吗?如果是的话,放弃一切,将任务设置为“吃”,吃的东西类似于木材运输工作。
棘轮怪胎

7
@ratchetfreak“我知道我的堡垒的安全取决于我与这个怪物的战斗,这样它才不会攻击平民,但是天哪,我的肚子刚好咆哮!” 在这方面,尽量不要让它像DF一样:P
三十二上校

我认为这类似于使用(或至少使用过)的东西,该东西允许使用平面包装的错误工件(这是由于违禁物品所致,导致所说的循环)
Destrictor 2015年

3
@ColonelThirtyTwo fun在哪里?;)
拉瑟

我强烈建议不要为此使用声明性的符号动作计划。基本上是不可能进行调试的,并且容易出现不良行为。以程序方式对每个任务的动作序列进行硬编码要容易得多。
mklingen

10

如果您可以使序列相当笼统,则没有太多的意大利面条代码。

在交货的情况下,例如:WorkTask与WorkPlan一起运行。工作计划说明必须从哪种房屋中选择哪种资源单元,使用哪种步行动画,使用哪种工作动画,上班时间以及所有这些细节。因此,最后,WorkTask可能看起来像:

  1. 在地图上找到%resource1%
  2. 使用%animation_1%转到该位置
  3. 使用%animation_2%进行%time%的工作
  4. 在%req_count1%计数中获取%req_resource1%
  5. 使用%animation%转到%home%
  6. 从%animation_6%内部开始%time_2%
  7. 等等..

我们成功地使用了描述的方法。我们的游戏中有约15个任务。一些重点:

  • 任务给单位动作(去那里,进入,退出,去这里,停留,工作,去)
  • 操作以“完成”或“中止”状态结束,并将其传递给任务
  • 一切都是硬编码的(无需编写解析器,接口方法,向后兼容)
  • 每个任务仅通过一些常用方法(创建,执行,保存,加载)实现抽象Task类。
  • 通常每个模块一个任务,但是一个模块中包含相似的任务
  • 非常相似的任务属于一类,并且由几个IF来控制(交付给房屋或交付给单位)
  • 每个任务都需要对资源进行适当的锁定和解锁(如果单元在任何步骤死亡,则必须释放他锁定的资源)

2
这是我们在矮人堡垒般游戏中使用的系统。任务是通过行为树来完成的。资源被行为锁定,而失败则被锁定。它比最佳答案所描述的行动计划方法更加健壮和易于调试
mklingen 2015年

5

因此,这基本上是地形排序的问题。

您有一个图,每个节点都是需要完成的任务,并且某些节点依赖于其他一些节点(这由图中从依赖节点到其依赖的节点的一条边表示)。您需要完成所有任务,因此需要对拓扑产生确定的节点进行某些排序(相关的节点在它们所依赖的节点之后)。

现在,通常有许多这样的排序(因为某些节点没有依赖性并且可以放置在任何地方,并且某些节点具有相同的依赖性并且彼此不依赖,因此它们之间的顺序可以是任意顺序,并且任何节点都可以在完成依赖项之后,以及在完成依赖它的节点之前,都可以放置在任何地方。

也有可能无法按地形对图形进行排序-当图形中存在循环时会发生这种情况(您没有木材,要砍柴需要砍树,要砍树需要斧头,要砍斧,需要木头)。在这种情况下,算法可能应该向玩家指示这些任务无法完成。

您还可以向节点添加优先级,任务可能是在满足依赖关系的所有顺序中找到这样的顺序,即先执行优先级较高的节点。

您还可以添加重新计算任务-最简单的方法可能是每次完成时都将带有超时的任务再次添加到图形中。

现在如何解决它-http://en.wikipedia.org/wiki/Topological_sorting

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.