第 14 章 ? 游戏人工智能 ? 游戏AI(Artificial Intelligence,人工智能)是近来讨论较多的主题。随着游戏中画质与音效的稳步提高和改善,游戏控制玩家(game controlled players)不用“聪明的”方式进行操作,这种情况变得越来越明显。游戏AI是编程人员为了给用户提供某种挑战或某种真实体验而设计出来的。在游戏中,站在一处从不移动的警卫显得非常不真实。如果你创建一个程序,使他不时朝四周张望或变换姿势,就会看起来更具活力,而且更加真实。通过创建一个在预设路径上行走的警卫,偶然还能够停下来与正在站岗的警卫谈话的情景,可以使玩家感觉到游戏的真实感有很大提高。 编写游戏AI是一个十分复杂的工程,里面包含的知识可以编撰成一本书了,但是AI是我们不可回避的问题,所以本章将为大家讲解AI的含义及相关概念,最后还会向大家推荐一些在Irrlicht中常使用的协助编写AI的类库。 学习目标 ? 了解游戏AI的想关概念 14.1 什么是智能 AI是一门相对年轻的学科,其早期的一些研究工作完成于19世纪50年代初期。受早期游戏机计算能力和存储空间的限制,游戏采用真正AI技术的历史很短。由于AI在游戏中是一个崭新的概念,因此游戏AI的定义对于大多数人,甚至从事游戏开发的人来说都还很模糊。 在介绍游戏AI之前,我们应该先了解一下智能的概念。“智能”这个术语相当模糊,它是指“获取和应用知识的能力”,从字面上解释,该定义可能意味着自动调温器也是智能的。因为自动调温器可以获取房间太冷这个知识,从而应用它所学到的知识调节加热器。事实上,智能的“真正”定义已经是一个古老的争论了,而设计一个好的游戏并不需要这个定义。基于我们自己的目的,一个智能的游戏智能体是能够获取关于这个世界的知识,并对该知识做出反应的智能体。做出反应的质量和效果就是游戏需要权衡和设计的问题。 14.2 什么是游戏AI 在AI的经典著作《Artifical Intelligence:A Modern Approach》(人工智能:一种现代方法)中,Russel和Norving指出,AI就是设计计算机程序可以像人一样行动和思考,同时是理性地行动和思考。这个定义包含智能的认知学和行为学的观点,并涵盖理性和“人性”。 简单地说,游戏AI就是游戏中的代码,使得在给定情形下,当游戏有多种选择时,计算机控制的竞争对手(或合作伙伴)采取看起来聪明的决策,从而产生相关、有用的行为。注意上述叙述中“看起来”这个词。游戏中由AI产生的行为是“结果”导向的,因此可以认为游戏界主要关注AI中的行为主义学派。的确,我们仅仅对系统将要做出的响应感兴趣,而不太关心系统是如何做出这个响应的。我们关心系统如何行动,而不关心如何思考。人们在玩游戏时并不会在意这个游戏是否运用庞大的决策脚本数据库,也不会在意是否对决策树进行直接搜索,或者是否建立所处环境的精确知识库,是否基于逻辑规则进行推理决策。正如这些AI所说,推理过程全由游戏AI实现。因此,纯粹的行为决策,如对手发动了哪项攻击、他是如何接近玩家的、他如何在环境中使用各种要素以及其他游戏细节,全部是由游戏AI系统完成的。 现代游戏发展过程中也使用AI这个术语描述其他游戏行为,比如人类输入接口的工作方式。有时甚至支配运动和碰撞的算法(如果游戏运动通过动画驱动而非物理模拟)也属于这一类。可见,AI是游开发界中一个被广泛使用的名词。当与其他同行讨论AI时,大家必须一致认同这个术语的内涵和范围。这点非常重要,否则一个人关于AI的观念与其他人的观念相差太远,就容易产生误解。本章涉及AI时,将使用非常狭窄的定义,即“基于角色的行为智能”。其中的术语“角色”源于大多数游戏的角色驱动本质。 以前,AI编程普遍被称为“游戏玩法编程”,因为CPU控制的角色所展现出来的行为的确不含任何智能成分。在视频游戏早期,大多数程序员都为他们游戏中的人物使用一些模式或重复运动。在某种程度上,玩这些游戏时都要找到预先确定的行为模式,以便能够轻易击倒对手并继续前往另一个地点。这是由早期处理器速度和存储空间的极端限制所决定的。模式很容易存储,只需要最少的代码来驱动,并且几乎不需要进行计算;无论在顶层表现什么行为,它都简单地使人物按规则模式运动。事实上,一些游戏采用所谓随机的运动,但由于早期游戏中的随机数产生器使用伪随机数的硬编码表,因此这些模式能够在整个游戏行为中最终预见。 过去,为了让游戏看起来更加智能,经常使用另一种技术,即让计算机对手作弊,也就是让其拥有人类玩家所不拥有的关于该游戏的额外信息,从而使下一步所做的决策看起来非常巧妙。计算机读入玩家所按的按钮后,以一个阻碍的走步作为系统的响应。一个实时策略作弊器可以使使用者在游戏早期还没有找到有价值资源的区域时便前往这些地点。当游戏赋予计算机对手额外的能力、资源以及一些可直接使用的东西,而不是依靠自己提前规划和了解对这些资源的需要,就可以实现AI的作弊。这些策略能够带来更具挑战性,但是最终还是不能让人满意的对手。 14.3 AI的组成与设计 几乎所有AI引擎都将以某种形式使用决策与推理、感知、导航等基本系统。 14.3.1 抉择与推理 决策系统是AI引擎中使用最广泛的部分,是决定用户构建的AI引擎类型的底层结构。推理可定义为从实际知识或假定为真的前提中获取逻辑或合理结论的行为。用游戏术语来说,意味着AI控制的对手获取关于世界的信息并响应智能、合理的决策。因此,AI系统受获取的外界信息限制,也受游戏设计时定义的响应集丰富程度的限制。游戏允许AI角色做的事情越来越多,游戏的响应集或状态空间就越来越大。用户选择的技术应该由用户要构建的游戏规模和状态空间的大小决定。 所有决策系统都可归结于这个定义:利用可得到的输入获取解决方案。这些技术之间的差别将决定用户选择使用的类型。我们关注的主要区别有:解决方案的类型、智能体的反应能力、系统的真实性、游戏类型、游戏内容、游戏平台等。 14.3.2 解决方案的类型 游戏解决方案的主要类型有两种:战略型和战术型。战略型解决方案通常针对长期、高层次并需要多个行动共同完成的目标。而战术型解决方案更多针对短期、低层次并只包含一个物理动作和技巧的目标。两者的区别在于游戏中关注整体行动还是个体行动。许多游戏同时需要战略型和战术型两种解决方案,因此开发人员根据这种划分将问题分离成几个独立的部分,并结合不同的结束实现。 14.3.3 智能体的反应能力 游戏元素应该如何反应?脚本化系统趋向于设计具有更多程式化和语境响应的角色,但它们容易受困于这些行动脚本,从而失去反应。与此相反,完全反应式系统容易被认为过于机械或作弊,并且不符合人类的感情。强响应系统需要一个非常丰富的响应集,否则它们表现的行为将是可预测和无新意的。然而这对街机式游戏或所谓的twitch游戏非常合适,需要在所设计的游戏类型和对所期望设计的玩法经验正确权衡的基础上进行阐述。 14.3.4 系统的真实性 要被认为是“真实的”,AI元素做出的决策和行动必须类似于人类。在游戏的限制条件下,每个AI实体都需要智能决定所要做的正确的事情,但类似于人类也意味着会犯错误。因此,AI角色也需要很好地体现人类的弱点。化解玩家所有拳击或射击永远不会落空的对手和Scrabble游戏中对整个字典了如指掌的对手都不会让玩家高兴,反而会让他们感到沮丧,我们的目标是在竞赛和娱乐之间找到平衡,从而使玩家被游戏的挑战性所吸引,同时通过击败游戏形成一个持续的积极反馈。真实性问题还包括对游戏使用物理定律的实际认同数量。玩家能跳得比实际生活中更高吗?他能飞吗?是否能很快痊愈?这些都得由开发人员决定,意味着“真实性”可定义为“特定游戏世界中的真实性”。在幻想世界中尤其要小心,因为肆意破坏规则的敌人将被认为是在作弊而不是具有魔法,必须采取措施以确保玩家了解并遵守游戏世界中的规则。还要记住,大多数玩家都知道地球物理定律,但在他们设法习惯开发人员设定的规则时,这些特殊定律最初很有可能成为他们的绊脚石。 14.3.5 游戏类型 不同类型的游戏需要不同类型的AI系统。在游戏层面上,必须记住以下几项: (1)输入(或感知)类型。要注意的事项包括输入的数量、频率、信息传递方式(轮询、事件、回调函数等)以及输入之间的层次关系。街机式游戏只有非常有限的输入,而实时策略游戏中的角色可能需要非常多关于世界的感知,以便导航地形、保持编队、帮助友好单元、接收人类发出的命令并对攻击的敌人做出响应。 (2)输出(或决策)类型。根据感知,系统赋予引擎决策部分信息,AI系统将做出一个决策或产生一个输出。输出可以是模拟的、数字的或在周边行为上的一连串事件,可以包含整个角色(如潜水以寻求掩护)、部分角色(如扭头以响应噪声)或多个角色(如让市民们挖更多石头)。输出可以是具体的,也可以是高层的,其中后者将影响许多AI角色的行为,并改变许多决策的进程。 (3)游戏类型需要的决策整体结构。有的游戏具有非常简单或单一性的决策,Robotron游戏就是一个例子。怪物以一定的速度和运动类型向玩家靠近,并试图杀死玩家。在复杂的游戏中(如《帝国时代》),需要在游戏中进行许多不同类型的决策,可以使用小组级策略、单元战术、一系列路径搜索问题以及其他更深奥的问题,如外交手段等。其中每一个问题都可能代表AI中的一个子系统,而且这些子系统采用完全不同的方法完成这些工作。 14.3.6 游戏内容 上述游戏类型是游戏玩法关注的特例,由特殊或新奇的游戏内容决定。《黑与白》之类的游戏需要为基本的游戏玩法机制设计非常专业的AI系统,即通过引导或展示如何完成工作教它学会主要的动物行为。预先设计框架时需要进行深思熟虑,同时可以向早期的原型性工作寻求帮助以克服设计上的缺陷。 14.3.7 游戏平台 游戏是为了哪种平台制作的呢?是个人电脑、家庭控制台、街机体系还是掌上电脑?尽管不同机器之间的界限已经开始变得模糊,但各自还是有具体要求和限制,这是我们必须要考虑的。通常需要考虑的平台有3种:个人电脑(PC)、控制台(Console)和掌上电脑(Handheld)。 (1)个人电脑。在线PC游戏可能需要用户的可扩展性,因此AI系统需要对这些进行处理。单人PC游戏通常具有非常深的AI系统,因为PC游戏玩家年龄一般偏大,他们希望更高的复杂性和对手的真实性。PC的标准输入设备是鼠标,因此人类玩家将用这个器件执行各种具体命令。如果让AI单调地执行一些任务或鼠标不可能执行的任务,会觉得犯规了。同时,对大多数游戏来说,持续变化的PC意味着最小配置也逐步提高。因此在做出设计决定时,AI程序员需要预测游戏运行的最小配置。而且PC游戏的体验过程通常比较长,AI对手需要经常变化,这样与其对抗才不会觉得重复。 (2)控制台。由于控制台的游戏玩家通常较为年轻,而且对虚幻场景更加开放,因此对它的实现约束也有所提高。然而,由于玩家技能高低的范围很大,因此对难度级别设置有了更广泛的应用,存储器和CPU的预算更为严格。这是因为与PC相比,这些机器的资源有限。从质量保证的角度而不是玩法体验的角度看,控制台游戏在很大程度上具有更高的质量标准。然而由于这种高标准,在被核准发行前AI系统需要承受更长时间和更艰辛的测试。 (3)掌上电脑。掌上电脑是最严格的平台,它曾经是任天堂的天下,但近年来变成了游戏开发的热门领域,如PDA、移动电话等都开始进入游戏世界。这些机器通常具有非常小的RAM,输入键的数量也十分有限,并且袖珍型机器的图形能力非常弱。事实上,过去常与8位或16位技术打交道的人再一次找到了可以施展才华的地方。这些平台上的AI需要更智能,空间和速度也要最优。正因为如此,这些机器通常为AI系统采用一些倒退的技术,比如模式化运动、类似于无意识障碍的敌人、作弊等。随着掌上电脑系统变得日益强大,这种情况将会改变,而且掌上电脑和控制台之间的界限也会变得模糊。 14.4 AI的输入处理和感知 AI感知可定义为游戏中元素相应环境中的事件。AI感知可以像玩家位置一样简单,也可以像在实时策略游戏中对计算机看到的人类进行记录一样复杂。通常,如果可能,这些类型的数据寄存器就会被封装成一个单个的代码模块,从而能够更容易地对系统进行添加,确保在AI系统其他部分没有做重复操作,有助于调整,并将计算提炼到一个最容易优化的中心位置。 中枢感知系统能够在每个输入寄存器中对额外数据或需要考虑的事项进行标记,包括感知类型、更新规则、反应时间、门限、负荷平衡、计算代价与前置条件等。 14.4.1 感知系统 不同类型的输入可能包括布尔型、整型、浮点型等,还可能包括静态感知和动态感知。篮球游戏中逻辑所需要的感知就是静态感知的一个例子,如“控球技能大于75”,只需确定一次,除非所玩的游戏允许技能在游戏过程中进行调整。 14.4.2 更新规则 不同的感知需要以不同的频率进行更新,同时不一定追求很高的更新频率,因为感知变化没有那么快或重新计算的代价十分高昂。这可以认为是一种形式的反应时间,但不完全正确。更像是一种轮询式的感知,人们不会在意它是否过时。继续篮球游戏的例子,我们可以通过视线检测确定持球者是否具有一条通向篮板的无障碍通道。这种检测的代价十分昂贵,特别是在要对所有移动角色使用预测确定他们是否会及时让出通道的情况下。因此,可以每隔一段时间检测一次,而不是一直检测。 14.4.3 反应时间 反应时间是在敌人确认环境变化之前的暂时停顿。当反应时间为零时,计算机就纯粹是一台计算机。在敌人确认事情之前安排一点随机大小的暂停时间,将会使系统的整体行为看起来更具人性,并且更公平。这也可以用于调整难度级别,使整个游戏的难度跟期望值差不多。反应时间也能使角色具有一点个性,从而使快的角色比慢的角色反应更快。 14.4.4 门限 门限是AI能够响应的最小值和最大值,可用于简单的数据范围检测,也可用于模仿听觉不好的角色或目光敏锐的角色。相应游戏事件的门限可以下降或升高,同样可用于模仿感知的退化或增强。因此,一个闪光弹会暂时使对手什么也看不见,但巡逻的守卫通过这个未经辨识的声音实际行动变得更加敏锐,因为他暂时集中了注意力。 14.4.5 负荷平衡 在一些游戏中,AI需要考虑的数据数量可能非常庞大,或者计算量非常繁重,从而难以对游戏的任何时间点进行评估。建立一个感知系统,以便可以指定具体输入变量的更新时间。这是一种使系统负荷平衡的简单方式,可以防止很少变化的时间占用太多CPU时间。 14.4.6 计算代价与预处理 除了刚刚提到的使计算负荷平衡外,还需要对计算代价进行粗略考虑,因此在脑海中要设计一个具有分层连接计算的系统,从而首先进行简单的预处理计算,如果能够通过这些简单计算达到目的,就可以不用进行复杂的判决。为了给出一个极度简化的例子,我们假定在Pac-Man游戏中,控制主要角色的AI程序需要进行两个计算:能量丸的数量和每个能量丸之间的距离。Pac-Man游戏最好能够在计算与所有能量丸的距离之前先检查能量丸的总数量,以确定至少有一个,因为计算距离需要消耗更多计算代价。 为游戏选择的感知系统很可能针对具体游戏,因为AI系统响应的输入在很大程度上取决于游戏的类型、玩法强调的重点、角色或敌人具有的所有特殊能力等。AI系统需要的一些数据来源于对人类传感系统的模仿,而其他数据仅仅是直接使用游戏中的信息。要确保不要太远离后一种情况,因为AI在计算或空间上的代价非常昂贵。 更新感知寄存器的主要样式有轮询和事件,下面分别进行介绍。 轮询(polling),在游戏循环基础上,轮询设计对每个游戏循环中要变化的具体值进行检测或计算,如时刻检测篮球玩家是否有机会传球。这对AI响应的大多数数据来说都是必要的。但这种数据更需要进行负荷平衡,模拟输入或可能以其他形式表示的输入需要始终使用这个方法。 事件(event)。事件在某些方面刚好与轮询相反。输入告诉感知系统它发生了变化,而感知系统注意到这种变化。如果感知系统没有接收到事件,就不会做任何事情。不会经常变化的数字输入是首选方法。原因在于将源源不断的事件注册、排队,然后执行,只是给轮询系统增加开销而已。 一些游戏广泛使用先进的感知系统。因为敌人的感觉是一种对付玩家的十分有效的武器,并且除了游戏目标外,大部分游戏体验都是关于如何击败感知系统的。 14.5 OpenSteer 前面介绍了有关AI的概念,让读者大致了解了什么是AI及在编写游戏AI时应该考虑的因素。下面将为读者介绍一个可以介入Irrlicht引擎,帮助编写游戏AI的类库OpenSteer。 OpenSteer是一个C++类库,能够帮助构建游戏中的人物自动做出的动作。在类库中,OpenSteer提供了一个基于OpenGL的程序—OpenSteerDemo。这是一个已经编译好的可以直接运行的程序,该程序展示了OpenSteer的相关用法。初学者可以查看和改写OpenSteerDemo中的插件来快速上手,使用它编写AI。OpenSteerDemo允许用户交互式地创建自己的AI,使用起来比较方便。OpenSteer的示意图如图14.1所示。 图14.1 OpenSteerDemo 读者可以自己尝试使用OpenSteerDemo编写自己的游戏AI。如果对OpenSteer还有什么不明白的地方,那么可以通过查阅OpenSteer项目的网站主页进行了解。该网站有很多学习资料供大家学习,网站的网址为:http://opensteer.sourceforge.net/。 通过学习本章的内容,读者可以在自己的游戏中添加一些活动的、能跟读者互动的AI,相信这些AI可以为你的游戏带来不少欢乐。