西部世界(译文)
By robot-v1.0
本文链接 https://www.kyfws.com/games/westworld-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 10 分钟阅读 - 4674 个词 阅读量 0西部世界(译文)
原文地址:https://www.codeproject.com/Articles/852543/WestWorld
原文作者:Terence Wallace
译文由本站 robot-v1.0 翻译
前言
A demonstration of Finite State Machines (FSM) where agents inhabit an Old West style gold mining town called West World.
有限状态机(FSM)的演示,代理商在其中居住于一个古老的西式金矿开采镇,名为"西部世界".
- 下载WestWorld-noexe.zip-306.1 KB(Download WestWorld-noexe.zip - 306.1 KB)
- 下载WestWorld.zip-306.1 KB(Download WestWorld.zip - 306.1 KB)
介绍(Introduction)
A demonstration of Finite State Machines (FSM) where agents inhabit an Old West style gold
mining town called West World.
作为如何创建利用代理的实际示例(*As a practical example of how to create agents that utilize*) 有限状态机(finite state machine) s [(s [) ^)^( ],我们将考察一个游戏环境,在该环境中,特工居住在一个名为"西部世界"的古老西式金矿开采镇.最初只有一个居民-一个名叫Miner Bob的金矿工.我在本文中包括了WestWorld1,WestWorld2和WestWorld3.我将尝试解释适用于本文所有项目的通用代码框架.(], we are going to look at a game environment where agents inhabit an Old West-style gold mining town named West World. Initially there will only be one inhabitant — a gold miner named Miner Bob. I have included WestWorld1, WestWorld2, and WestWorld3 in this article. I will attempt the explain the general code framework which applies to all of the projects in this article.)
- 西部世界1(WestWorld1)-FSM基础(- Basics of FSM)
- 西部世界2(WestWorld2)-有两名特工的FSM(矿工和妻子)(- FSM with two agents (Miner & Wife))
- 西部世界3(WestWorld3)-包括FSM和代理之间的消息传递(- Includes FSM with Messaging between Agents) WestWorld被实现为基于简单.NET Console的应用程序.任何状态更改或状态操作的输出将作为文本发送到控制台窗口.(WestWorld is implemented as a simple .NET Console based application. Any state changes or output from state actions will be sent as text to the console window.)
背景(Background)
有限状态机(通常称为FSM)多年来一直是AI编码器的首选工具,可以使游戏代理商充满智能的幻想.它们快速且易于编码.(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. They are quick and simple to code.)
- 它们易于调试.(They are easy to debug.)
- 它们几乎没有计算开销.(They have little computational overhead.)
- 他们很直观.考虑事物处于一种或另一种状态是人类的天性.(They are intuitive. It’s human nature to think about things as being in one state or another.)
- 它们很灵活.程序员可以轻松地调整和调整游戏代理的有限状态机,以提供游戏设计师所需的行为.(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.) 有限状态机是具有有限数量状态的设备或设备模型.它们可以在任何给定时间处于特定状态,并且可以根据输入进行操作,以从一种状态转换为另一种状态.它们也可能导致输出或动作发生. FSM随时只能处于一种状态.其背后的想法是将对象的行为分解为可管理的"块"(即状态).例如,墙上的电灯开关是一个非常简单的有限状态机.它有两种状态:开和关.(A finite state machine is a device, or a model of a device, which has a finite number of states. They can be in a particular state at any given time and can operate on input to either transitions from one state to another. They can also cause an output or action to take place. A FSM can only be in one state at any moment in time. The idea behind it is to decompose an object’s behavior into manageable “chunks” (i.e. states). The light switch on your wall, for example, is a very simple finite state machine. It has two states: On and Off.)
总览(Overview)
西方世界有四个地点:一个金矿,一个鲍勃可以在其中存放任何发现的金块的银行,一个可以解渴的沙龙和一个可以在白天疲倦的安逸之家(There are four locations in West World: a gold mine, a bank where Bob can deposit any nuggets he finds, a saloon in which he can quench his thirst, and home-sweet-home where he can sleep the fatigue of the day) 远.鲍勃目前的状态决定了他去哪儿以及到达那儿后做什么.(away. Exactly where he goes, and what he does when he gets there, is determined by Bob’s current state.) 他将根据口渴,疲劳以及发现黑客窃取的金币等变量来更改状态(He will change states depending on variables like thirst, fatigue, and how much gold he has found hacking) 在金矿中消失.在程序的输出中,每次看到Miner Bob更改位置时,(away down in the gold mine. In the output from the program, each time you see Miner Bob change location) 他正在改变状态.所有其他事件都是在一个州内发生的动作.(he is changing state. All the other events are actions that take place within a state.)
码(Code)
西部世界1(West World 1)
实体类别(Entity Class)
西方世界的所有居民均源自此基类实体.这是一个带有私有成员的简单类,用于存储(All inhabitants of West World are derived from this base class Entity. This is a simple class with a private member for storing a) UniqueID
数.它还指定了一个(number. It also specifies a) MustOverride
成员函数(member function,) Update
(),必须由所有子类实现. Update是在每个更新步骤中都会调用的函数,子类将使用该函数来更新其状态机以及必须随每个时间步骤进行更新的任何其他数据.((), that must be implemented by all subclasses. Update is a function that gets called every update step and will be used by subclasses to update their state machine along with any other data that must be updated with each time step.)
这是Entity类声明:(Here is the Entity class declaration:)
''
''' <summary>
''' Base class for a game object
''' </summary>
Public MustInherit Class Entity
'every entity must have a unique identifying number
Private _UniqueID As Integer
'this is the next valid ID. Each time a BaseGameEntity is instantiated
'this value is updated
Private Shared _NextID As Integer = 0
Public Shared ReadOnly Property NextID As Integer
Get
Return _NextID
End Get
End Property
''' <summary>
''' This must be called within each constructor to make sure the ID is set
''' correctly. It verifies that the value passed to the method is greater
''' or equal to the next valid ID, before setting the ID and incrementing
''' the next valid ID
''' </summary>
''' <value>
Public Property UniqueID As Integer
Get
Return _UniqueID
End Get
Set(value As Integer)
'make sure the val is equal to or greater than the next available ID
_UniqueID = value
_NextID = _UniqueID + 1
End Set
End Property
Protected Sub New(ByVal id As Integer)
_UniqueID = id
End Sub
''' <summary>
''' All entities must implement an update function
''' </summary>
Public MustOverride Sub Update()
End Class
矿工阶层(The Miner Class)
Miner类是从Entity类派生的,并且包含Miner拥有的各种属性(例如健康状况,疲劳程度,位置等)的类成员.一个矿工包含一个实例(The Miner class is derived from the Entity class and contains class members for the various attributes a Miner possesses, such as health, its fatigue, position, and so forth. A Miner contains an instance of a) State
类,以及用于更改其状态的方法.的(class in addition to a method for changing its State. The) Miner.Update
()方法很简单;它只是增加了(() method is straightforward; it simply increments the) _
Thirst
调用Execute方法之前的值.看起来像这样:(value before calling the Execute method. It looks like this:)
Public Class Miner
Inherits Entity
Private _CurrentState As State
''' <summary>
''' The higher the value, the thirstier the miner
'''
Private _Thirst As Integer
''' <summary>
''' The higher the value, the more tired the miner
''' </summary>
Private _Fatigue As Integer
Public Sub New(ByVal inUniqueID As Integer)
MyBase.New(inUniqueID)
_Location = LocationType.shack
_GoldCarried = 0
_Wealth = 0
_Thirst = 0
_Fatigue = 0
_CurrentState = GoHomeAndSleepTilRested.Instance()
End Sub
''' <summary>
''' Base class override
''' </summary>
Public Overrides Sub Update()
_Thirst += 1
If _CurrentState IsNot Nothing Then
_CurrentState.Execute(Me)
End If
End Sub
...
End Class
西部世界2(West World 2)
状态机类(State Machine Class)
设计(Design)
通过将所有与状态相关的数据和方法封装到State Machine类中,可以使设计更加简洁.这样,代理可以拥有状态机的实例,并将当前状态,全局状态和先前状态的管理委托给它.(The design can be made a lot cleaner by encapsulating all the state related data and methods into a State Machine class. This way an agent can own an instance of a state machine and delegate the management of current states, global states, and previous states to it.) 考虑到这一点,请看以下StateMachine类模板.现在,代理程序要做的就是拥有一个StateMachine实例,并实现一种方法来更新状态机以获得完整的FSM功能.(With this in mind take a look at the following StateMachine class template. Now all an agent has to do is to own an instance of a StateMachine and implement a method to update the state machine to get full FSM functionality.)
Public Class StateMachine(Of T)
''' <summary>
''' Pointer to the agent that owns this instance
''' </summary>
Public Property Owner As T
Public Property Current As State(Of T)
''' <summary>
''' Record of the last state the agent was in
''' </summary>
Public Property Previous As State(Of T)
''' <summary>
''' This is called every time the FSM is updated
''' </summary>
Public Property [Global] As State(Of T)
Public Sub New(ByVal owner As T)
_Owner = owner
_Current = Nothing
_Previous = Nothing
_Global = Nothing
End Sub
''' <summary>
''' call this to update the FSM
''' </summary>
Public Sub Update()
'if a global state exists, call its execute method, else do nothing
If _Global IsNot Nothing Then
_Global.Execute(_Owner)
End If
'same for the current state
If _Current IsNot Nothing Then
_Current.Execute(_Owner)
End If
End Sub
''' <summary>
''' Change to a new state
''' </summary>
''' <param name="pNewState"></param>
Public Sub ChangeState(ByVal pNewState As State(Of T))
'keep a record of the previous state
_Previous = _Current
'call the exit method of the existing state
_Current.Exit(_Owner)
'change state to the new state
_Current = pNewState
'call the entry method of the new state
_Current.Enter(_Owner)
End Sub
...
End Class
西部世界3(West World 3)
FSM消息传递功能(FSM Messaging Capabilities)
设计(Design)
精心设计的游戏往往是事件驱动的.当事件发生时-发射了武器,拉了杠杆,触发了警报等等.-事件被广播到游戏中的相关对象,以便它们可以适当地响应.这些事件通常以数据包的形式发送,该数据包包含有关事件的信息,例如发送事件的内容,应响应的对象,实际事件是什么,时间戳等等.(Well-designed games tend to be event driven. When an event occurs — a weapon is fired, a lever is pulled, an alarm is tripped, etc. — the event is broadcast to the relevant objects in the game so that they may respond appropriately. These events are typically sent in the form of a packet of data that contains information about the event such as what sent it, what objects should respond to it, what the actual event is, a time stamp, and so forth.) 对于西方世界,数据包是通过Telegram类发送的.智能游戏代理使用电报相互通信.拥有发送,处理和响应事件的能力,可以轻松设计代理行为.(In the case of West World packets of data are sent via the Telegram class. Intelligent game agents use Telegrams to communicate with each other. Endowed with the power to send, handle, and respond to events, it’s easy to design Agent behaviors.)
MessageDispatcher类别(MessageDispatcher Class)
电报的创建,分派和管理由名为MessageDispatcher的类处理.每当座席需要发送消息时,它都会呼叫(The creation, dispatch, and management of telegrams is handled by a class named MessageDispatcher. Whenever an agent needs to send a message, it calls) MessageDispatcher.DispatchMessage
()以及所有必要的信息,例如消息类型,发送消息的时间,收件人的ID等.的(() with all the necessary information, such as the message type, the time the message is to be dispatched, the ID of the recipient, and so on. The) MessageDispatcher
使用此信息来创建(uses this information to create a) Telegram
,它既可以立即分派,也可以存储在队列中,准备在正确的时间分派.(, which it either dispatches immediately or stores in a queue ready to be dispatched at the correct time.)
Public Class MessageDispatcher
'to make code easier to read
Public Const SEND_MSG_IMMEDIATELY As Double = 0.0F
Public Const NO_ADDITIONAL_INFO As Integer = 0
'a Queue is used as the container for the delayed messages
'because of the benefit of automatic sorting and avoidance
'of duplicates. Messages are sorted by their dispatch time.
Private PriorityQ As New HashSet(Of Telegram)()
Private Shared _Instance As New MessageDispatcher
Private Sub New()
End Sub
Public Shared ReadOnly Property Instance As MessageDispatcher
Get
Return _Instance
End Get
End Property
...
End Class
EntityManager类别(EntityManager Class)
之前(Before) MessageDispatcher
可以发送消息,它必须获取对发送者指定的实体的引用.因此,实例化实体必须进行某种查找以供参考-一种电话簿,其中指向座席的指针通过其UniqueID进行交叉引用.此演示使用的查找表是一个单例类,称为(can dispatch a message, it must get a reference to the entity specified by the sender. Therefore, there must be some sort of lookup for instantiated entities to refer to — a sort of telephone book where pointers to agents are crossreferenced by their UniqueID. The lookup table used for this demo is a singleton class called) EntityManager
.(.)
Public Class EntityManager
''' <summary>
''' This method stores a pointer to the entity in the std::vector
''' m_Entities at the index position indicated by the entity's ID
''' (makes for faster access)
''' </summary>
Public Sub RegisterEntity(ByVal e As Entity)
_EntityMap.Add(e.UniqueID, e)
End Sub
''' <summary>
''' Returns a pointer to the entity with the ID given as a parameter
''' </summary>
''' <param name="id"></param>
Public Function GetEntityFromID(ByVal id As Integer) As Entity
'find the entity
Return _EntityMap(id)
End Function
...
End Class
概要(Summary)
本文向您展示了为自己的游戏创建灵活且可扩展的有限状态机所需的技能.如您所见,添加消息传递可以大大增强智能的幻觉.该程序的输出开始看起来像两个真实人物的动作和互动.这只是一个非常简单的例子.行为的复杂性仅受您的想象力限制.(*This article has shown you the skills required to create a flexible and extensible finite state machine for your own games. As you have seen, the addition of messaging can enhanced the illusion of intelligence a great deal. The output from the program is starting to look like the actions and interactions of two real people. This is only a very simple example. The complexity of behaviors is only limited by your imagination.*) 此外,您不必将游戏代理限制为仅一个有限状态机.例如,最好使用两个并行工作的FSM:一个用来控制角色的动作,另一个用来控制武器的选择,瞄准和射击.状态可能包含状态机.这被称为(*Additionally, you don’t have to restrict your game agents to just one finite state machine. It may be a good idea to use two FSMs working in parallel: one to control a character’s movement and one to control the weapon selection, aiming, and firing, for example. It’s possible to have a state contain a state machine. This is known as a*) 分层状态机(Hierarchical State Machine) [([) ^)^( ].例如,您的游戏代理可能具有"探索",“战斗"和"巡逻"状态.反过来,“战斗"状态可能拥有一个状态机,用于管理战斗所需的状态,例如"道奇”,“追逐敌人"和"射击”.(]. For instance, your game agent may have the states Explore, Combat, and Patrol. In turn, the Combat state may own a state machine that manages the states required for combat such as Dodge, ChaseEnemy, and Shoot.)
学分(Credits)
这里显示的VB.NET代码特别感谢Mat Buckland,他的书中的原始C ++代码来自于Mat Buckland:(*The VB.NET code displayed here owes special credit to Mat Buckland for which the original C++ code comes from in his book:*)** 通过示例编程游戏AI(Programming Game AI by Example) **[([) ^)^( ].您可以在此处找到更多信息:(] . You can find out more information here:) http://www.ai-junkie.com/books/toc_pgaibe.html(http://www.ai-junkie.com/books/toc_pgaibe.html)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
VB.NET VB .NET Windows LINQ VS2012 VS2013 Visual-Studio Dev 新闻 翻译