Skip to content

Instantly share code, notes, and snippets.

@Andrea
Created May 3, 2014 15:30
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save Andrea/5b8dfa9daff76ffcf3b9 to your computer and use it in GitHub Desktop.
Simplest Behaviour Tree
using System;
namespace SimplestBehaviourTree
{
class Program
{
static void Main(string[] args)
{
new RunTree().Run();
Console.ReadLine();
}
}
public class RunTree
{
private int i = 0;
public void Run()
{
var plant = new Action(PlantSeeds);
var plantIfThereIsSpace = new Selector(new Action(WeedsNotCoveringGround), plant);
var sequenece = new Sequence(new Action(GetToPlantingGrounds), plant);
var root = new Selector(sequenece, plantIfThereIsSpace);
//set a reference to the root
var behaviour = new Behavior(root);
behaviour.Behave();
}
private Result GetToPlantingGrounds()
{
if(i++<10)
{
Console.WriteLine("Action - searching planting grounds");
return Result.Running;
}
return Result.Success;
}
private static Result PlantSeeds()
{
Console.WriteLine("Action - plant ");
return Result.Success;
}
private static Result WeedsNotCoveringGround()
{
Console.WriteLine("Conditional - Is there space ");
return Result.Failure;
}
}
public enum Result
{
Failure,
Success,
Running
}
public class Action : BehaviorComponent
{
private readonly Func<Result> _action;
public Action(Func<Result> action)
{
_action = action;
}
public override Result Behave()
{
switch (_action.Invoke())
{
case Result.Success:
ReturnCode = Result.Success;
return ReturnCode;
case Result.Failure:
ReturnCode = Result.Failure;
return ReturnCode;
case Result.Running:
ReturnCode = Result.Running;
return ReturnCode;
default:
ReturnCode = Result.Failure;
return ReturnCode;
}
}
}
public interface IComposite
{
}
public abstract class BehaviorComponent
{
protected Result ReturnCode;
public abstract Result Behave();
}
public class Behavior
{
private readonly BehaviorComponent _root;
public Result ReturnCode { get; set; }
public Behavior(IComposite root)
{
_root = root as BehaviorComponent;
}
public Result Behave()
{
ReturnCode = _root.Behave();
return ReturnCode;
}
}
public class Selector : BehaviorComponent, IComposite
{
private readonly BehaviorComponent[] _behaviors;
public Selector(params BehaviorComponent[] behaviors)
{
_behaviors = behaviors;
}
public override Result Behave()
{
for (int index = 0; index < _behaviors.Length; )
{
var behaviorComponent = _behaviors[index];
switch (behaviorComponent.Behave())
{
case Result.Failure:
index++;
continue;
case Result.Success:
index++;
ReturnCode = Result.Success;
return ReturnCode;
case Result.Running:
ReturnCode = Result.Running;
return ReturnCode;
default:
continue;
}
}
return ReturnCode;
}
}
public class Sequence : BehaviorComponent, IComposite
{
private readonly BehaviorComponent[] _behaviors;
public Sequence(params BehaviorComponent[] behaviors)
{
_behaviors = behaviors;
}
public override Result Behave()
{
for (int index = 0; index < _behaviors.Length; )
{
var behaviorComponent = _behaviors[index];
switch (behaviorComponent.Behave())
{
case Result.Success:
index++;
continue;
case Result.Failure:
index++;
ReturnCode = Result.Failure;
return ReturnCode;
case Result.Running:
continue;
default:
ReturnCode = Result.Success;
continue;
}
}
return ReturnCode;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment