www.pudn.com > IntroductionTo3DGameEngineDesign.rar > Thinker.cs
using System;
using System.Collections;
using System.Threading;
using System.Diagnostics;
using System.Xml;
using GameEngine;
namespace GameAI
{
///
/// Summary description for Thinker.
///
public class Thinker : IDisposable
{
#region delegates
public delegate void SensorMethod( Thinker the_thinker );
public delegate void ActionMethod( Thinker the_thinker );
#endregion
#region Attributes
private ArrayList m_state_list = null;
private ArrayList m_sensor_methods = null;
private AIState m_current_state = null;
private SortedList m_fact_list;
private Thread m_think_thread;
private Model m_model = null;
private bool m_thread_active = true;
private static SortedList m_methods = new SortedList();
#endregion
#region Properties
public Model Self { get { return m_model; } }
#endregion
public Thinker( Model model )
{
m_model = model;
m_state_list = new ArrayList();
m_sensor_methods = new ArrayList();
m_fact_list = new SortedList();
m_methods = new SortedList();
m_think_thread = new Thread(new ThreadStart(Execute));
m_think_thread.IsBackground = true;
m_think_thread.Start();
}
public static void AddAction( string action_name, ActionMethod method )
{
if ( !m_methods.Contains( action_name ) )
{
m_methods.Add(action_name, method);
}
}
public static ActionMethod GetAction( string action_name )
{
ActionMethod method = null;
if ( m_methods.Contains( action_name ) )
{
int index = m_methods.IndexOfKey( action_name );
method = (ActionMethod)m_methods.GetByIndex(index);
}
return method;
}
public static string GetActionName( ActionMethod method )
{
string action_name = null;
if ( m_methods.Contains( method ) )
{
int index = m_methods.IndexOfValue( method );
action_name = (string)m_methods.GetKey(index);
}
return action_name;
}
public void Execute()
{
Debug.WriteLine("thinker thread started");
while ( m_thread_active )
{
if ( m_current_state != null )
{
foreach ( SensorMethod method in m_sensor_methods )
{
method( this );
}
m_current_state.DoActions( this );
m_current_state = m_current_state.Think();
}
}
Debug.WriteLine("thinker thread terminated");
}
public void Dispose()
{
m_thread_active = false;
while ( m_think_thread.IsAlive ) Thread.Sleep(1);
}
public AIState GetState( string name )
{
AIState the_state = null;
foreach ( AIState state in m_state_list )
{
if ( state.Name == name )
{
the_state = state;
}
}
return the_state;
}
public Fact GetFact( string name )
{
Fact the_fact = null;
if ( m_fact_list.Contains( name ) )
{
int index = m_fact_list.IndexOfKey( name );
the_fact = (Fact)m_fact_list.GetByIndex(index);
}
else
{
the_fact = new Fact(name);
the_fact.Value = 0.0f;
m_fact_list.Add( name, the_fact );
}
return the_fact;
}
public void SetFact( string name, float value )
{
if ( m_fact_list.Contains( name ) )
{
int index = m_fact_list.IndexOfKey( name );
Fact fact = (Fact)m_fact_list.GetByIndex(index);
fact.Value = value;
}
else
{
Fact fact = new Fact(name);
fact.Value = value;
m_fact_list.Add( name, fact );
}
}
public void AddSensorMethod( SensorMethod method )
{
m_sensor_methods.Add( method );
}
public void AddState( AIState state )
{
m_state_list.Add( state );
}
public void Write( string filename )
{
XmlTextWriter writer = new XmlTextWriter( filename, null );
writer.WriteStartDocument();
writer.WriteStartElement("Knowledge");
//Use indentation for readability.
writer.Formatting = Formatting.Indented;
writer.Indentation = 4;
int num_facts = m_fact_list.Count;
for ( int i=0; i