Beispiel #1
0
        public ApproachMachine()
        {
            DataStorage[PlayerPosition] = new Point(10, 10);
            DataStorage[GoalPosition]   = new Point(0, 0);
            DataStorage[Switch]         = false;

            var switchOffState = new State();

            this[SwitchOff] = switchOffState;
            switchOffState.OnExecuteEvent = (machine, state) =>
            {
                Debug.WriteLine($"SwitchOff");
                if ((bool)machine.DataStorage[Switch])
                {
                    machine.NextStateName = SwitchOn;
                }
            };

            var switchOnState = new State();

            this[SwitchOn] = switchOnState;

            var behaviourMachine = new BehaviourMachine();

            behaviourMachine.DataStorage.ReferTo(DataStorage, PlayerPosition);
            behaviourMachine.DataStorage.ReferTo(DataStorage, GoalPosition);

            switchOnState.OnExecuteEvent = (machine, state) =>
            {
                Debug.WriteLine($"SwitchOn");
                behaviourMachine.Execute();
            };

            var moveOrTeleportSelector = new SelectorNode();

            behaviourMachine.RegisterRootNode(moveOrTeleportSelector);

            var moveDecorator = new DecoratorNode();

            moveOrTeleportSelector.ChildNodes.Add(moveDecorator);
            moveDecorator.ConditionCallback = (machine, node) =>
            {
                Debug.WriteLine($"move condition check");
                var playerPosition = (Point)machine.DataStorage[PlayerPosition];
                var goalPosition   = (Point)machine.DataStorage[GoalPosition];
                Debug.WriteLine($"P:{playerPosition} G:{goalPosition}");
                return(!playerPosition.Equals(goalPosition));
            };
            var moveAction = new ActionNode();

            moveDecorator.ChildNode   = moveAction;
            moveAction.ActionCallback = (machine, node) =>
            {
                Debug.WriteLine($"Move");
                var playerPosition = (Point)machine.DataStorage[PlayerPosition];
                var goalPosition   = (Point)machine.DataStorage[GoalPosition];
                var diffX          = Math.Abs(playerPosition.X - goalPosition.X);
                var diffY          = Math.Abs(playerPosition.Y - goalPosition.Y);
                if (diffX >= diffY)
                {
                    playerPosition.X += playerPosition.X > goalPosition.X ? -1 : 1;
                }
                else
                {
                    playerPosition.Y += playerPosition.Y > goalPosition.Y ? -1 : 1;
                }
                machine.DataStorage[PlayerPosition] = playerPosition;
                return(true);
            };

            var teleportAction = new ActionNode();

            teleportAction.DataStorage[TeleportCounter] = 10;
            moveOrTeleportSelector.ChildNodes.Add(teleportAction);
            teleportAction.ActionCallback = (machine, node) =>
            {
                Debug.WriteLine($"teleport");
                var teleportCounter = (int)node.DataStorage[TeleportCounter];
                teleportCounter--;
                node.DataStorage[TeleportCounter] = teleportCounter;
                Debug.WriteLine($"teleport counter: {teleportCounter}");
                if (teleportCounter > 0)
                {
                    return(false);
                }

                var playerPosition = (Point)machine.DataStorage[PlayerPosition];
                playerPosition.X = new Random().Next(-10, 10);
                playerPosition.Y = new Random().Next(-10, 10);
                machine.DataStorage[PlayerPosition] = playerPosition;

                node.DataStorage[TeleportCounter] = 10;
                Debug.WriteLine($"teleport to {playerPosition}");
                return(true);
            };
        }
Beispiel #2
0
        public void SimpleSearcherTest()
        {
            const string hitpoint        = "hp";
            const string distanceToTower = "distance";

            var machine = new BehaviourMachine();

            machine.DataStorage[hitpoint]        = 100;
            machine.DataStorage[distanceToTower] = 10;

            machine.OnExecuteEvent += (m) =>
            {
                var hp       = (int)m.DataStorage[hitpoint];
                var distance = (int)m.DataStorage[distanceToTower];
                Debug.WriteLine($"HP: {hp}");
                Debug.WriteLine($"Distance: {distance}");
            };

            var selector = new SelectorNode();

            machine.RegisterRootNode(selector);

            var decoratorHp = new DecoratorNode();

            selector.ChildNodes.Add(decoratorHp);

            decoratorHp.ConditionCallback = (m, n) => m.DataStorage.GetValue <int>(hitpoint) > 5;
            var attackNearEnemy = new ActionNode();

            attackNearEnemy.ActionCallback = (m, n) =>
            {
                Debug.WriteLine("近くの敵を攻撃");

                var distance = (int)m.DataStorage[distanceToTower];
                distance += 1;
                m.DataStorage[distanceToTower] = distance;

                var hp = (int)m.DataStorage[hitpoint];
                hp -= 5;
                m.DataStorage[hitpoint] = hp;
                return(true);
            };
            decoratorHp.ChildNode = attackNearEnemy;

            var sequencer = new SequencerNode();

            selector.ChildNodes.Add(sequencer);

            var moveToNearTower = new ActionNode();

            sequencer.ChildNodes.Add(moveToNearTower);

            moveToNearTower.ActionCallback = (m, n) =>
            {
                var distance = (int)m.DataStorage[distanceToTower];
                if (distance <= 0)
                {
                    return(true);
                }

                Debug.WriteLine("近くのタワーに移動");
                distance--;
                m.DataStorage[distanceToTower] = distance;
                return(true);
            };

            var wait = new ActionNode();

            sequencer.ChildNodes.Add(wait);

            wait.ActionCallback = (m, n) =>
            {
                Debug.WriteLine("待機");

                var distance = (int)m.DataStorage[distanceToTower];
                if (distance < 5)
                {
                    var hp = (int)m.DataStorage[hitpoint];
                    hp += 20;
                    m.DataStorage[hitpoint] = hp;
                }

                return(true);
            };

            for (var i = 0; i < 100; i++)
            {
                machine.Execute();
            }
        }