I know I promised the post last week, but it’s the run up to xmas and I have had so much work to do its unreal.
Well let’s jump right in, Finite State Machines or FSMs have for many years been the AI coder’s first choice to create the illusion of intelligence but FSMs are not just used in games AI I have even found then in database APIs.
Here is the best description of a FSM I have found.
|
A finite state machine is a device, or a model of 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. |
If you looking for more information on FMS then I really recommend the book Programming Game AI by Example, this book is based on C++ but the code can easily be transferred to C#.
So let’s start writing some code in Visual Studio creates two projects one Console Application called OrcTest and one Class Library called Ai.
So we are going to start by creating a class called StateTransitionTable.cs in the Ai project.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace Ai
{
abstract public class StateTransitionTable
{
protected Dictionary<object, IState> table = new Dictionary<object, IState>();
public void SetState(object evt, IState state)
{
table.Add(evt, state);
}
public IState GetState(object evt)
{
Ai.IState i = null;
try
{
i = table[evt];
}
catch (KeyNotFoundException)
{
return null;
}
return i;
}
}
}
Next we are going to create a new class file with our Interface code that each state will inherit from and I called the file IState.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace Ai
{
public interface IState
{
void Enter(Entity e);
void Execute(Entity e);
void Exit(Entity e);
}
}
And last but not least we will create one more file called Entity.
using System;
using System.Collections.Generic;
using System.Text;
namespace Ai
{
abstract public class Entity
{
protected static Ai.StateTransitionTable transitionTable = null;
protected IState currentState = null;
public void UpdateState()
{
if (currentState != null)
currentState.Execute(this);
else
System.Diagnostics.Trace.WriteLine("zero state");
}
public object Event
{
set
{
if (value == null)
{
currentState.Exit(this);
currentState = null;
return;
}
IState i = transitionTable.GetState(value);
if (i != null)
{
if (currentState != null)
currentState.Exit(this);
currentState = i;
currentState.Enter(this);
}
}
}
}
}
Now we have our base code it’s time to write our State, in this system am going to create 4 states.
- AttackState
- FleeState
- IdleState
- PatrolState
I am only going to show you one state file as all 4 States are the same.
using System;
using System.Collections.Generic;
using System.Text;
namespace Ai
{
public class AttackState : Ai.IState
{
public virtual void Enter(Entity e)
{
throw new NotImplementedException();
}
public virtual void Execute(Entity e)
{
throw new NotImplementedException();
}
public virtual void Exit(Entity e)
{
throw new NotImplementedException();
}
}
}
So that’s our FSM setup next we are going to use is it in our OrcTest application.
So we will start by creating a class call Orc.css and add this code
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Ai;
namespace OrcTest
{
enum OrcEvent
{
Idle,
Patrol,
Attack,
Flee,
}
class OrcTransitionTable : Ai.StateTransitionTable
{
public OrcTransitionTable()
{
base.table.Add(OrcEvent.Idle, new IdleState());
base.table.Add(OrcEvent.Patrol, new PatrolState());
base.table.Add(OrcEvent.Attack, new AttackState());
base.table.Add(OrcEvent.Flee, new FleeState());
}
}
class Orc : Ai.Entity
{
private int _piss;
public int Piss
{
get { return _piss; }
set { _piss = value; }
}
static Orc()
{
transitionTable = new OrcTransitionTable();
}
}
}
Next we will modify the Program.cs file with the following code.
using System;
using System.Collections.Generic;
using System.Text;
namespace OrcTest
{
class Program
{
static void Main(string[] args)
{
Orc o = new Orc();
o.Event = OrcEvent.Idle;
o.UpdateState();
o.Event = OrcEvent.Patrol;
o.UpdateState();
o.Event = OrcEvent.Attack;
o.UpdateState();
o.Event = OrcEvent.Flee;
o.UpdateState();
o.Event = null;
o.UpdateState();
Console.ReadLine();
}
}
}
So next we are going to override the states we created earlier will Orc states
Again I will just show you one as they are all basically the same.
using System;
using System.Collections.Generic;
using System.Text;
using Ai;
namespace OrcTest
{
class AttackState: Ai.AttackState
{
public override void Enter(Ai.Entity e)
{
Console.WriteLine("Enter Attack State");
}
public override void Execute(Ai.Entity e)
{
Console.WriteLine("In Attack State");
}
public override void Exit(Ai.Entity e)
{
Console.WriteLine("Exit Attack State");
}
}
}
And that’s it we have a basic FSM.
Hope you liked to post feel free to comment
Exactly what I was searching for, appreciate it for posting . cpanel vps | unmetered vps |