Skip to content

Commit

Permalink
feat(composites): new selector random node
Browse files Browse the repository at this point in the history
Selects the first node to return success and shuffles ever time it's run. Optimized for performance.
  • Loading branch information
ashblue committed May 31, 2019
1 parent cec1d36 commit 0e13b8d
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ public BehaviorTreeBuilder Selector (string name = "selector") {
return ParentTask<Selector>(name);
}

/// <summary>
/// Selects the first node to return success
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public BehaviorTreeBuilder SelectorRandom (string name = "selector random") {
return ParentTask<SelectorRandom>(name);
}

public BehaviorTreeBuilder Parallel (string name = "parallel") {
return ParentTask<Parallel>(name);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using Adnc.FluidBT.Tasks;
using Random = System.Random;

namespace Adnc.FluidBT.TaskParents.Composites {
/// <summary>
/// Randomly selects a child node with a shuffle algorithm
/// </summary>
public class SelectorRandom : CompositeBase {
private bool _init;

protected override TaskStatus OnUpdate () {
if (!_init) {
ShuffleChildren();
_init = true;
}

for (var i = ChildIndex; i < Children.Count; i++) {
var child = Children[ChildIndex];

switch (child.Update()) {
case TaskStatus.Success:
return TaskStatus.Success;
case TaskStatus.Continue:
return TaskStatus.Continue;
}

ChildIndex++;
}

return TaskStatus.Failure;
}

public override void Reset () {
base.Reset();

ShuffleChildren();
}

private void ShuffleChildren () {
var rng = new Random();
var n = Children.Count;
while (n > 1) {
n--;
var k = rng.Next(n + 1);
var value = Children[k];
Children[k] = Children[n];
Children[n] = value;
}
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ public void BeforeEach () {
_invokeCount = 0;
_builder = new BehaviorTreeBuilder(null);
}

public class SelectorRandomMethod : BehaviorTreeBuilderTest {
public void It_should_add_a_random_selector () {
var tree = _builder
.SelectorRandom("random selector")
.Build();

var selectorRandom = tree.Root.Children[0] as SelectorRandom;

Assert.IsNotNull(selectorRandom);
}
}

public class SequenceMethod : BehaviorTreeBuilderTest {
[Test]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using Adnc.FluidBT.Tasks;
using Adnc.FluidBT.Testing;
using NUnit.Framework;

namespace Adnc.FluidBT.TaskParents.Composites.Editors.Tests {
public class SelectorRandomTest {
public class UpdateMethod {
[Test]
public void It_should_return_success_if_a_child_returns_success () {
var child = A.TaskStub().WithUpdateStatus(TaskStatus.Success).Build();
var selectorRandom = new SelectorRandom();
selectorRandom.AddChild(child);

Assert.AreEqual(TaskStatus.Success, selectorRandom.Update());
}

[Test]
public void It_should_return_continue_if_a_child_returns_continue () {
var child = A.TaskStub().WithUpdateStatus(TaskStatus.Continue).Build();
var selectorRandom = new SelectorRandom();
selectorRandom.AddChild(child);

Assert.AreEqual(TaskStatus.Continue, selectorRandom.Update());
}

[Test]
public void It_should_return_failure_if_empty () {
var selectorRandom = new SelectorRandom();

Assert.AreEqual(TaskStatus.Failure, selectorRandom.Update());

}

[Test]
public void It_should_return_failure_if_child_returns_failure () {
var child = A.TaskStub().WithUpdateStatus(TaskStatus.Failure).Build();
var selectorRandom = new SelectorRandom();
selectorRandom.AddChild(child);

Assert.AreEqual(TaskStatus.Failure, selectorRandom.Update());

}
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 0e13b8d

Please sign in to comment.