状态驱动的游戏智能体设计(上)
2008-03-11 14:51
435 查看
本文由恋花蝶最初发表于http://blog.csdn.net/lanphaday,欢迎转载,但必须保持全文完整,也必须包含本声明。译者并示取得中文版的翻译授权,翻译本文只是出于研究和学习目的。任何人不得在未经同意的情况下将英文版和中文版用于商业行为,转载本文产生的法律和道德责任由转载者承担,与译者无关。State-Driven Game Agent Design 状态驱动的游戏智能体设计[align=left]Mat Buckland著[/align][align=left]赖勇浩(http://blog.csdn.net/lanphaday) 译[/align][align=left]Note: the text for this tutorial comprises part of the second chapter of the book Programming Game AI by Example. Its appearance online is a cunningly disguised attempt to tempt you into purchasing said book. I have no shame. Buy the book, you’ll enjoy it. J[/align][align=left] 题注:本文取自《Programming Game AI by Example》一书的第二章,它在网上刊出的原因是想让你购买这本书。尽管这看起来有点狡猾,但我并不感到羞愧,因为如果你购买了这本书,你会发现它值得你购买。[/align][align=left]原文地址:http://www.ai-junkie.com/architecture/state_driven/tut_state1.html[/align][align=left]Finite state machines, or FSMs as they are usually referred to, have for many years been the AI coder’s instrument of choice to imbue a game agent with the illusion of intelligence. You will find FSMs of one kind or another in just about every game to hit the shelves since the early days of video games, and despite the increasing popularity of more esoteric agent architectures, they are going to be around for a long time to come. Here are just some of the reasons why:[/align][align=left]就像经常听到的,有限状态机(简写为FSM)早就被AI程序员用来实现游戏智能体以体现智能感。你会发现在FSM几乎是所有视频游戏的基础构架,不管正在出现和流行的越来越深奥的智能体架构,FSM在长久的未来仍然有武之地。这里是一些为什么FSM如此强劲的原因:[/align] They are quick and simple to code.There are many ways of programming a finite state machine and almost all of them are reasonably simple to implement. You’ll see several alternatives described in this article together with the pros and cons of using them.
可以快速简单地编写代码。实现有限状态机有多种途径,而且都可以简单实现。在本文你就能看到多种描述和赞成或者反对使用它们的理由。
They are easy to debug.Because a game agent’s behavior is broken down into easily manageable chunks, if an agent starts acting strangely, it can be debugged by adding tracer code to each state. In this way, the AI programmer can easily follow the sequence of events that precedes the buggy behavior and take action accordingly.
易于调试。因为一个游戏智能体的行为由一个易于管理的代码段来实现,如果一个智能出现奇怪的行为,可以通过为每一个状态增加Tracer来调试。这样能够容易地跟踪事件序列,就可以针对之前的怪异行为修改代码了。
They have little computational overhead.Finite state machines use hardly any precious processor time because they essentially follow hard- coded rules. There is no real “thinking” involved beyond the if-this-then-that sort of thought process.
需要付出一点计算代价。有限状态机几乎不使用宝贵的处理器时间,因为他们本质上跟硬编码是一样的。在那种“如果这样就那样”的思考处理中根本不存在真正的“思考”。
They are intuitive.It’s human nature to think about things as being in one state or another and we often refer to ourselves as being in such and such a state. How many times have you “got yourself into a state” or found yourself in “the right state of mind”? Humans don’t really work like finite state machines of course, but sometimes we find it useful to think of our behavior in this way. Similarly, it is fairly easy to break down a game agent’s behavior into a number of states and to create the rules required for manipulating them. For the same reason, finite state machines also make it easy for you to discuss the design of your AI with non-programmers (with game producers and level designers for example), providing improved communication and exchange of ideas.
符合直觉。人类天生就以当前处以这种或者哪种状态来思考事情,所以我们常常听到我们自己处于什么状态的说法。多少次你“让你自己进入状态”或者发现你自己处于“正确的精神状态”?尽管人类并非真的像有限状态机那样工作,但通常我们发现这样有利于我们思考我们的行为。同样地,这易于通过一系列的状态和创造操作规则来实现一个游戏智能体的行为。基于同样的原因,有限状态机能让你和非程序员(如游戏策划和关卡设计师等)更好地进行关于你的AI设计的讨论,改进交流和交换观点。
They are flexible.A game agent’s finite state machine can easily be adjusted and tweaked by the programmer to provide the behavior required by the game designer. It’s also a simple matter to expand the scope of an agent’s behavior by adding new states and rules. In addition, as your AI skills grow you’ll find that finite state machines provide a solid backbone with which you can combine other techniques such as fuzzy logic or neural networks.
可伸缩性。游戏智能体的有限状态机易于调整,能够很容易让程序员实现游戏设计师需要的行为,也易于通过增加新的状态和规则来扩展智能体的行为。此外,随着你AI技术的增进,你将发现有限状态机提供坚实的基础,让你能够把模糊逻辑和神经网络之类的技术组合到游戏中。
[align=left] [/align][align=left]What Exactly Is a Finite State Machine?[/align][align=left]有限状态机定义[/align][align=left]Historically, a finite state machine is a rigidly formalized device used by mathematicians to solve problems. The most famous finite state machine is probably Alan Turing’s hypothetical device: the Turing machine, which he wrote about in his 1936 paper, “On Computable Numbers.” This was a machine presaging modern-day programmable computers that could perform any logical operation by reading, writing, and erasing symbols on an infinitely long strip of tape. Fortunately, as AI programmers, we can forgo the formal mathematical definition of a finite state machine; a descriptive one will suffice:[/align][align=left] 从历史观点上来说,有限状态机是一种严格的公式化的被数学家用以解决难题的一种策略。最著名的有限状态机可能是阿兰·图灵在1936年发表的论文《On Computable Numbers》上写下的的猜想——图灵机。这是现代计算机的雏形,能够通过在无限长的磁带上进行读、写和擦除符号来实现所有逻辑操作。幸运的是,作为AI程序员,我们能够对公式化的数学定义不加理会,如下描述已经足够:[/align][align=left]A finite state machine is a device, or a model of a device, which has a finite number of states it can be in at any given time and can operate on input to either make transitions from one state to another or to cause an output or action to take place. A finite state machine can only be in one state at any moment in time.[/align][align=left]有限状态机是一种策略或者一种策略模型,它由有限的一系列状态构成,在任一给定时刻,可以通过输入操作作出从一种状态到另一种状态的转换或者产生输出或者发生动作。有限状态机在任一时刻都只能够处于一种状态中。[/align][align=left]The idea behind a finite state machine, therefore, is to decompose an object’s behavior into easily manageable “chunks” or states. The light switch on your wall, for example, is a very simple finite state machine. It has two states: on and off. Transitions between states are made by the input of your finger. By flicking the switch up it makes the transition from off to on, and by flicking the switch down it makes the transition from on to off. There is no output or action associated with the off state (unless you consider the bulb being off as an action), but when it is in the on state electricity is allowed to flow through the switch and light up your room via the filament in a lightbulb. See Figure 2.1.[/align][align=left]因此,有限状态机背后的思想就是把一个对象的行为分解为易于管理的“块”或者状态。例如墙上的电灯开关,就是一种非常简单的有限状态机。它有两个状态:开与关。两个状态通过你指头产生的输入来切换。把开关扳上,它就从关的状态转换到开的状态,把开关扳下,它就从开的状态转换到关的状态。在关的状态没有任何输出或者动作(除非你装灯泡被关掉视为一种动作),但当在开的状态下时电流通过开关并且通过灯泡里的灯丝照亮房间。如图2.1[/align]
[align=center]Figure 2.1. A light switch is a finite state machine. (Note that the switches are reversed in Europe and many other parts of the world.)[/align][align=center]图2.1 开关是一种有限状态机。(注意:这种开关在欧洲和其它很多国家仍有存在。)[/align][align=left]Of course, the behavior of a game agent is usually much more complex than a lightbulb (thank goodness!). Here are some examples of how finite state machines have been used in games.[/align][align=left]当然,游戏智能体的行为往往比灯泡要复杂得多。下文是一些在游戏中使用有限状态机的的例子。[/align]本文由恋花蝶最初发表于http://blog.csdn.net/lanphaday,欢迎转载,但必须保持全文完整,也必须包含本声明。译者并示取得中文版的翻译授权,翻译本文只是出于研究和学习目的。任何人不得在未经同意的情况下将英文版和中文版用于商业行为,转载本文产生的法律和道德责任由转载者承担,与译者无关。[align=left]· The ghosts’ behavior in Pac-Man is implemented as a finite state machine. There is one Evade state, which is the same for all ghosts, and then each ghost has its own Chase state, the actions of which are implemented differently for each ghost. The input of the player eating one of the power pills is the condition for the transition from Chase to Evade. The input of a timer running down is the condition for the transition from Evade to Chase.[/align][align=left]· Pac-Mac里的精灵的行为用有限状态机实现。所有的精灵都有一种Evade(逃避)状态,它们的实现都是一样的;但每一个精灵都一个Chase(追踪)状态,它的实现各不相同。[/align][align=left]· Quake-style bots are implemented as finite state machines. They have states such as FindArmor, FindHealth, SeekCover, and RunAway. Even the weapons in Quake implement their own mini finite state machines. For example, a rocket may implement states such asMove, TouchObject, and Die.[/align][align=left]· Quake系列的机器人以有限状态机实现。它们FindArmor(找装备)、FindHealth(找补血)、SeekCover(找掩护)和RunAway(逃跑)等多种状态。甚至Quake里实现的武器都带有小型有限状态机,例如一个火箭炮实现的状态就有Move(移动)、TouchObject(触到物体)和Die(死亡)等几种状态。[/align][align=left]· Players in sports simulations such as the soccer game FIFA2002 are implemented as state machines. They have states such as Strike, Dribble, ChaseBall, and MarkPlayer. In addition, the teams themselves are often implemented as FSMs and can have states such as KickOff, Defend, or WalkOutOnField.[/align][align=left]· FIFA2002之类的运动模拟游戏里的运动员是用状态机实现的,它们有Strike(踢出)、Dribble(带球)、ChaseBall(逐球)和MarkPlayer(盯人)等状态。此外,整个球队通常也是用FSM实现的,有KickOff(发球)、Defend(防守)和WalkOutOnField(不知道怎么翻译,请足球达人告知一下)。[/align][align=left]· The NPCs (non-player characters) in RTSs (real-time strategy games) such as Warcraft make use of finite state machines. They have states such as MoveToPosition, Patrol, andFollowPath.[/align][align=left]· RTS(实时策略游戏)(例如Warcraft)中的NPC(非玩家角色)也利用有限状态机。它们的状态有MoveToPosition(移动到某地)、Patrol(巡逻)和FollowPath(跟随)等。[/align][align=left] [/align][align=left]Implementing a Finite State Machine[/align][align=left]有限状态机实现[/align][align=left] There are a number of ways of implementing finite state machines. A naive approach is to use a series of if-then statements or the slightly tidier mechanism of a switch statement. Using a switch with an enumerated type to represent the states looks something like this:[/align][align=left]实现有限状态机有许多方式。一个直观的做法就是使用一系列的if-then语句或者稍显整洁的switch语句。使用switch的实现看起来就像这里的代码:[/align][align=center]
enum StateType{state_RunAway, state_Patrol, state_Attack};[/align] [align=left]void Agent::UpdateState(StateType CurrentState)[/align] [align=left]{[/align] [align=left] switch(CurrentState)[/align] [align=left] {[/align] [align=left] case state_RunAway:[/align] [align=left] EvadeEnemy();[/align] [align=left] if (Safe())[/align] [align=left] {[/align] [align=left] ChangeState(state_Patrol);[/align] [align=left] }[/align] [align=left] break;[/align] [align=left] case state_Patrol:[/align] [align=left] FollowPatrolPath();[/align] [align=left] if (Threatened())[/align] [align=left] {[/align] [align=left] if (StrongerThanEnemy())[/align] [align=left] {[/align] [align=left] ChangeState(state_Attack);[/align] [align=left] }[/align] [align=left] else[/align] [align=left] {[/align] [align=left] ChangeState(state_RunAway);[/align] [align=left] }[/align] [align=left] }[/align] [align=left] break;[/align] [align=left] case state_Attack:[/align] [align=left] if (WeakerThanEnemy())[/align] [align=left] {[/align] [align=left] ChangeState(state_RunAway);[/align] [align=left] }[/align] [align=left] else[/align] [align=left] {[/align] [align=left] BashEnemyOverHead();[/align] [align=left] }[/align] [align=left] break;[/align] [align=left] }//end switch[/align] [align=left]}[/align] |
Current State[/align] | [align=left]Condition[/align] | [align=left]State Transition[/align] |
[align=left]Runaway[/align] | [align=left]Safe[/align] | [align=left]Patrol[/align] |
[align=left]Attack[/align] | [align=left]WeakerThanEnemy[/align] | [align=left]RunAway[/align] |
[align=left]Patrol[/align] | [align=left]Threatened AND StrongerThanEnemy[/align] | [align=left]Attack[/align] |
[align=left]Patrol[/align] | [align=left]Threatened AND WeakerThanEnemy[/align] | [align=left]RunAway[/align] |
Class State[/align] [align=left]{[/align] [align=left]public:[/align] [align=left] [/align] [align=left] virtual void Execute (Troll* troll) = 0;[/align] [align=left]}; [/align] |
class Troll[/align] [align=left]{[/align] [align=left] /* ATTRIBUTES OMITTED */[/align] [align=left] [/align] [align=left] State* m_pCurrentState;[/align] [align=left] [/align] [align=left]public:[/align] [align=left] [/align] [align=left] /* INTERFACE TO ATTRIBUTES OMITTED */[/align] [align=left] [/align] [align=left] void Update()[/align] [align=left] {[/align] [align=left] m_pCurrentState->Execute(this);[/align] [align=left] }[/align] [align=left] [/align] [align=left] void ChangeState(const State* pNewState)[/align] [align=left] {[/align] [align=left] delete m_pCurrentState;[/align] [align=left] m_pCurrentState = pNewState;[/align] [align=left] }[/align] [align=left]};[/align] |
//----------------------------------State_Runaway[/align] [align=left]class State_RunAway : public State[/align] [align=left]{[/align] [align=left]public:[/align] [align=left] [/align] [align=left] void Execute(Troll* troll)[/align] [align=left] {[/align] [align=left] if (troll->isSafe())[/align] [align=left] {[/align] [align=left] troll->ChangeState(new State_Sleep());[/align] [align=left] }[/align] [align=left] else[/align] [align=left] {[/align] [align=left] troll->MoveAwayFromEnemy();[/align] [align=left] }[/align] [align=left] }[/align] [align=left]};[/align] [align=left] [/align] [align=left]//----------------------------------State_Sleep[/align] [align=left]class State_Sleep : public State[/align] [align=left]{[/align] [align=left]public:[/align] [align=left] [/align] [align=left] void Execute(Troll* troll)[/align] [align=left] {[/align] [align=left] if (troll->isThreatened())[/align] [align=left] {[/align] [align=left] troll->ChangeState(new State_RunAway())[/align] [align=left] }[/align] [align=left] [/align] [align=left] else[/align] [align=left] {[/align] [align=left] troll->Snore();[/align] [align=left] }[/align] [align=left] }[/align] [align=left]};[/align] |
相关文章推荐
- 状态驱动的游戏智能体设计(下)
- 状态驱动的游戏智能体设计
- 状态驱动的游戏智能体设计(下)
- 状态驱动的游戏智能体设计(上)
- 状态驱动的游戏智能体设计(中)
- 状态驱动的游戏智能体设计(上)
- 状态驱动的游戏智能体设计(中)
- 状态驱动的游戏智能体设计
- 状态驱动的游戏智能体设计(中)
- 状态驱动的游戏智能体设计(下)
- 游戏程序开发:状态驱动的游戏智能体设计(一)
- 状态驱动的游戏智能体设计(下)
- 状态驱动的游戏智能体设计
- 状态驱动的游戏智能体设计(下)
- 游戏程序开发:状态驱动的游戏智能体设计 (二)
- 状态驱动的游戏智能体设计(中英双语)
- 状态驱动的游戏智能体设计(上)
- 状态驱动的游戏智能体设计(上)
- 状态驱动的游戏智能体设计(中)
- 游戏程序开发:状态驱动的游戏智能体设计(三)