Skip to content

Instantly share code, notes, and snippets.

@aalmada
Last active April 15, 2024 10:47
Show Gist options
  • Select an option

  • Save aalmada/a1edba42d27df7524b9f13c5e9fdfd34 to your computer and use it in GitHub Desktop.

Select an option

Save aalmada/a1edba42d27df7524b9f13c5e9fdfd34 to your computer and use it in GitHub Desktop.

Revisions

  1. aalmada revised this gist Apr 15, 2024. 2 changed files with 15 additions and 24 deletions.
    38 changes: 14 additions & 24 deletions BehaviorTree.cs
    Original file line number Diff line number Diff line change
    @@ -8,19 +8,13 @@
    using System;
    using System.Collections.Generic;

    var root = ParallelAny([
    Repeat(WriteLineRange(0, 4), 2),
    var root = ParallelAll([
    Invert(Repeat(WriteLineRange(0, 4), 2)),
    WriteLineRange(10, 10),
    ]);

    foreach(var status in root)
    foreach(var _ in root)
    {
    switch(status)
    {
    case BehaviorStatus.Succeeded:
    case BehaviorStatus.Failed:
    return;
    }
    Console.WriteLine("-");
    }

    @@ -57,7 +51,7 @@ static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus>[] c

    case BehaviorStatus.Failed:
    yield return BehaviorStatus.Failed;
    break;
    yield break;
    }
    }
    childSucceeded:
    @@ -88,7 +82,7 @@ static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus>[] c

    case BehaviorStatus.Succeeded:
    yield return BehaviorStatus.Succeeded;
    break;
    yield break;

    case BehaviorStatus.Failed:
    goto childFailed;
    @@ -109,7 +103,6 @@ static IEnumerable<BehaviorStatus> ParallelAny(IEnumerable<BehaviorStatus>[] chi

    static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus>[] children)
    {

    var enumerators = new IEnumerator<BehaviorStatus>[children.Length];
    for (var index = 0; index < enumerators.Length && index < children.Length; index++)
    enumerators[index] = children[index].GetEnumerator();
    @@ -125,11 +118,11 @@ static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus>[] c
    {
    case BehaviorStatus.Succeeded:
    yield return BehaviorStatus.Succeeded;
    break;
    yield break;

    case BehaviorStatus.Failed:
    yield return BehaviorStatus.Failed;
    break;
    yield break;
    }
    }
    yield return BehaviorStatus.Running;
    @@ -172,11 +165,12 @@ static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus>[] c
    if(succeededCounter == children.Length)
    {
    yield return BehaviorStatus.Succeeded;
    yield break;
    }
    break;
    case BehaviorStatus.Failed:
    yield return BehaviorStatus.Failed;
    break;
    yield break;
    }
    }
    }
    @@ -207,10 +201,10 @@ static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus> chi
    break;
    case BehaviorStatus.Succeeded:
    yield return BehaviorStatus.Failed;
    break;
    yield break;
    case BehaviorStatus.Failed:
    yield return BehaviorStatus.Succeeded;
    break;
    yield break;
    }
    }
    }
    @@ -239,7 +233,7 @@ static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus> chi

    case BehaviorStatus.Failed:
    yield return BehaviorStatus.Failed;
    break;
    yield break;
    }
    }
    childSucceeded:
    @@ -272,7 +266,7 @@ static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus> chi

    case BehaviorStatus.Failed:
    yield return BehaviorStatus.Succeeded;
    break;
    yield break;
    }
    }
    childSucceeded:
    @@ -313,8 +307,4 @@ class BehaviorEnumerator
    {
    public required IEnumerator<BehaviorStatus> Instance { get; init; }
    public bool Succeeded { get; set; } = false;
    }




    }
    1 change: 1 addition & 0 deletions ​BehaviorTree.output.txt
    Original file line number Diff line number Diff line change
    @@ -20,3 +20,4 @@
    16
    -
    3
    -
  2. aalmada revised this gist Apr 11, 2024. 1 changed file with 16 additions and 12 deletions.
    28 changes: 16 additions & 12 deletions BehaviorTree.cs
    Original file line number Diff line number Diff line change
    @@ -194,20 +194,24 @@ static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus>[] c
    static IEnumerable<BehaviorStatus> Invert(IEnumerable<BehaviorStatus> child)
    {
    ArgumentNullException.ThrowIfNull(child);
    return GetEnumerable(child);

    foreach(var status in child)
    {
    switch(status)
    static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus> child)
    {
    foreach(var status in child)
    {
    case BehaviorStatus.Running:
    yield return BehaviorStatus.Running;
    break;
    case BehaviorStatus.Succeeded:
    yield return BehaviorStatus.Failed;
    break;
    case BehaviorStatus.Failed:
    yield return BehaviorStatus.Succeeded;
    break;
    switch(status)
    {
    case BehaviorStatus.Running:
    yield return BehaviorStatus.Running;
    break;
    case BehaviorStatus.Succeeded:
    yield return BehaviorStatus.Failed;
    break;
    case BehaviorStatus.Failed:
    yield return BehaviorStatus.Succeeded;
    break;
    }
    }
    }
    }
  3. aalmada created this gist Apr 10, 2024.
    316 changes: 316 additions & 0 deletions BehaviorTree.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,316 @@
    /*
    SharpLab tools in Run mode:
    • value.Inspect()
    • Inspect.Heap(object)
    • Inspect.Stack(value)
    • Inspect.MemoryGraph(value1, value2, …)
    */
    using System;
    using System.Collections.Generic;

    var root = ParallelAny([
    Repeat(WriteLineRange(0, 4), 2),
    WriteLineRange(10, 10),
    ]);

    foreach(var status in root)
    {
    switch(status)
    {
    case BehaviorStatus.Succeeded:
    case BehaviorStatus.Failed:
    return;
    }
    Console.WriteLine("-");
    }

    static IEnumerable<BehaviorStatus> Succeed()
    {
    yield return BehaviorStatus.Succeeded;
    }

    static IEnumerable<BehaviorStatus> Fail()
    {
    yield return BehaviorStatus.Failed;
    }

    static IEnumerable<BehaviorStatus> Sequence(IEnumerable<BehaviorStatus>[] children)
    {
    ArgumentNullException.ThrowIfNull(children);
    return GetEnumerable(children);

    static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus>[] children)
    {
    for(var index = 0; index < children.Length; index++)
    {
    var child = children[index];
    foreach(var status in child)
    {
    switch(status)
    {
    case BehaviorStatus.Running:
    yield return BehaviorStatus.Running;
    break;

    case BehaviorStatus.Succeeded:
    goto childSucceeded;

    case BehaviorStatus.Failed:
    yield return BehaviorStatus.Failed;
    break;
    }
    }
    childSucceeded:
    if(index < children.Length - 1)
    yield return BehaviorStatus.Running;
    }
    yield return BehaviorStatus.Succeeded;
    }
    }

    static IEnumerable<BehaviorStatus> Select(IEnumerable<BehaviorStatus>[] children)
    {
    ArgumentNullException.ThrowIfNull(children);
    return GetEnumerable(children);

    static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus>[] children)
    {
    for(var index = 0; index < children.Length; index++)
    {
    var child = children[index];
    foreach(var status in child)
    {
    switch(status)
    {
    case BehaviorStatus.Running:
    yield return BehaviorStatus.Running;
    break;

    case BehaviorStatus.Succeeded:
    yield return BehaviorStatus.Succeeded;
    break;

    case BehaviorStatus.Failed:
    goto childFailed;
    }
    }
    childFailed:
    if(index < children.Length - 1)
    yield return BehaviorStatus.Running;
    }
    yield return BehaviorStatus.Failed;
    }
    }

    static IEnumerable<BehaviorStatus> ParallelAny(IEnumerable<BehaviorStatus>[] children)
    {
    ArgumentNullException.ThrowIfNull(children);
    return GetEnumerable(children);

    static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus>[] children)
    {

    var enumerators = new IEnumerator<BehaviorStatus>[children.Length];
    for (var index = 0; index < enumerators.Length && index < children.Length; index++)
    enumerators[index] = children[index].GetEnumerator();

    try
    {
    while(true)
    {
    foreach(var enumerator in enumerators)
    {
    enumerator.MoveNext();
    switch(enumerator.Current)
    {
    case BehaviorStatus.Succeeded:
    yield return BehaviorStatus.Succeeded;
    break;

    case BehaviorStatus.Failed:
    yield return BehaviorStatus.Failed;
    break;
    }
    }
    yield return BehaviorStatus.Running;
    }
    }
    finally
    {
    foreach(var enumerator in enumerators)
    enumerator.Dispose();
    }
    }
    }

    static IEnumerable<BehaviorStatus> ParallelAll(IEnumerable<BehaviorStatus>[] children)
    {
    ArgumentNullException.ThrowIfNull(children);
    return GetEnumerable(children);

    static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus>[] children)
    {
    var enumerators = new BehaviorEnumerator[children.Length];
    for (var index = 0; index < enumerators.Length && index < children.Length; index++)
    enumerators[index] = new BehaviorEnumerator { Instance = children[index].GetEnumerator() };

    try
    {
    var succeededCounter = 0;
    while(true)
    {
    foreach(var enumerator in enumerators)
    {
    if(!enumerator.Succeeded)
    {
    enumerator.Instance.MoveNext();
    switch(enumerator.Instance.Current)
    {
    case BehaviorStatus.Succeeded:
    enumerator.Succeeded = true;
    succeededCounter++;
    if(succeededCounter == children.Length)
    {
    yield return BehaviorStatus.Succeeded;
    }
    break;
    case BehaviorStatus.Failed:
    yield return BehaviorStatus.Failed;
    break;
    }
    }
    }
    yield return BehaviorStatus.Running;
    }
    }
    finally
    {
    foreach(var enumerator in enumerators)
    enumerator.Instance.Dispose();
    }
    }
    }

    static IEnumerable<BehaviorStatus> Invert(IEnumerable<BehaviorStatus> child)
    {
    ArgumentNullException.ThrowIfNull(child);

    foreach(var status in child)
    {
    switch(status)
    {
    case BehaviorStatus.Running:
    yield return BehaviorStatus.Running;
    break;
    case BehaviorStatus.Succeeded:
    yield return BehaviorStatus.Failed;
    break;
    case BehaviorStatus.Failed:
    yield return BehaviorStatus.Succeeded;
    break;
    }
    }
    }

    static IEnumerable<BehaviorStatus> Repeat(IEnumerable<BehaviorStatus> child, int count)
    {
    ArgumentNullException.ThrowIfNull(child);
    ArgumentOutOfRangeException.ThrowIfNegative(count);
    return GetEnumerable(child, count);

    static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus> child, int count)
    {
    for(var counter = 0; counter < count; counter++)
    {
    foreach(var status in child)
    {
    switch(status)
    {
    case BehaviorStatus.Running:
    yield return BehaviorStatus.Running;
    break;

    case BehaviorStatus.Succeeded:
    goto childSucceeded;

    case BehaviorStatus.Failed:
    yield return BehaviorStatus.Failed;
    break;
    }
    }
    childSucceeded:
    if(counter < count - 1)
    yield return BehaviorStatus.Running;
    }
    yield return BehaviorStatus.Succeeded;
    }
    }

    static IEnumerable<BehaviorStatus> RepeatUntilFail(IEnumerable<BehaviorStatus> child)
    {
    ArgumentNullException.ThrowIfNull(child);
    return GetEnumerable(child);

    static IEnumerable<BehaviorStatus> GetEnumerable(IEnumerable<BehaviorStatus> child)
    {
    while(true)
    {
    foreach(var status in child)
    {
    switch(status)
    {
    case BehaviorStatus.Running:
    yield return BehaviorStatus.Running;
    break;

    case BehaviorStatus.Succeeded:
    goto childSucceeded;

    case BehaviorStatus.Failed:
    yield return BehaviorStatus.Succeeded;
    break;
    }
    }
    childSucceeded:
    yield return BehaviorStatus.Running;
    }
    }
    }

    static IEnumerable<BehaviorStatus> WriteLine(string? message)
    {
    Console.WriteLine(message);

    yield return BehaviorStatus.Succeeded;
    }

    static IEnumerable<BehaviorStatus> WriteLineRange(int start, int count)
    {
    ArgumentOutOfRangeException.ThrowIfNegative(count);
    return GetEnumerable(start, count);

    static IEnumerable<BehaviorStatus> GetEnumerable(int start, int count)
    {
    var end = start + count;
    for(var value = start; value < end; value++)
    {
    Console.WriteLine(value);

    if(value < end - 1)
    yield return BehaviorStatus.Running;
    }
    yield return BehaviorStatus.Succeeded;
    }
    }

    enum BehaviorStatus { Running, Succeeded, Failed };

    class BehaviorEnumerator
    {
    public required IEnumerator<BehaviorStatus> Instance { get; init; }
    public bool Succeeded { get; set; } = false;
    }




    22 changes: 22 additions & 0 deletions ​BehaviorTree.output.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,22 @@
    0
    10
    -
    1
    11
    -
    2
    12
    -
    3
    13
    -
    0
    14
    -
    1
    15
    -
    2
    16
    -
    3
    6 changes: 6 additions & 0 deletions ​​.sharplab.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,6 @@
    {
    "version": 1,
    "target": "Run",
    "mode": "Release",
    "branch": "core-x64"
    }