예제 #1
0
        public void RandomTest()
        {
            var blackboard = new TestBlackboard();
            var node       = new Random <TestBlackboard>();
            var tree       = BehaviorTreeBuilder <TestBlackboard> .Begin()
                             .Sequence()
                             .Decorator(node).Leaf(new TrackingLeaf())
                             .Build(blackboard);

            ushort[] result = new ushort[2];
            for (var i = 0; i < 100; i++)
            {
                this.UpdateAndStep(tree, 0.1f);
                if (node.Status == BTTaskStatus.Succeeded)
                {
                    result[1]++;
                }
                else
                {
                    result[0]++;
                }
            }

            // We should get a decently even spread but we can't rely on it, 50% sway should be plenty enough to have a stable result
            Assert.Greater(result[0], 25);
            Assert.Greater(result[1], 25);

            Assert.AreEqual(100, blackboard.GetTracking(TestBlackboard.TrackingExecution));
        }
 public static BehaviorTreeBuilder ExampleAction(this BehaviorTreeBuilder builder, string name, Action callback)
 {
     return(builder.AddNode(new BehaviorTreeBuilderExtensionActionTest.ExtensionAction {
         Name = name,
         callback = callback,
     }));
 }
예제 #3
0
    [Test] public void TreeA()
    {
        MockCondition isSafe = new MockCondition(BehaviorStatus.Failure);
        MockCondition isFoodNearby = new MockCondition(BehaviorStatus.Success);
        MockAction run = new MockAction(BehaviorStatus.Running);
        MockAction eat = new MockAction(BehaviorStatus.Running);

        BehaviorTree behaviorTree = new BehaviorTreeBuilder<BehaviorTree>(new Selector())
            .Sequence("Run")
                .Decorator(new Invert())
                    .Condition(isSafe)
                .Action(run)
            .End()
            .Sequence("Eat")
                .Condition(isFoodNearby)
                .Action(eat)
            .End()
        .Build();

        Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Running);

        run.status = BehaviorStatus.Success;
        Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Success);

        isSafe.status = BehaviorStatus.Success;
        Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Running);

        eat.status = BehaviorStatus.Success;
        Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Success);

        isFoodNearby.status = BehaviorStatus.Failure;
        Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Failure);
    }
예제 #4
0
    [Test] public void Action_Success()
    {
        BehaviorTree behaviorTree = new BehaviorTreeBuilder<BehaviorTree>(new Selector())
            .Action(new MockAction(BehaviorStatus.Success))
        .Build();

        Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Success);
    }
예제 #5
0
    [Test] public void Condition_Failure()
    {
        BehaviorTree behaviorTree = new BehaviorTreeBuilder<BehaviorTree>(new Selector())
            .Condition(new MockCondition(BehaviorStatus.Failure))
        .Build();

        Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Failure);
    }
예제 #6
0
    [Test] public void Sequence_BothChildrenFailure()
    {
        BehaviorTree behaviorTree = new BehaviorTreeBuilder<BehaviorTree>(new Sequence())
            .Condition(new MockCondition(BehaviorStatus.Failure))
            .Condition(new MockCondition(BehaviorStatus.Failure))
        .Build();

        Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Failure);
    }
예제 #7
0
    [Test] public void Sequence_FirstChildFailureAndNextChildSuccess()
    {
        BehaviorTree behaviorTree = new BehaviorTreeBuilder<BehaviorTree>(new Sequence())
            .Condition(new MockCondition(BehaviorStatus.Failure))
            .Condition(new MockCondition(BehaviorStatus.Success))
        .Build();

        Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Failure);
    }
예제 #8
0
    [Test] public void Selector_BothChildrenSuccess()
    {
        BehaviorTree behaviorTree = new BehaviorTreeBuilder<BehaviorTree>(new Selector())
            .Condition(new MockCondition(BehaviorStatus.Success))
            .Condition(new MockCondition(BehaviorStatus.Success))
        .Build();

        Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Success);
    }
예제 #9
0
    [Test] public void Decorator_Invert_ChildFailure()
    {
        BehaviorTree behaviorTree = new BehaviorTreeBuilder<BehaviorTree>(new Selector())
            .Decorator(new Invert())
                .Condition(new MockCondition(BehaviorStatus.Failure))
        .Build();

        Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Success);
    }
예제 #10
0
    [Test] public void Decorator_Repeat_ChildFailure()
    {
        Repeat repeat = new Repeat(10);

        BehaviorTree behaviorTree = new BehaviorTreeBuilder<BehaviorTree>(new Selector())
            .Decorator(repeat)
                .Condition(new MockCondition(BehaviorStatus.Failure))
        .Build();

        Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Failure);
        Assert.IsTrue(repeat.repetitionCount == 0);
    }
예제 #11
0
        private void bulidSelfAbortTree()
        {
            var builder = BehaviorTreeBuilder <SlimeBehaviorTree> .begin(this);

            builder.selector(AbortTypes.Self);
            builder.conditionalDecorator(m =>
            {
                return(m.slime.actorProperty.HP <= 0);
            }, false);
            builder.sequence()
            .logAction("-- dead! --")
            .action(m => m.slime.dead())
            .endComposite();

            builder.conditionalDecorator(m =>
            {
                return(m.slime.startLostTarget);
            });
            builder.sequence()
            .logAction("-- lostTarget!--")
            .action(m => m.slime.lostTarget())
            .endComposite();

            builder.conditionalDecorator(
                m => m.slime.isLostTarget, false
                );
            builder.sequence()
            .logAction("--back! --")
            .action(m => m.slime.back())
            .endComposite();

            builder.conditionalDecorator(
                m => m.slime.isFindTarget, false
                );
            builder.sequence()
            .logAction("--chase! --")
            .action(m => m.slime.chase())
            .endComposite();


            builder.sequence()
            .logAction("--idle --")
            //.action(m => m.slime.idle())
            .waitAction(2f)
            .action(m => m.slime.patrol())
            .endComposite()
            ;

            builder.endComposite();

            tree = builder.build(1f / 60);
        }
예제 #12
0
        protected override IBehaviorTreeNode createBehaviorTree()
        {
            BehaviorTreeBuilder builder = new BehaviorTreeBuilder();

            return(AIExtensions.WithFightingAI(
                       builder
                       .Sequence()

                       .End()
                       .Build(),
                       Entity
                       ));
        }
        static BehaviorTreeDesc BuildTreeDesc()
        {
            var builder = new BehaviorTreeBuilder();

            builder.Composite <SequenceTaskDesc>()
            .AppendChild(builder.Leaf <LogTaskDesc>(
                             d => d.Message = "Start"))
            .AppendChild(builder.Leaf <WaitTimerTaskDesc>(
                             d => d.Time = new VariableDesc(VariableType.UInteger, VariableSource.LiteralConstant, "3000")))
            .AppendChild(builder.Leaf <LogTaskDesc>(d =>
                                                    d.Message = "End"));
            return(builder.Build());
        }
        public void It_should_run_the_custom_action()
        {
            var result = false;
            var tree   = new BehaviorTreeBuilder(null)
                         .Sequence()
                         .ExampleAction("test", () => result = true)
                         .End()
                         .Build();

            tree.Tick();

            Assert.IsTrue(result);
        }
예제 #15
0
        protected override IBehaviorTreeNode createBehaviorTree()
        {
            BehaviorTreeBuilder builder = new BehaviorTreeBuilder();

            return(AIExtensions.WithFightingAI(
                       builder
                       .Sequence()
                       .LongRunningResultCached(() => new WaitTask(Entity, TimeSpan.FromMilliseconds(1000)))
                       .LongRunningResultCached(() => new WanderTask(Entity, BlockStartPosition, BlockRadius))
                       .End()
                       .Build(),
                       Entity
                       ));
        }
예제 #16
0
    [Test] public void Sequence_FirstChildRunningAndNextChildSuccess()
    {
        MockAction mockActionA = new MockAction(BehaviorStatus.Running);

        BehaviorTree behaviorTree = new BehaviorTreeBuilder<BehaviorTree>(new Sequence())
            .Action(mockActionA)
            .Condition(new MockCondition(BehaviorStatus.Success))
        .Build();

        Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Running);

        mockActionA.status = BehaviorStatus.Failure;
        Assert.IsTrue(behaviorTree.Tick() == BehaviorStatus.Failure);
    }
예제 #17
0
        protected override IBehaviorTreeNode createBehaviorTree()
        {
            BehaviorTreeBuilder builder = new BehaviorTreeBuilder();

            return(AIExtensions.WithFightingAI(
                       builder
                       .Sequence()
                       .LongRunningResultCached(() => new WaitTask(Entity, TimeSpan.FromMilliseconds(200)))
                       .LongRunningResultCached(() => new FollowTask(Entity, targetID, tillDistance, teleportDistance))
                       .End()
                       .Build(),
                       Entity
                       ));
        }
예제 #18
0
        public void InvertTest()
        {
            var blackboard = new TestBlackboard();
            var node       = new Invert <TestBlackboard>();
            var tree       = BehaviorTreeBuilder <TestBlackboard> .Begin()
                             .Sequence()
                             .Decorator(node).Leaf(new TrackingLeaf())
                             .Build(blackboard);

            this.UpdateAndStep(tree, 0.1f);

            Assert.AreEqual(BTTaskStatus.Failed, node.Status);
            Assert.AreEqual(1, blackboard.GetTracking(TestBlackboard.TrackingExecution));
        }
예제 #19
0
        public void It_should_run_the_custom_action()
        {
            var result = false;
            var tree   = new BehaviorTreeBuilder(null)
                         .CustomSequence("test")
                         .Do(() => {
                result = true;
                return(TaskStatus.Success);
            })
                         .End()
                         .Build();

            tree.Tick();

            Assert.IsTrue(result);
        }
예제 #20
0
    void Start()
    {
        BehaviorTreeBuilder builder = new BehaviorTreeBuilder();

        builder.Sequence("sequence1");
        builder.Action("action1", Action01);
        builder.Action("action2", Action02);
        builder.Sequence("sequence02");
        builder.Action("action03", Action03);
        builder.Action("action04", Action04);
        builder.End();
        builder.Action("Action05", Action05);
        builder.Action("Action06", Action06);
        builder.End();
        tree = builder.Build();
    }
            public void It_should_not_fail_when_aborting_a_built_condition()
            {
                var treeAlt = new BehaviorTreeBuilder(null)
                              .Sequence()
                              .Condition(() => false)
                              .End()
                              .Build();

                var tree = _builder
                           .Parallel()
                           .Splice(treeAlt)
                           .Build();

                Assert.DoesNotThrow(() => {
                    tree.Tick();
                });
            }
예제 #22
0
        protected override IBehaviorTreeNode createBehaviorTree()
        {
            BehaviorTreeBuilder builder = new BehaviorTreeBuilder();

            return(AIExtensions.WithFightingAI(
                       builder
                       .Sequence()
                       .LongRunningResultCached(() => new GoToTask(Entity, BlockGuardPosition))
                       .SingleStep((GameTime gameTime) => {
                Entity.Direction = LookDirection;

                return BehaviourTreeStatus.Success;
            })
                       .End()
                       .Build(),
                       Entity
                       ));
        }
예제 #23
0
        public static BehaviorTree <BehaviorTreeMinerState> BuildSelfAbortTree()
        {
            var builder = BehaviorTreeBuilder <BehaviorTreeMinerState> .Begin(new BehaviorTreeMinerState());

            builder.Selector(AbortTypes.Self);

            // sleep is most important
            builder.ConditionalDecorator(m => m.MinerState.Fatigue >= MinerState.MAX_FATIGUE, false);
            builder.Sequence()
            .LogAction("--- Tired! Gotta go home")
            .Action(m => m.GoToLocation(MinerState.Location.Home))
            .LogAction("--- Prep me my bed!")
            .Action(m => m.Sleep())
            .EndComposite();

            // thirst is next most important
            builder.ConditionalDecorator(m => m.MinerState.Thirst >= MinerState.MAX_THIRST, false);
            builder.Sequence()
            .LogAction("--- Thirsty! Time for a drink")
            .Action(m => m.GoToLocation(MinerState.Location.Saloon))
            .LogAction("--- Get me a drink!")
            .Action(m => m.Drink())
            .EndComposite();

            // dropping off gold is next
            builder.ConditionalDecorator(m => m.MinerState.Gold >= MinerState.MAX_GOLD, false);
            builder.Sequence()
            .LogAction("--- Bags are full! Gotta drop this off at the bank.")
            .Action(m => m.GoToLocation(MinerState.Location.Bank))
            .LogAction("--- Take me gold!")
            .Action(m => m.DepositGold())
            .EndComposite();

            // fetching gold is last
            builder.Sequence()
            .Action(m => m.GoToLocation(MinerState.Location.Mine))
            .LogAction("--- Time to get me some gold!")
            .Action(m => m.DigForGold())
            .EndComposite();

            builder.EndComposite();

            return(builder.Build());
        }
예제 #24
0
        // the same tree is here, once with LowerPriority aborts and once with Self aborts and ConditionalDecorators
        public void buildLowerPriorityAbortTree()
        {
            var builder = BehaviorTreeBuilder <BehaviorTreeMiner> .begin(this);

            builder.selector();

            // sleep is most important
            builder.sequence(AbortTypes.LowerPriority)
            .conditional(m => m.minerState.fatigue >= MinerState.MAX_FATIGUE)
            .logAction("--- tired! gotta go home")
            .action(m => m.goToLocation(MinerState.Location.Home))
            .logAction("--- prep me my bed!")
            .action(m => m.sleep())
            .endComposite();

            // thirst is next most important
            builder.sequence(AbortTypes.LowerPriority)
            .conditional(m => m.minerState.thirst >= MinerState.MAX_THIRST)
            .logAction("--- thirsty! time for a drink")
            .action(m => m.goToLocation(MinerState.Location.Saloon))
            .logAction("--- get me a drink!")
            .action(m => m.drink())
            .endComposite();

            // dropping off gold is next
            builder.sequence(AbortTypes.LowerPriority)
            .conditional(m => m.minerState.gold >= MinerState.MAX_GOLD)
            .logAction("--- bags are full! gotta drop this off at the bank.")
            .action(m => m.goToLocation(MinerState.Location.Bank))
            .logAction("--- take me gold!")
            .action(m => m.depositGold())
            .endComposite();

            // fetching gold is last
            builder.sequence()
            .action(m => m.goToLocation(MinerState.Location.Mine))
            .logAction("--- time to get me some gold!")
            .action(m => m.digForGold())
            .endComposite();

            builder.endComposite();

            _tree = builder.build();
        }
예제 #25
0
        // the same tree is here, once with LowerPriority aborts and once with Self aborts and ConditionalDecorators
        public void BuildLowerPriorityAbortTree()
        {
            var builder = BehaviorTreeBuilder <BehaviorTreeMiner> .Begin(this);

            builder.Selector();

            // sleep is most important
            builder.Sequence(AbortTypes.LowerPriority)
            .Conditional(m => m.MinerState.Fatigue >= MinerState.MaxFatigue)
            .LogAction("--- tired! gotta go home")
            .Action(m => m.GoToLocation(MinerState.Location.Home))
            .LogAction("--- prep me my bed!")
            .Action(m => m.Sleep())
            .EndComposite();

            // thirst is next most important
            builder.Sequence(AbortTypes.LowerPriority)
            .Conditional(m => m.MinerState.Thirst >= MinerState.MaxThirst)
            .LogAction("--- thirsty! time for a drink")
            .Action(m => m.GoToLocation(MinerState.Location.Saloon))
            .LogAction("--- get me a drink!")
            .Action(m => m.Drink())
            .EndComposite();

            // dropping off gold is next
            builder.Sequence(AbortTypes.LowerPriority)
            .Conditional(m => m.MinerState.Gold >= MinerState.MaxGold)
            .LogAction("--- bags are full! gotta drop this off at the bank.")
            .Action(m => m.GoToLocation(MinerState.Location.Bank))
            .LogAction("--- take me gold!")
            .Action(m => m.DepositGold())
            .EndComposite();

            // fetching gold is last
            builder.Sequence()
            .Action(m => m.GoToLocation(MinerState.Location.Mine))
            .LogAction("--- time to get me some gold!")
            .Action(m => m.DigForGold())
            .EndComposite();

            builder.EndComposite();

            _tree = builder.Build();
        }
예제 #26
0
        public static IBehaviorTreeNode WithFightingAI(IBehaviorTreeNode tree, MovingEntity entity)
        {
            BehaviorTreeBuilder builder = new BehaviorTreeBuilder(((RootNode)tree).TickFrequency);

            return(builder
                   .Selector()
                   .LongRunning(() => new FightTask(entity))
                   .Sequence()
                   .SingleStepResultCached((GameTime gameTime) =>
            {
                entity.StopWalking();

                return BehaviourTreeStatus.Success;
            })
                   .Splice(tree)
                   .End()
                   .End()
                   .Build());
        }
예제 #27
0
 public void FluentTreeBuilderTest()
 {
     var behaviorBuilder = new BehaviorTreeBuilder <AIContext>();
     var tree            =
         behaviorBuilder
         .Selector
         .Behavior(context => BehaviorResult.Success)
         .Sequence
         .Behavior(context => BehaviorResult.Success)
         .End
         .Sequence
         .Decorate(DecorateFor.AlwaysSucceeding)
         .Behavior(context => BehaviorResult.Success)
         .Sequence
         .Behavior(context => BehaviorResult.Success)
         .End
         .Question(context => 1 == 1)
         .End
         .End
         .Tree;
 }
예제 #28
0
        public void IntervalTest()
        {
            var blackboard = new TestBlackboard();
            var tree       = BehaviorTreeBuilder <TestBlackboard> .Begin()
                             .Sequence()
                             .Interval().Leaf(new TrackingLeaf())
                             .Build(blackboard);

            for (var n = 0; n < 10; n++)
            {
                for (var i = 0; i < 9; i++)
                {
                    this.UpdateAndStep(tree, 0.1f);
                }

                Assert.AreEqual(n, blackboard.GetTracking(TestBlackboard.TrackingExecution));

                this.UpdateAndStep(tree, 0.1f);

                Assert.AreEqual(n + 1, blackboard.GetTracking(TestBlackboard.TrackingExecution));
            }
        }
예제 #29
0
        private void buildBehaviorTree()
        {
            //Initialize pathfinding
            _origin    = (entity.position / Game1.TILE_SIZE).ToPoint();
            _waypoints = _grid.search(new Point(_origin.X, _origin.Y), new Point(_origin.X + 5, _origin.Y));

            BehaviorTreeBuilder <EnemyController> _behaviorTreeBuilder = BehaviorTreeBuilder <EnemyController> .begin(this);

            _behaviorTreeBuilder.untilSuccess();
            //Creates a method with input of EnemyController and output of TaskStatus
            Func <EnemyController, TaskStatus> chasePlayer = delegate(EnemyController context) {
                if (target == null)
                {
                    return(TaskStatus.Failure);
                }

                Point currentNode = (entity.position / Game1.TILE_SIZE).ToPoint();
                Point targetNode  = (target.position / Game1.TILE_SIZE).ToPoint();

                _waypoints            = _grid.search(currentNode, targetNode);
                _currentWaypointIndex = 0;

                //Check to see if path exists
                if (_waypoints == null)
                {
                    return(TaskStatus.Failure);
                }

                return(TaskStatus.Running);
            };


            _behaviorTreeBuilder.action(chasePlayer);

            _behaviorTree = _behaviorTreeBuilder.build();
        }
예제 #30
0
        public override void Init()
        {
            base.Init();
            _boss.SetMaxHealth(MAX_HEALTH);


            #region behavior tree
            _tree = new BehaviorTreeBuilder(gameObject)
                    .Selector()
                    .Condition(() => _boss.IsDead)
                    .Condition(() => _boss.IsInvincible)
                    .Sequence()
                    .Selector("Attack")
                    .Sequence("Drone")
                    .Condition(() => _attackType == AttackType.DRONE)
                    .Do("Drone Attack", () => {
                DroneAttack();
                return(TaskStatus.Success);
            })
                    .WaitTime(0.8f)
                    .End()
                    .Sequence("Shotgun")
                    .Condition(() => _attackType == AttackType.SHOTGUN)
                    .Do("Fire Shotgun", () => {
                FireShotgun();
                return(TaskStatus.Success);
            })
                    .WaitTime(1.5f)
                    .End()
                    .Sequence("Laser")
                    .Condition(() => _attackType == AttackType.LASER)
                    .Do("Fire Laser", () => {
                Laser(Vector2.right);
                return(TaskStatus.Success);
            })
                    .WaitTime(3f)
                    .End()
                    .Sequence("ExplosionCore")
                    .Condition(() => _attackType == AttackType.EXPLOSION_CORE)
                    .Do("Fire Explosion Core", () => {
                FireExplosionCore();
                return(TaskStatus.Success);
            })
                    .WaitTime(0.8f)
                    .End()
                    .Sequence("Smash")
                    .Condition(() => _attackType == AttackType.SMASH)
                    .Do("Smash Player", () => {
                Smash();
                return(TaskStatus.Success);
            })
                    .WaitTime(3f)
                    .End()
                    .End()
                    .Do("Choose Random Attack Type", () => {
                // _attackType = BS.Utils.Random.RandomEnum<AttackType>();
                _attackType = AttackType.SMASH;
                return(TaskStatus.Success);
            })
                    .End()
                    .Build();
            #endregion
        }