├── libs └── NUnit.Should.dll ├── .gitignore ├── packages ├── NUnit.2.6.3 │ ├── license.txt │ ├── NUnit.2.6.3.nupkg │ ├── lib │ │ └── nunit.framework.dll │ └── NUnit.2.6.3.nuspec └── repositories.config ├── Tests ├── packages.config ├── Mocks │ ├── Failure.cs │ ├── Running.cs │ ├── Success.cs │ ├── FailureCounter.cs │ ├── RunningCounter.cs │ └── SuccessCounter.cs ├── ActionTests.cs ├── Tests.csproj ├── SequenceTests.cs └── SelectorTests.cs ├── BehaveN.nunit ├── BehaveN ├── IBehaviorTree.cs ├── Composite.cs ├── ITask.cs ├── Actions │ └── ActionRunner.cs ├── Task.cs ├── BehaviorTree.cs ├── Composites │ ├── Selector.cs │ └── Sequence.cs ├── Blackboard.cs └── BehaveN.csproj ├── Properties └── AssemblyInfo.cs └── BehaveN.sln /libs/NUnit.Should.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/BehaveN/master/libs/NUnit.Should.dll -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.userprefs 3 | bin 4 | obj 5 | 6 | TestResult.xml 7 | BehaveN.VisualState.xml 8 | -------------------------------------------------------------------------------- /packages/NUnit.2.6.3/license.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/BehaveN/master/packages/NUnit.2.6.3/license.txt -------------------------------------------------------------------------------- /packages/NUnit.2.6.3/NUnit.2.6.3.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/BehaveN/master/packages/NUnit.2.6.3/NUnit.2.6.3.nupkg -------------------------------------------------------------------------------- /packages/NUnit.2.6.3/lib/nunit.framework.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/BehaveN/master/packages/NUnit.2.6.3/lib/nunit.framework.dll -------------------------------------------------------------------------------- /Tests/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/repositories.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Tests/Mocks/Failure.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BehaveN; 3 | 4 | namespace Tests { 5 | public class Failure : Task { 6 | protected override TaskResult Update(Blackboard blackboard) { 7 | return TaskResult.Failure; 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /Tests/Mocks/Running.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BehaveN; 3 | 4 | namespace Tests { 5 | public class Running : Task { 6 | protected override TaskResult Update(Blackboard blackboard) { 7 | return TaskResult.Running; 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /Tests/Mocks/Success.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BehaveN; 3 | 4 | namespace Tests { 5 | public class Success : Task { 6 | protected override TaskResult Update(Blackboard blackboard) { 7 | return TaskResult.Success; 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /BehaveN.nunit: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /BehaveN/IBehaviorTree.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BehaveN { 4 | public interface IBehaviorTree { 5 | TaskResult Tick(); 6 | void SetBlackboardValue(Enum name, object value); 7 | void SetBlackboardValue(string name, object value); 8 | } 9 | } -------------------------------------------------------------------------------- /BehaveN/Composite.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace BehaveN { 5 | public abstract class Composite : Task { 6 | protected List children; 7 | 8 | public Composite() { 9 | children = new List(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Tests/Mocks/FailureCounter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BehaveN; 3 | 4 | namespace Tests { 5 | public class FailureCounter : Task { 6 | public int Count { get; set; } 7 | 8 | protected override TaskResult Update(Blackboard blackboard) { 9 | ++Count; 10 | return TaskResult.Failure; 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Tests/Mocks/RunningCounter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BehaveN; 3 | 4 | namespace Tests { 5 | public class RunningCounter : Task { 6 | public int Count { get; set; } 7 | 8 | protected override TaskResult Update(Blackboard blackboard) { 9 | ++Count; 10 | return TaskResult.Running; 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Tests/Mocks/SuccessCounter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BehaveN; 3 | 4 | namespace Tests { 5 | public class SuccessCounter : Task { 6 | public int Count { get; set; } 7 | 8 | protected override TaskResult Update(Blackboard blackboard) { 9 | ++Count; 10 | return TaskResult.Success; 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /BehaveN/ITask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BehaveN { 4 | public enum TaskResult { 5 | NotInitialized, 6 | Running, 7 | Success, 8 | Failure, 9 | } 10 | 11 | public interface ITask { 12 | TaskResult Tick(Blackboard blackboard); 13 | void OnInitialize(Blackboard blackboard); 14 | void OnReset(Blackboard blackboard); 15 | } 16 | } -------------------------------------------------------------------------------- /BehaveN/Actions/ActionRunner.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BehaveN { 4 | public class ActionRunner : Task { 5 | Func action; 6 | 7 | public ActionRunner(Func action) { 8 | this.action = action; 9 | } 10 | 11 | protected override TaskResult Update(Blackboard blackboard) { 12 | return action(blackboard); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /BehaveN/Task.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace BehaveN 5 | { 6 | public abstract class Task : ITask 7 | { 8 | TaskResult status = TaskResult.NotInitialized; 9 | 10 | public TaskResult Tick(Blackboard blackboard) { 11 | if (status == TaskResult.NotInitialized) { 12 | OnInitialize(blackboard); 13 | } 14 | 15 | status = Update(blackboard); 16 | 17 | if (status != TaskResult.Running) { 18 | OnReset(blackboard); 19 | } 20 | 21 | return status; 22 | } 23 | 24 | public virtual void OnInitialize(Blackboard blackboard) { } 25 | public virtual void OnReset(Blackboard blackboard) { } 26 | 27 | protected abstract TaskResult Update(Blackboard blackboard); 28 | } 29 | } -------------------------------------------------------------------------------- /BehaveN/BehaviorTree.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BehaveN { 4 | public class BehaviorTree : IBehaviorTree { 5 | protected Blackboard Blackboard { get; private set; } 6 | protected ITask RootNode { get; set; } 7 | 8 | public BehaviorTree() : this(new Blackboard()) { } 9 | 10 | public BehaviorTree(Blackboard blackboard) { 11 | Blackboard = blackboard; 12 | } 13 | 14 | public BehaviorTree(ITask rootNode) : this(rootNode, null) { } 15 | 16 | public BehaviorTree(ITask rootNode, Blackboard blackboard) : this(blackboard) { 17 | RootNode = rootNode; 18 | } 19 | 20 | public virtual TaskResult Tick() { 21 | return RootNode.Tick(Blackboard); 22 | } 23 | 24 | public void SetBlackboardValue(Enum name, object value) { 25 | Blackboard.Set(name, value); 26 | } 27 | 28 | public void SetBlackboardValue(string name, object value) { 29 | Blackboard.Set(name, value); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // Information about this assembly is defined by the following attributes. 5 | // Change them to the values specific to your project. 6 | [assembly: AssemblyTitle("BehaviorTreeLib")] 7 | [assembly: AssemblyDescription("")] 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("")] 11 | [assembly: AssemblyCopyright("dkoontz")] 12 | [assembly: AssemblyTrademark("")] 13 | [assembly: AssemblyCulture("")] 14 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 15 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 16 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 17 | [assembly: AssemblyVersion("1.0.*")] 18 | // The following attributes are used to specify the signing key for the assembly, 19 | // if desired. See the Mono documentation for more information about signing. 20 | //[assembly: AssemblyDelaySign(false)] 21 | //[assembly: AssemblyKeyFile("")] 22 | 23 | -------------------------------------------------------------------------------- /BehaveN/Composites/Selector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace BehaveN { 5 | /// 6 | /// Runs each Behavior until one return Success or Running. 7 | /// Returns Failure if no Behaviors return Success. 8 | /// 9 | public class Selector : Composite { 10 | List.Enumerator childEnumerator; 11 | TaskResult previousStatus; 12 | bool atEndOfList; 13 | 14 | public Selector(params Task[] behaviors) { 15 | children = new List(behaviors); 16 | } 17 | 18 | public override void OnInitialize(Blackboard blackboard) { 19 | childEnumerator = children.GetEnumerator(); 20 | atEndOfList = false; 21 | } 22 | 23 | protected override TaskResult Update(Blackboard blackboard) { 24 | TaskResult currentStatus = TaskResult.Failure; 25 | 26 | if (previousStatus == TaskResult.Success || atEndOfList) { 27 | OnInitialize(blackboard); 28 | } 29 | 30 | if (previousStatus == TaskResult.Running) { 31 | currentStatus = childEnumerator.Current.Tick(blackboard); 32 | previousStatus = currentStatus; 33 | } 34 | 35 | while (currentStatus == TaskResult.Failure && !atEndOfList) { 36 | atEndOfList = !childEnumerator.MoveNext(); 37 | if (!atEndOfList) { 38 | currentStatus = childEnumerator.Current.Tick(blackboard); 39 | previousStatus = currentStatus; 40 | } 41 | } 42 | 43 | return currentStatus; 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /Tests/ActionTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | using BehaveN; 4 | 5 | namespace Tests { 6 | [TestFixture] 7 | public class ActionTests { 8 | 9 | [Test] 10 | public void Action_returns_result_from_delegate() { 11 | var action = new ActionRunner( Blackboard => TaskResult.Success ); 12 | Assert.AreEqual(TaskResult.Success, action.Tick(new Blackboard())); 13 | 14 | action = new ActionRunner( Blackboard => TaskResult.Failure ); 15 | Assert.AreEqual(TaskResult.Failure, action.Tick(new Blackboard())); 16 | 17 | action = new ActionRunner( Blackboard => TaskResult.Running ); 18 | Assert.AreEqual(TaskResult.Running, action.Tick(new Blackboard())); 19 | } 20 | 21 | [Test] 22 | public void Action_invokes_delegate_when_tick_is_called() { 23 | bool wasCalled = false; 24 | var action = new ActionRunner( Blackboard => { 25 | wasCalled = true; 26 | return TaskResult.Success; 27 | }); 28 | action.Tick(new Blackboard()); 29 | Assert.AreEqual(true, wasCalled); 30 | } 31 | 32 | [Test] 33 | public void Action_has_access_to_Blackboard_variables() { 34 | var Blackboard = new Blackboard(); 35 | Blackboard.Set("score", 10); 36 | 37 | var action = new ActionRunner(ctx => { 38 | ctx.Set("score", ctx.Get("score") + 1); 39 | return TaskResult.Success; 40 | }); 41 | action.Tick(Blackboard); 42 | 43 | Assert.AreEqual(11, Blackboard.Get("score")); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /BehaveN/Composites/Sequence.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections.Generic; 4 | 5 | namespace BehaveN { 6 | /// 7 | /// Runs each Behavior until one returns Failure or Running. 8 | /// Returns Success if all Behaviors return Success. 9 | /// 10 | public class Sequence : Composite { 11 | List.Enumerator childEnumerator; 12 | TaskResult previousStatus; 13 | bool atEndOfList; 14 | 15 | public Sequence(params Task[] behaviors) { 16 | children = new List(behaviors); 17 | } 18 | 19 | public override void OnInitialize(Blackboard blackboard) { 20 | childEnumerator = children.GetEnumerator(); 21 | atEndOfList = false; 22 | } 23 | 24 | protected override TaskResult Update(Blackboard blackboard) { 25 | TaskResult currentStatus = TaskResult.Success; 26 | 27 | if (previousStatus == TaskResult.Failure || atEndOfList) { 28 | OnInitialize(blackboard); 29 | } 30 | 31 | if (previousStatus == TaskResult.Running) { 32 | currentStatus = childEnumerator.Current.Tick(blackboard); 33 | previousStatus = currentStatus; 34 | } 35 | 36 | while (currentStatus == TaskResult.Success && !atEndOfList) { 37 | atEndOfList = !childEnumerator.MoveNext(); 38 | if (!atEndOfList) { 39 | currentStatus = childEnumerator.Current.Tick(blackboard); 40 | previousStatus = currentStatus; 41 | } 42 | } 43 | 44 | return currentStatus; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /packages/NUnit.2.6.3/NUnit.2.6.3.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | NUnit 5 | 2.6.3 6 | NUnit 7 | Charlie Poole 8 | Charlie Poole 9 | http://nunit.org/nuget/license.html 10 | http://nunit.org/ 11 | http://nunit.org/nuget/nunit_32x32.png 12 | false 13 | NUnit features a fluent assert syntax, parameterized, generic and theory tests and is user-extensible. A number of runners, both from the NUnit project and by third parties, are able to execute NUnit tests. 14 | 15 | Version 2.6 is the seventh major release of this well-known and well-tested programming tool. 16 | 17 | This package includes only the framework assembly. You will need to install the NUnit.Runners package unless you are using a third-party runner. 18 | NUnit is a unit-testing framework for all .Net languages with a strong TDD focus. 19 | Version 2.6 is the seventh major release of NUnit. 20 | 21 | Unlike earlier versions, this package includes only the framework assembly. You will need to install the NUnit.Runners package unless you are using a third-party runner. 22 | 23 | The nunit.mocks assembly is now provided by the NUnit.Mocks package. The pnunit.framework assembly is provided by the pNUnit package. 24 | en-US 25 | nunit test testing tdd framework fluent assert theory plugin addin 26 | 27 | -------------------------------------------------------------------------------- /BehaveN/Blackboard.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace BehaveN 5 | { 6 | public class Blackboard { 7 | Dictionary values; 8 | 9 | public Blackboard() { 10 | values = new Dictionary(); 11 | } 12 | 13 | public Blackboard(Dictionary initialValues) : this() { 14 | foreach (var kvp in initialValues) { 15 | Set(kvp.Key, kvp.Value); 16 | } 17 | } 18 | 19 | public Blackboard(Dictionary initialValues) : this() { 20 | foreach (var kvp in initialValues) { 21 | Set(kvp.Key, kvp.Value); 22 | } 23 | } 24 | 25 | public T Get(Enum name) { 26 | return Get(EnumValueToString(name)); 27 | } 28 | 29 | public T Get(string name) { 30 | object result; 31 | if (values.TryGetValue(name, out result)) { 32 | return (T)result; 33 | } 34 | else { 35 | throw new InvalidOperationException("Blackboard does not contain a value for " + name); 36 | } 37 | } 38 | 39 | public T GetOrCreate(Enum name) { 40 | return GetOrCreate(EnumValueToString(name)); 41 | } 42 | 43 | public T GetOrCreate(string name) { 44 | object result; 45 | if (!values.TryGetValue(name, out result)) { 46 | result = default(T); 47 | values[name] = result; 48 | } 49 | return (T)result; 50 | } 51 | 52 | public void Set(Enum name, object value) { 53 | Set(EnumValueToString(name), value); 54 | } 55 | 56 | public void Set(string name, object value) { 57 | values[name] = value; 58 | } 59 | 60 | public bool HasVariable(Enum name) { 61 | return HasVariable(EnumValueToString(name)); 62 | } 63 | 64 | public bool HasVariable(string name) { 65 | return values.ContainsKey(name); 66 | } 67 | 68 | protected static string EnumValueToString(Enum value) { 69 | return string.Format("{0}.{1}", value.GetType(), value); 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /BehaveN/BehaveN.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.0 7 | 2.0 8 | {7711129E-2435-4025-BCCB-16A64BBF8284} 9 | Library 10 | BehaveN 11 | BehaveN 12 | 13 | 14 | true 15 | full 16 | false 17 | bin\Debug 18 | DEBUG; 19 | prompt 20 | 4 21 | false 22 | 23 | 24 | full 25 | true 26 | bin\Release 27 | prompt 28 | 4 29 | false 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Tests/Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.0 7 | 2.0 8 | {0CB842A8-D408-4F0B-A5DD-AC868031DA40} 9 | Library 10 | Tests 11 | Tests 12 | 13 | 14 | true 15 | full 16 | false 17 | bin\Debug 18 | DEBUG; 19 | prompt 20 | 4 21 | false 22 | 23 | 24 | full 25 | true 26 | bin\Release 27 | prompt 28 | 4 29 | false 30 | 31 | 32 | 33 | 34 | ..\libs\NUnit.Should.dll 35 | 36 | 37 | ..\packages\NUnit.2.6.3\lib\nunit.framework.dll 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | {7711129E-2435-4025-BCCB-16A64BBF8284} 58 | BehaveN 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /Tests/SequenceTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | using BehaveN; 4 | 5 | namespace Tests { 6 | [TestFixture] 7 | public class SequenceTests { 8 | [Test] 9 | public void Sequence_returns_success_with_zero_children() { 10 | var sequence = new Sequence(); 11 | sequence.Tick(new Blackboard()).ShouldEqual(TaskResult.Success); 12 | } 13 | 14 | [Test] 15 | public void Sequence_returns_after_first_failure() { 16 | var counter = new SuccessCounter(); 17 | var sequence = new Sequence(new Failure()); 18 | sequence.Tick(new Blackboard()); 19 | counter.Count.ShouldEqual(0); 20 | } 21 | 22 | [Test] 23 | public void Sequence_runs_all_behaviors_until_a_non_success_result() { 24 | var counter1 = new SuccessCounter(); 25 | var counter2 = new SuccessCounter(); 26 | var counter3 = new SuccessCounter(); 27 | var sequence = new Sequence(counter1, counter2, new Failure(), counter3); 28 | sequence.Tick(new Blackboard()); 29 | counter1.Count.ShouldEqual(1); 30 | counter2.Count.ShouldEqual(1); 31 | counter3.Count.ShouldEqual(0); 32 | } 33 | 34 | [Test] 35 | public void Sequence_returns_success_when_all_behaviors_are_successful() { 36 | var sequence = new Sequence(new Success(), new Success(), new Success()); 37 | sequence.Tick(new Blackboard()).ShouldEqual(TaskResult.Success); 38 | } 39 | 40 | [Test] 41 | public void Sequence_passes_along_result_from_behavior_if_not_successful() { 42 | var sequence = new Sequence(new Success(), new Failure(), new Success()); 43 | sequence.Tick(new Blackboard()).ShouldEqual(TaskResult.Failure); 44 | 45 | sequence = new Sequence(new Success(), new Running(), new Success()); 46 | sequence.Tick(new Blackboard()).ShouldEqual(TaskResult.Running); 47 | } 48 | 49 | [Test] 50 | public void Sequence_resumes_at_running_node() { 51 | var successCounter = new SuccessCounter(); 52 | var runningCounter = new RunningCounter(); 53 | var sequence = new Sequence(successCounter, runningCounter); 54 | var Blackboard = new Blackboard(); 55 | sequence.Tick(Blackboard); 56 | successCounter.Count.ShouldEqual(1); 57 | runningCounter.Count.ShouldEqual(1); 58 | sequence.Tick(Blackboard); 59 | successCounter.Count.ShouldEqual(1); 60 | runningCounter.Count.ShouldEqual(2); 61 | } 62 | 63 | [Test] 64 | public void Sequence_starts_at_first_node_on_next_tick_after_successfully_running_all_nodes() { 65 | var successCounter = new SuccessCounter(); 66 | var successCounter2 = new SuccessCounter(); 67 | var sequence = new Sequence(successCounter, successCounter2); 68 | var Blackboard = new Blackboard(); 69 | sequence.Tick(Blackboard); 70 | successCounter.Count.ShouldEqual(1); 71 | successCounter2.Count.ShouldEqual(1); 72 | sequence.Tick(Blackboard); 73 | successCounter.Count.ShouldEqual(2); 74 | successCounter2.Count.ShouldEqual(2); 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /BehaveN.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BehaveN", "BehaveN\BehaveN.csproj", "{7711129E-2435-4025-BCCB-16A64BBF8284}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{0CB842A8-D408-4F0B-A5DD-AC868031DA40}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {0CB842A8-D408-4F0B-A5DD-AC868031DA40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {0CB842A8-D408-4F0B-A5DD-AC868031DA40}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {0CB842A8-D408-4F0B-A5DD-AC868031DA40}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {0CB842A8-D408-4F0B-A5DD-AC868031DA40}.Release|Any CPU.Build.0 = Release|Any CPU 18 | {7711129E-2435-4025-BCCB-16A64BBF8284}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {7711129E-2435-4025-BCCB-16A64BBF8284}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {7711129E-2435-4025-BCCB-16A64BBF8284}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {7711129E-2435-4025-BCCB-16A64BBF8284}.Release|Any CPU.Build.0 = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(MonoDevelopProperties) = preSolution 24 | StartupItem = Tests\Tests.csproj 25 | Policies = $0 26 | $0.DotNetNamingPolicy = $1 27 | $1.DirectoryNamespaceAssociation = None 28 | $1.ResourceNamePolicy = FileFormatDefault 29 | $0.TextStylePolicy = $2 30 | $2.TabsToSpaces = False 31 | $2.inheritsSet = VisualStudio 32 | $2.inheritsScope = text/plain 33 | $2.scope = text/x-csharp 34 | $0.CSharpFormattingPolicy = $3 35 | $3.IndentSwitchBody = True 36 | $3.NamespaceBraceStyle = EndOfLine 37 | $3.ClassBraceStyle = EndOfLine 38 | $3.InterfaceBraceStyle = EndOfLine 39 | $3.StructBraceStyle = EndOfLine 40 | $3.EnumBraceStyle = EndOfLine 41 | $3.MethodBraceStyle = EndOfLine 42 | $3.ConstructorBraceStyle = EndOfLine 43 | $3.DestructorBraceStyle = EndOfLine 44 | $3.ElseNewLinePlacement = NewLine 45 | $3.CatchNewLinePlacement = NewLine 46 | $3.FinallyNewLinePlacement = NewLine 47 | $3.WhileNewLinePlacement = NewLine 48 | $3.EmbeddedStatementPlacement = SameLine 49 | $3.ArrayInitializerBraceStyle = NextLine 50 | $3.BeforeMethodDeclarationParentheses = False 51 | $3.BeforeMethodCallParentheses = False 52 | $3.BeforeConstructorDeclarationParentheses = False 53 | $3.BeforeIndexerDeclarationBracket = False 54 | $3.BeforeDelegateDeclarationParentheses = False 55 | $3.AfterDelegateDeclarationParameterComma = True 56 | $3.NewParentheses = False 57 | $3.SpacesBeforeBrackets = False 58 | $3.inheritsSet = Mono 59 | $3.inheritsScope = text/x-csharp 60 | $3.scope = text/x-csharp 61 | $0.TextStylePolicy = $4 62 | $4.FileWidth = 120 63 | $4.TabsToSpaces = False 64 | $4.inheritsSet = VisualStudio 65 | $4.inheritsScope = text/plain 66 | $4.scope = text/plain 67 | EndGlobalSection 68 | EndGlobal 69 | -------------------------------------------------------------------------------- /Tests/SelectorTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | using BehaveN; 4 | 5 | namespace Tests { 6 | [TestFixture] 7 | public class SelectorTests { 8 | 9 | [Test] 10 | public void Selector_returns_failure_with_zero_children() { 11 | var selector = new Selector(); 12 | Assert.AreEqual(TaskResult.Failure, selector.Tick(new Blackboard())); 13 | } 14 | 15 | [Test] 16 | public void Selector_returns_success_if_first_non_failing_child_returns_success() { 17 | var selector = new Selector(new Success()); 18 | Assert.AreEqual(TaskResult.Success, selector.Tick(new Blackboard())); 19 | 20 | selector = new Selector(new Failure(), new Success()); 21 | Assert.AreEqual(TaskResult.Success, selector.Tick(new Blackboard())); 22 | 23 | selector = new Selector(new Running(), new Success()); 24 | Assert.AreNotEqual(TaskResult.Success, selector.Tick(new Blackboard())); 25 | } 26 | 27 | [Test] 28 | public void Selector_returns_running_if_first_non_failing_child_returns_running() { 29 | var selector = new Selector(new Running()); 30 | Assert.AreEqual(TaskResult.Running, selector.Tick(new Blackboard())); 31 | 32 | selector = new Selector(new Failure(), new Running()); 33 | Assert.AreEqual(TaskResult.Running, selector.Tick(new Blackboard())); 34 | 35 | selector = new Selector(new Success(), new Running()); 36 | Assert.AreNotEqual(TaskResult.Running, selector.Tick(new Blackboard())); 37 | } 38 | 39 | [Test] 40 | public void Selector_runs_all_behaviors_until_success_or_running_result() { 41 | var counter1 = new FailureCounter(); 42 | var counter2 = new FailureCounter(); 43 | 44 | var selector = new Selector(counter1, new Success(), counter2); 45 | selector.Tick(new Blackboard()); 46 | Assert.AreEqual(1, counter1.Count); 47 | Assert.AreEqual(0, counter2.Count); 48 | 49 | counter1 = new FailureCounter(); 50 | counter2 = new FailureCounter(); 51 | 52 | selector = new Selector(counter1, new Running(), counter2); 53 | selector.Tick(new Blackboard()); 54 | Assert.AreEqual(1, counter1.Count); 55 | Assert.AreEqual(0, counter2.Count); 56 | } 57 | 58 | [Test] 59 | public void Selector_resumes_at_running_node() { 60 | var failureCounter = new FailureCounter(); 61 | var runningCounter = new RunningCounter(); 62 | var selector = new Selector(failureCounter, runningCounter); 63 | var Blackboard = new Blackboard(); 64 | selector.Tick(Blackboard); 65 | failureCounter.Count.ShouldEqual(1); 66 | runningCounter.Count.ShouldEqual(1); 67 | selector.Tick(Blackboard); 68 | failureCounter.Count.ShouldEqual(1); 69 | runningCounter.Count.ShouldEqual(2); 70 | } 71 | 72 | [Test] 73 | public void Selector_starts_at_first_node_on_next_tick_after_all_nodes_fail() { 74 | var failCounter = new FailureCounter(); 75 | var failCounter2 = new FailureCounter(); 76 | var selector = new Selector(failCounter, failCounter2); 77 | var Blackboard = new Blackboard(); 78 | selector.Tick(Blackboard); 79 | failCounter.Count.ShouldEqual(1); 80 | failCounter2.Count.ShouldEqual(1); 81 | selector.Tick(Blackboard); 82 | failCounter.Count.ShouldEqual(2); 83 | failCounter2.Count.ShouldEqual(2); 84 | } 85 | } 86 | } --------------------------------------------------------------------------------