欢迎光临散文网 会员登陆 & 注册

模块化的AI(下) | Game AI Pro

2020-06-07 16:11 作者:有木乘舟  | 我要投稿

8.5 Modular AI: Conceptual Abstractions and Modular Components

  概念抽象定义了体系结构支持的基类类型。换句话说,这些抽象定义了GAIA其余部分将使用的接口。模块化组件是对应的组件,每个组件为概念抽象提供具体的实现。这种方法允许GAIA提供一个环境,支持松散耦合的模块化组合,而不受特定实现的限制。开发人员可以自由地思考,这些可以生成所需行为的抽象应该属于哪种类型,然后通过重用和定制现有的模块化组件,或者根据需要创建新组件来配置实现。

  本节将描述GAIA使用的主要概念抽象,提供它们的使用示例,并给出它们的接口。

8.5.1 Considerations

 Considerations是最有用的概念抽象。如果您不确定是否要构建一个完整的模块化人工智能,或者只是在寻找一个可以用来改进现有体系结构的技巧,那就可以从它开始。

  Considerations被用来表示每一个不同的因素,这些因素可能被权衡在一起以做出决定。核心是,每一种考虑都提供了一种方法来评估一项行动相对于所考虑的因素的适宜性。清单8.1完整地显示了考虑事项界面。

  为了了解这些行动是如何进行的,让我们以狙击手做出狙击敌人的这一决定,它只有在以下这些情况满足时才会执行:

  • 撤退路线是无阻碍的。

  • 杀戮区域中有一个目标。

  • 离狙击手上次射击已经过了“一两分钟”。

  为这个决定构建配置需要实现上面三种情况,每种情况对应一个组件,每个组件都是实现考虑接口的模块化组件。

  首先,一个实体存在考虑(EntityExists consideration)是用来检查是否有敌人在狙击手将要撤退的区域里。实体存在考虑(EntityExists consideration)通过遍历所有联系表(或所有参与者,或所有威胁,具体取决于配置方式)来查看是否至少有一个符合某些约束集。

  在这种情况下,限制条件是实体必须是敌人,并且必须在狙击手计划逃离的区域内。该区域是使用区域定义的,区域是另一个概念抽象(如下所述)。如果有敌人封锁撤退线,这一首要考虑将否决这一选择(即不允许选择),否则它将允许执行这一选择(但其他考虑仍可能否决这一选择)。

  接下来,狙击手需要选择一个射击目标(a contact),这时候就需要用到第二个实体存在考虑(EntityExists consideration),目标必须是敌人,并且在杀戮区域内。要加入其它条件限制也非常容易,只需要在联系表上进行配置即可,比如让狙击手更倾向于接近掩护较少、级别更高的敌人。考虑事项(consideration)的是使用选择器(在后面的章节中讨论)来选择最佳目标并将其存储在大脑的黑板上。如果选择了一个选项,那么开枪动作将会从黑板上直接选取这个目标,而不是再全部遍历一遍。如果找不到目标,则该选项无效。

  最后,一个ExecutionHistory consideration用来检查自狙击手上一次射击后过了多久。这个考虑选项有60到120秒的延迟,如果时间低于这个延迟,则否决该选项。每次这个选项被选中时(推理机选中该选项并执行),consideration会重新开始一个延迟计时。

  考虑事项是最强大的概念抽象,可以随意与本章中描述的其他思想配合使用。它们很容易实现(唯一稍微棘手的部分是决定如何将它们组合在一起本章稍后将详细介绍),并且能大大减少重复并提高代码重用。一旦拥有了它们,配置决策就变成了一个简单的枚举选项并为每个选项指定注意事项的问题。配置一个主意事项比用代码写一个函数简单得多,通常只需要几秒到几分钟,但每个注意事项底层却包含了几十上百行代码。新的考虑事项或能力只需要配置一次,就能够无限次重复使用。

  由于考虑事项被大量重复使用,因此它也允许你花时间来为复杂决策做差异化设计。EntityExists是一个很好的例子,它展示了考虑事项可以变得多么复杂和强大,但是即使是像ExecutionHistory这样非常简单的考虑事项,也可以根据选项执行的时间、上次运行的时间或是否运行过来做出决定。这使得我们可以实现像冷静、目标惯性(延迟)、重复惩罚和单次奖励(这些概念在我们之前的工作[Dill 2006]中进行了详细讨论)。它还可以支持广泛的评估功能,这些功能可以根据经过的时间来驱动决策----例如,通过比较随机值(如本例所述)或应用响应曲线(如Lewis关于效用函数选择的章节和Mark关于行为数学的书籍[Lewis 2016,Mark 2009]所述)。有了考虑事项,意味着你需要的时候可以在几秒钟内就能用上它,而不用花几分钟甚至几小时重新实现它。并且由于已经经过了大量的使用和测试,它的bug也会非常的少。上面没有讨论的一个问题是,为了评估每一个选项,推理机实际上是如何综合考虑的。这是一个很大的话题,所以我们暂时不谈它(我们在下面用一整节的篇幅讨论它)。简单地说,返回一组权重值,这些权重值组合在一起决定推理机的决策。

8.5.2 Weight Functions

  虽然考虑事项可以减少基础代码中的重复部分,但是不同类型的考虑事项之间仍然有很多重复。  因此,剩下的许多概念抽象都是为了让我们能够将重复的代码封装在考虑事项中。首先是权重函数。

  许多不同类型的注意事项计算一个浮点值,然后将该单个浮点值转换为一组权重值。权重函数抽象负责进行这一转换。例如,Distance consideration计算两个位置之间的距离,然后使用权重函数将该浮点值转换为一组权重值。有些游戏可能会有Health consideration,这和NPC的健康(或者敌人的健康)是一样的。其他有可能需要Ammo consideration。我们在狙击手身上使用的ExecutionHistory consideration,它实际上有三个权重函数:一个是当选项被选择时使用,一个是当它从未被选择时使用,一个是当它以前被选择过但现在没被选择时使用。

  当然,并非所有考虑事项都会产生浮点值。例如,EntityExists consideration会生成一个布尔值:如果找到实体,则为TRUE;如果没有找到实体,则为FALSE。但其不同的实例可能会为TRUE或FALSE返回不同的权重值。在狙击手的例子中,一个EntityExists consideration会否决一个选项,当区域中有目标被检测到时(检查撤离路线);也可能是因为没有目标被检测到时(选择射击目标)。这是通过改变每个人使用的权重函数的配置来实现的。其他考虑因素也可能产生布尔值----例如,有的游戏会有LineOfSight consideration,如果两个角色之间有视线交流则返回True,否则返回FALSE。

  有许多不同的方法可以将输入值转换为一组权重值。对于浮点数,我们可以应用一个响应曲线(BasicCurve权重函数),或者我们可以将可能的输入值分成若干部分,并为每个部分返回一组不同的权重值(例如,如果跟敌人的距离小于50米或大于300米,则否决射击选项,但如果它位于FloatSequence权重函数之间,则不否决),或者我们可以简单地将其视为布尔值(布尔权重函数)。我们甚至可能完全忽略输入值,并且总是返回一个固定的结果(恒重函数,the Constant weight function)----这通常是和ExecutionHistory consideration一起配合完成的,以确保特定的选项只被选中一次。例如,如果它从未被选中,它将获得一次固定的奖金。

  考虑事项不必知道使用了哪种技术,因此我们使用概念抽象,其中转换是使用一致的接口完成的,不同的方法是作为模块组件实现的(例如,BasicCurve、FloatSequence、Boolean或恒重函数)。清单8.2给出了这个概念抽象的接口。

  回到狙击手的例子,EntityExists的两个注意事项都将使用布尔权重函数。布尔权重函数配置了两组权重值:一组在输入值为TRUE时返回,另一组在输入值为FALSE时返回。在这两种情况下,一组权重值将配置为否决某个选项(TRUE值分配给逃生路线检查,FALSE值分配给目标选择),而另一组权重值将被配置为对最终决策没有影响。

  ExecutionHistory consideration更有趣一些。它有三个权重函数:一个在选项执行时使用(评估选项被选中后的时间增量),一个在选项从未被选中时使用(评估游戏加载后的时间增量),如果选项在过去已被选中但当前未被选中,则使用此选项(它计算自上次停止执行以来的时间增量)。在这种情况下,当选择这个选项时(即当狙击手正在射击时),我们使用一个被配置为无效的恒重函数。我们同样为一个选项从未被选择时这种情况配置了权重函数,如当狙击手第一次遇到目前并开枪时。第三个权重函数(如果当前未选择该选项,但在过去已执行过该选项,则使用该函数)使用FloatSequence权重函数检查输入值是否大于我们的冷却时间,并返回相应的结果。此权重函数还配置为在每次选择该选项时随机化冷却时间。

8.5.3 Reasoners

  如前几节所述,推理机实现了负责决策的概念抽象。推理机的组件决定了推理机的类型和选项。每个选项包含一系列的注意事项和操作。推理机使用这些注意事项来评估每个选项并决定要选择哪个选项,这些操作决定当关联选项被选择时应会发生什么。清单8.3给出了这个抽象的接口。

    GAIA目前提供四种不同的模块化推理机组件:

  • 序列推理机,按照配置中列出的顺序执行其选项(非常像BT中的序列节点)。与其他类型的推理机不同,序列推理机总是执行其每个选项,因此它忽略了任何可能被配置到他们上面的考虑事项。

  • 基于规则的推理机,它使用每个选项的注意事项来确定该选项是否有效(即,在当前情况下,是否应该执行该选项)。每勾选一个,这个推理器都会按照配置中指定的顺序向下排列选项列表,并选择第一个有效的选项。这与许多BT实现中的选择器节点的方法基本相同。

  • FSM推理机,它允许我们实现一个有限状态机。对于这个推理机,每个选项包含一个转换列表,而不是考虑事项。每个转换都指定了一组注意事项(决定是否应进行转换),以及在转换确实启动时应选择的选项(即状态)。推理器使用选择器(在下面的8.7节中描述)从转换列表中进行选择。

  • 双效用推理机(DualUtility reasoner),GAIA使用的基于效用的推理机。双效用推理机计算两个浮点值:秩(the rank)和权重。然后使用这两个值和随机数生成器来选择一个选项。在我们之前的工作中讨论了双效用推理机(Dill 2015,Dill et al。以及第8.6.2节。

  当然,模块化的体系结构可以不局限于以上这些设定来做决策。例如,我们经常考虑实现一个面向目标的动作规划器(GOAP)推理机(当我们想要搜索满足某个目标的动作序列时)。像FSM推理机一样,可以通过构建新组件的方式来很好的组合进GAIA里。

8.5.4 Actions

  动作是推理机的输出,它们负责将命令发送回游戏、更改黑板或推理机决定执行的其他操作。它们的接口如清单8.4所示。

  如上所述,动作可以是抽象的,也可以是具体的。抽象动作是指导决策过程的行为,如子推理动作。其他抽象动作包括暂停(the Pause)和设置变量(SetVariable),暂停动作在将其自身标记为完成之前会延迟指定的时间量,它常用于序列推理机中,用来控制具体动作的时序

。设置变量动作用于在数据存储区上设置变量(通常是大脑的黑板)。

  就其本质而言,具体动作不能作为GAIA库的一部分来实现。它们包含特定游戏代码,用于使npc执行任务。常见的具体动作包括移动、播放动画、播放声音、使用武器等。

  我们的工厂系统允许开发人员将特定游戏代码注入人工智能(Dill 2016)。

8.5.5 Targets

  目标为组件配置提供了一种抽象的方法来指定位置和/或实体。例如,Distance consideration测量两个位置之间的距离。为了使这个考虑事项可以复用,GAIA需要在配置中指定这两个位置应该是什么。也许一个是NPC的位置,另一个是玩家的。也许一个是敌人的位置,另一个是需要保护的目标的位置(如夺旗模式中的旗帜)。理想情况下,Distance consideration不必知道它所测量的点之间的距离是如何计算的,只需有某种机制来获得这两个位置,然后它就可以从那里进行计算。类似的,LineOfSight consideration需要知道要检查视线之间的位置或实体,Move action需要知道要移动到哪里, FireWeapon action需要知道要射击的目标,等等。

  GAIA对此的解决方案是目标概念抽象,其接口如清单8.5所示。目标为其他组件提供位置和/或实体。例如,Self target 返回AI控制的NPC的actor和位置。ByName target按名称查找角色(也会从actors或联系表中查找,根据不同的配置方式)。

  

  所有目标都可以提供位置信息,但有些目标不提供实体信息。例如,Position target返回一个固定(x,y,z)位置(在目标的配置中指定),但不返回实体。编写配置的人员应该意识到这一点,并确保在需要实体的情况下不使用不提供实体的目标,但GAIA也有检测功能。实际上,这从来不是一个问题,在需要实体的情况下使用Position target是没有意义的。

  与所有概念抽象一样,一些类型的目标可以在GAIA中实现,而另一些则需要通过游戏实现。例如,某些游戏可能会添加一个玩家目标,为计算机返回联系人(或参与者)。对于其他游戏(如多人游戏),这种类型的目标是没有意义的。

8.5.6 Regions

  区域与目标类似,不同的是,它们指定的区域更大,而不是指定空间中的单个(x,y,z)位置。它们通常用于触发器和触发区之类的事情,尽管它们还有很多其他用途。例如,狙击手配置将使用它们来指定杀戮区(它应该射击的区域)和撤退路线(它计划逃离的路线中需要通过的区域)。

  区域是一个概念抽象,因为它有助于为人工智能设计师提供各种方法来指定它们。具体实现可以为圆形区域(目标/圆心和半径),平行四边形区域(位置和两个向量),多边形区域(顶点序列)。

  类似地,一些游戏会非常喜欢简单的二维区域,另一些游戏则需要在三维空间中指定区域。

清单8.6给出了这个抽象的接口。

8.5.7 Other Conceptual Abstractions

  概念抽象提供了一种强大的机制,它允许我们封装和重用代码。之前讨论的都是比较常用的,GAIA还有一些其他的:

  • 传感器,它提供了一种将数据传送到人工智能的机制(尽管大多数项目只是直接写入数据存储)。

  • 执行过滤器,它可以控制推理器和/或传感器的频率。

  • 实体过滤器,它是选择满足某些约束集的实体的选择器的替代方法。

  • 数据元素,它封装存储在数据存储中的内容。

  • 向量,它抽象出一个游戏对位置表示的方法的实现细节。

  此外,随着GAIA的不断改进,不时会发现并添加新的概念抽象(向量是最新的例子)。GAIA包括一个宏和模板化类系统,允许我们通过调用单个宏并传入抽象的名称来为每个概念抽象创建大部分基础结构,包括它们的工厂和任何全局配置的存储(Dill 2016)。

8.6 Combining Considerations

  注意事项是模块化组件中最重要的一种。在许多方面,它们是GAIA运转的关键部分。一般来说,它们是建立决策逻辑的最小模块。它们可以表示的概念包括:两个目标之间的距离、目标所剩的血量,或者自上次选择特定选项以来的时间变化量。推理机使用考虑事项来评估每个选项,并选择它们将要执行的选项,但是推理机如何结合考虑事项的输出呢?

  多年来,我们尝试了许多不同的方法来解决这个问题,有的很简单,有的很复杂。本章将介绍几种方法:一种非常简单的布尔方法,用于实验性教育游戏中的触发系统(Dill and Graham 2016,Dill et al)。一种更复杂的基于效用的方法,结合三个值来执行选项评估(Dill 2015,Dill et al,. 2012)。最后一种方法虽然看起来很难用,但实验经验表明只要理解其基本规则就能很方便的用于各种决策。

8.6.1 Simple Boolean Considerations

  最简单的组合考虑事项的方法就是把它们当做布尔值。每个选项都有一个单独的考虑事项,返回TRUE(可以选择该选项)或FALSE(不能)。逻辑操作(如AND、OR和NOT)可以视为常规考虑事项,除非它们包含一个或多个子考虑事项,并返回对其子考虑事项的综合评估。因此,一个选项的单一考虑事项通常是一个AND或OR,它包含一个附加考虑事项的列表(其中一些本身可能是布尔操作)。

  这一方法被用于The Mars Game中的触发系统,这是一个实验性教育游戏,背景是火星,用于九年级和十年级的数学和编程教育。清单8.7显示了一个Mars Game触发器的示例(在YAML中指定)。这个特定的触发器在关卡开始后,先等待15秒,然后播放一行对话框提示如何解决有种的特定挑战,同时触发器会在Blackboard中标记提示已被触发。但是,它只在以下情况下播放提示:

  • 这个提示在上个关卡中没有出现过。

  • 玩家还没有在他们的漫游者(rover)中执行一个阻塞程序(Blockly program) 。

  • 玩家的漫游者面朝南或西(即180°或270°),因为提示描述了如何处理开始时面朝错误方向的情况。

  这种方法的优点是十分简单,大多数开发人员甚至游戏设计者都很熟悉布尔逻辑,因此它不仅易于实现,而且易于使用。它非常适用于触发系统和基于规则的推理机这样的系统,它们可以独立地对每个选项进行决策,而无需将两个选项进行比较,就可以确定哪个选项是最好的。然而,如果你真的想做出更细微的决定,并且这些情况经常出现在项目的后期,当设计师(或QA,或出版商,或公司所有者)来找你说“它做的大多是伟大的,但在这种情况下,我希望它能……”时,它会受到很大的影响。

  考虑到这一点,最好有一种方法,它允许用简单的方式指定布尔型决策,但也支持在需要时进行复杂的比较----这时候就轮到双重效用考虑事项出场了。

8.6.2 Dual Utility Considerations

  双重效用考虑事项是GAIA使用的方法,每个考虑事项返回三个值:加数、乘法器和秩。然后将这三个值组合起来以创建选项的总体权重和秩,该方法的名称就是这样来的(权重和秩)。

8.6.2.1 Calculating Weight and Rank 

  一次一个地执行这些步骤,首先要做的是将加法器和乘法器组合成选项的总权重(W)。这是通过首先将所有的加数相加,然后将结果乘以所有的乘法器来完成的。

  接下来,计算考虑事项的总秩R,通过计算全体考虑事项的最大秩来实现:

  还有其他的公式可以用来计算权重和秩,GAIA也支持一些替代方案(在后面的章节中会有更多介绍),但绝大多数情况下,主要使用这两个公式。

8.6.2.2 Selecting an Option

  计算出权重和秩后,推理机需要使用它们来选择一个选项。具体如何做到这一点取决于推理机的类型,但所有这些都基于双重效用推理机。双重效用推理背后的想法是,人工智能将使用秩将选项划分为不同的类别,然后使用基于权重的随机选择从排名最高的类别中选择。实际上,实现这一目标有四个步骤:

  • 排除任何W0≤0的选项。它们不能在步骤4中选择,并且会使步骤2更加复杂,因此最好在前面消除它们。

  • 从剩下的选项中找出最高级别,并删除任何级别低于该级别的选项。此步骤确保仅考虑排名最高类别的选项。

  • 从剩下的选项中找出最大权重,并删除权重“远小于”该权重的选项。“远远小于”是指在推理机配置中指定的百分比,在许多情况下,推理机的配置为完全跳过此步骤。这一步可以确保基于权重的随机选择在存在更好的选项时不会选择权重非常低的选项,因为这样做看起来很蠢----虽然在技术上是可行的,但考虑到其他可用的选项,这样做不太明智。

  • 使用“基于权重的随机”从保留的选项中进行选择。

  有几件事值得一提。首先,注意步骤1。任何选项都可以通过将其权重设置为0来消除,不管其他选项的权重和级别如何。更重要的是,回顾等式8.1,任何考虑事项都可以通过返回0的乘数,将一个选项的权重强制为0(即否决它),不管其他考虑事项的值是什么。任何乘以0的值都是0,这提供了一种简单的方法来处理双重效用选项。如果一个选项的W0>0,我们就说它是有效的(也就说它是可选择的),反之无效。基于规则的推理机通过按顺序检查其选项并选择第一个有效选项来工作,而不考虑优先级。

8.6.2.3 Configuring Dual Utility Considerations

   实现双重效用考虑事项的关键是提供默认值,以确保即使系统具有相当大的复杂性,在配置考虑事项时也会隐藏复杂性。本节将讨论GAIA用于完成此任务的默认值、命名约定和其他技巧。在这个过程中,它会给出一些例子,狙击手将会使用这些例子来选择目标。

  在GAIA中,指定权重值的最基本方法是简单地将addend、multiplier或rank指定为XML中的属性。三个值中未指定的那个将会被设置为无效的默认值(addend=0,multiplier=1,rank=-FLT_MAX)。因此,配置AI的开发人员只需要指定他或她想要更改的值即可。

  举个例子,一个优秀的狙击手应该更倾向于对军官开火。为了实现这一点,游戏可以在每个联系表上放置一个布尔值“IsOfficer”。当狙击手认为目标是军官时,该布尔值为“真”,反之为“假”。然后,在配置中,我们使用BooleanVariable考虑事项从PickerEntity目标(狙击手的目标)中查找这个值。如果该值为真,则考虑使用布尔权重函数将乘数设置为10,否则不执行任何操作(即返回默认值)。假设有一个10个士兵的队伍(每个士兵的权重为1)和一个军官(每个军官的权重为10),所有其他条件相同的情况下,那么狙击手大概有一半的时间会朝军官射击。表8.8显示了这个考虑事项的配置:

  在有些情况下,考虑事项不想自己的选项被选择,不论何种情况。例如,当狙击手选择了一个目标时,我们需要确保他只会朝敌人开火。这可以通过在联系表中存储一个Side来实现,SIde有三个值:朋友,敌人或平民。如果Side的值不是“敌人”,那么狙击手就不会选择这个目标,不管他的其他属性是什么。这可以通过指定乘数0来配置,但是这样配置应该更明确,更易于阅读。考虑到这一点,权重可以指定一个布尔值vote,如果该布尔值为“真”,那么乘法器将设置为0。反之,所有三个权重值将设置为默认值。

  表8.9是狙击手的考虑事项结果。这种考虑与清单8.8中的非常相似,只是它查找一个字符串变量,而不是布尔变量,并将结果传递给一个字符串权重函数。该函数会将字符串与每个条目进行匹配。如果字符串与任何条目都不匹配,则返回默认值。在这种情况下,这意味着如果字符串是“敌人”,那么考虑事项将无效(因为当vote为假时,它返回默认值),否则它将设置乘数为0(因为vote为真),从而使选项无效。

  另外,清单8.8和中的考虑事项很好地展示了模块化人工智能如此强大的原因。这些考虑事项评估数据存储上的变量的值。它可以是任何数据存储上的任何变量。在这种特殊情况下,数据存储是使用一个目标(而不是NPC或大脑黑板)来指定的,它同样可以是指定实体的任何类型的目标。一旦考虑事项找到了变量的值,它就会将该值传递给一个权重函数以转换为权重值。如果没有考虑事项、数据存储和权重函数的思想,我们将不得不为这些检查编写专门的代码块,这些代码块只在狙击手的目标选择中使用,并且在使用布尔数据存储变量的任何其他地方重复实现。此外,该代码将是几十行C++代码,而不是一行XML。不过,最重要的是,XML中指定的值在很大程度上是我们在向同事或朋友描述逻辑时使用的人类化的概念。

  人工智能应该评估什么?它正在考虑是否射击的目标(PickerEntity目标)。它应该如何评估这个目标?检查它是不是敌人,是不是军官。这个评估应该怎么做?只向敌人开枪,一半的时间就干掉敌人的军官。

  配置注意事项还有一个细节尚未讨论。为了被选中,每个选项都需要有一个大于0的权重,但是所有考虑事项的默认加法器都是0。我们至少需要一个考虑事项的加法器大于0,不然总权重将会为0。此外,我们希望所有选项的默认权重都合理,如1。

  可以通过设置一个Tuning考虑事项来解决这个问题,是一个只返回指定的加数器、乘法器和秩的考虑事项,它的默认加法器是1。该选项的配置可以(而且通常会)指定一个Tuning考虑事项,但如果没有,则会自动添加一个addend为1的默认Tuning考虑事项。

8.6.2.4 Changing Combination Techniques at Runtime

  到目前为止,我们已经说过选项拥有这些考虑事项,并负责为推理机将它们组合在一起。这实际上有点不准确。选项有一个AIConsiderationSet,它反而包含了注意事项。考虑事项集合负责组合其考虑事项,并返回总权重和秩,它还可以返回其考虑事项的组合加法器和乘法器,而无需将其乘以总权重。其接口如清单8.10所示。这种区别很重要,因为它意味着我们可以在考虑事项集合上放置标志,以指定该特定集合中的考虑事项应与不同的规则组合。此外,还有一种特殊类型的考虑事项,它包含另一个考虑事项集合(AIConsideration_ConsiderationSet)。

  最常用的组合注意事项的替代方法是对权重应用不同布尔运算。默认情况下,如果任何考虑事项否决了一个选项(即,返回0的乘数),则该选项将不会被选中。这本质上是一个连接词(即一个逻辑和)----所有的考虑必须是“真”(即乘数大于0),以便选项是“真”(即有效)。在某些情况下,我们需要的不是AND,而是一个逻辑OR,也就是说,只要至少有一个对价的乘数不为0,我们就希望选项vt是有效的。在某些情况下,我们需要的不是AND,而是逻辑OR,也就是说,只要至少有一个考虑事项的乘法器不为0,我们就希望该选项有效。这是通过让考虑事项集合忽略乘法器小于或等于0的任何考虑事项来实现的,除非每个考虑事项都具有小于或等于0的乘法器。类似地,NOT的实现方式是将小于或等于0的任何乘法器替换为1,将大于0的任何乘法器替换为0。GAIA还支持不同的组合秩的方法:它不需要取最大值,而可以取最小值或将所有考虑事项的秩加在一起得到总的秩。所有这些更改的配置都与所有其他更改一样,也就是说,有一个属性告诉考虑事项集合要使用哪种计算方法,默认值(未指定该属性时)将使用标准方法。

  更多关于配置双重效用注意事项的技术,请参见Dill (2006), Dill et al. (2012), Lewis (2016), and Mark (2009)。

8.7 Pickers

  我们将在本章中讨论的最后一个主题是pickers。选取器使用推理机来查看事物列表(通常是联系表、参与者或威胁的列表,但也可能是FSM选项的转换列表),并为某个目的选择最佳的一项(例如,最好的交谈对象、最好的拍摄对象、最好的掩护对象等)。EntityExists考虑事项使用的选取器和FSM推理机使用的略有不同,但核心思想是一样的。

  虽然大多数推理机在其配置中定义了所有选项,但选择器的推理机必须从运行时确定的选项中进行选择。例如,我们可以使用一个选择器来查看我们的联系人以选择要拍摄的内容,或者查看我们的威胁以选择一个要做出反应的内容,或者查看附近的掩护位置以选择一个要使用的内容(尽管游戏必须扩展GAIA以支持掩护位置来完成最后一个)。在我们的狙击手例子中,EntityExists考虑事项使用选择器来选择要射击的对象,并检查是否有其他目标在其撤退路线上。  第一个选取器应该使用双重效用推理机,因为它希望选择最佳实体。第二种可以使用基于规则的推理器,因为它只需要知道这样的实体是否存在。

  Picker选项是通过获取某个类别中的所有实体(例如所有参与者、所有联系表或所有威胁)并为每个实体创建一个选项而动态创建的。每个选项都有相同的注意事项,在配置中指定。考虑事项可以通过使用PickerEntity目标访问它们负责评估的实体。例如,用来选取狙击手目标的选取器可能会检查与目标的距离、是否在杀伤区、有多少掩护、是否是敌人、是否是军官等等。检查撤退线的选取器只需检查每个实体是否是敌人,以及是否处在撤退路线经过的区域内。

  将所有内容放在一起,狙击手考虑射击的一个简单选项可能如清单8.11所示。此选项使用EntityExists考虑事项来选择目标,然后将选定的目标存储在大脑黑板上的SnipTarget变量中。选取器有两个考虑事项,一个是检查目标是否是敌人,另一个是检查目标是否在50米到300米之间。如果找不到目标,则使用布尔权重函数否决该选项。如果找到目标,它会使用Fire Action来射击。实际上,我们可能希望在选择器中添加更多的考虑事项(以使目标选择更加智能化),这里体现了关键思想。

8.8 Conclusion

  模块化人工智能是一种人工智能规范的方法,它大量地利用软件工程的原理来显著地减少代码重复和提高重用性。它允许开发者以能够表达人类逻辑概念的模块化组件来实现决策逻辑,而不是单纯的通过c++代码来实现。由于组件会被重复使用,因此组件也会变得更加健壮、更多的特性负载(实现更多微妙的差别)。 更重要的是,因为大部分工作都是调用已经编写好的代码,所以人工智能规范可以做得比其他方法快得多。模块化人工智能已经成功地应用于几个只剩几个月开发时间的项目中,其中一款游戏的销量超过5000000份,我们在不到4个月的时间内实现了所有的boss人工智能,从头开始(包括实现架构)。

  本章介绍了一个完整的模块化体系结构(GAIA),它使用各种不同类型的模块化组件。在所有这些概念抽象中,考虑事项是最强大的。对于那些受限于在现有体系结构中工作的人来说,即使在现有体系结构中,也很可能获得模块化人工智能的许多好处,只要实现考虑事项并允许它们驱动您的评估功能。我们在另一款畅销游戏中采用了这种方法,并取得了巨大的成功。

References

Dill, K. 2006. Prioritizing actions in a goal based RTS AI. In AI Game Programming Wisdom         3, ed. S. Rabin. Boston, MA: Charles River Media, pp. 321–330. 

Dill, K. 2015. Dual utility reasoning. In Game AI Pro 2, ed. S. Rabin. Boca Raton, FL: CRC             Press, pp. 23–26. 

Dill, K. 2016. Six factory system tricks for extensibility and library reuse. In Game AI Pro 3,           ed. S. Rabin. Boca Raton, FL: CRC Press, pp. 49–62. 

Dill, K., B. Freeman, S. Frazier, and J. Benito. 2015. Mars game: Creating and evaluating an         engaging educational game. Proceedings of the 2015 Interservice/Industry Training,             Simulation & Education Conference, December 2015, Orlando, FL. 

Dill, K. and R. Graham. 2016. Quick and dirty: 2 lightweight AI architectures. Game                       Developer’s Conference, March 2016, San Francisco, CA. 

Dill, K., E.R. Pursel, P. Garrity, and G. Fragomeni. 2012. Design patterns for the                             configuration of utility-based AI. Proceedings of the 2012 Interservice/Industry Training,         Simulation & Education Conference, December 2012, Orlando, FL.

Isla, D. 2005. Handling complexity in Halo 2 AI. http://www.gamasutra.com/view/feature/              130663/gdc_2005_proceeding_handling_.php (accessed June 26, 2016). 

Jacopin, É. 2016. Vintage random number generators. In Game AI Pro 3, ed. S. Rabin.                   Boca  Raton, FL: CRC Press, pp. 471–478. 

Lewis, M. 2016. Choosing effective utility-based considerations. In Game AI Pro 3, ed.                     S. Rabin. Boca Raton, FL: CRC Press, pp. 167–178. 

Mark, D. 2009. Behavioral Mathematics for Game AI. Boston, MA: Charles River Media.


文章来源:http://www.gameaipro.com/  

如侵犯版权,请联系译者删除。  

读者若需要转载,请注明出处。   

若有错误,欢迎指正。


模块化的AI(下) | Game AI Pro的评论 (共 条)

分享到微博请遵守国家法律