Skip to content

Instantly share code, notes, and snippets.

@ungood
Created March 6, 2012 18:59
Show Gist options
  • Select an option

  • Save ungood/1988205 to your computer and use it in GitHub Desktop.

Select an option

Save ungood/1988205 to your computer and use it in GitHub Desktop.
Braaaains
// An action a mob can take. For example: wander, move towards goal, attack
public interface IMobAction
{
bool CanExecute(Mob mob);
void Execute(Mob mob);
}
// A simple example:
public class WanderAction : IMobAction
{
public bool CanExecute(Mob mob) {
return !mob.IsImmobile && !mob.IsTrapped;
}
public void Execute(Mob mob) {
mob.Move(GetRandomDirection());
}
}
public interface IMobGoal
{
public int Priority { get; }
void UpdatePriority(); // Some goals tend to decay in priority
IMobAction GetNextAction();
}
public interface IMobStrategy
{
void ReactToEvent(Mob mob, MobEvent evt);
}
public class ASimpleStrategy : IMobStrategy
{
public IMobGoal ReactToEvent(Mob mob, MobEvent evt)
{
// Based on the event type, return a goal.
if(evt.EventType == PlayerSighted)
return new MoveTowardsPlayerGoal(AReallyLargePriority);
if(evt.EventType == HeardSound)
return new DetermineSourceOfSoundGoal(ASmallerPriority);
// etc...
// Events that we don't care about can't change the goal
return null;
}
}
// A mob is an intelligent thing.
// It is basically a state machine.
// It has a state represented by its current strategy and goal, and it responds to events.
// Events may change the current goal (ooh! shiny!) or more rarely change its strategy (an enraged zombie might follow a different strategy then a passive one)
public class Mob
{
public bool CanSenseEvent(MobEvent evt);
public IMobStrategy CurrentStrategy { get; set; }
public IMobGoal CurrentGoal { get; set; }
}
public class Zombie : Mob
{
public Zombie()
{
CurrentStrategy = new StandardZombieStrategy();
CurrentGoal = new WanderGoal();
}
}
public class MobManager
{
private readonly IList<Mob> mobs = new List<Mob>();
public void HandleEvent(MobEvent evt)
{
foreach(var mob in mobs.Where(m => m.CanSense(evt))
{
var newGoal = mob.CurrentStrategy.ReactToEvent(mob, evt);
if(newGoal != null && newGoal.Priority > mob.CurrentGoal.Priority) // Perhaps randomize this a touch.
mob.CurrentGoal = newGoal;
}
}
public void Tick()
{
foreach(var mob in mobs)
{
mob.CurrentGoal.UpdatePriority();
var action = mob.CurrentGoal.GetNextAction();
if(action.CanExecute(mob))
action.Execute(mob);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment