예제 #1
0
    //-----------------------------------------------------------------------------------------------
    private static void ParseMethodsFromNode(XmlNode compoundTaskNode, CompoundTask task, Domain domain)
    {
        XmlNodeList methodList = compoundTaskNode.ChildNodes;

        foreach (XmlNode methodNode in methodList)
        {
            Method methodToAdd = new Method();

            XmlNodeList methodDataMembers = methodNode.ChildNodes;

            foreach (XmlNode methodDataMember in methodDataMembers)
            {
                string dataType = methodDataMember.Name;

                switch (dataType)
                {
                case "Precondition":
                {
                    ParsePreconditionForMethod(methodDataMember, methodToAdd);
                    break;
                }

                case "Subtasks":
                {
                    ParseSubtasksForMethod(methodDataMember, methodToAdd, domain);
                    break;
                }
                }
            }

            task.RegisterMethod(methodToAdd);
        }
    }
예제 #2
0
    //From the failed task, get a node in hierarchy with a valid method in current state
    public static CompoundTask GetValidNode(PrimitiveTask failedTask, State state)
    {
        CompoundTask parent  = new CompoundTask();
        Task         current = failedTask;


        //Get parent of task, until a parent with a valid method is found, or the root of hierarchy is reached

        while (current.parent != null)
        {
            parent = current.parent;


            foreach (Method method in parent.methods)
            {
                if (RuleMatcher.MatchCondition(method.preconditions, state, method.logicalOperator))
                {
                    return(parent);
                }
            }


            current = parent;
        }

        return(parent);
    }
예제 #3
0
        public void UpwardUnifyTest1()
        {
            var up = new CompoundTask("up", 1);

            up.AddMethod(1, new object[] { "xyz" }, new LocalVariableName[0],
                         null, 0, null, 1);

            var down = new CompoundTask("down", 1);
            // ReSharper disable once InconsistentNaming
            var X = new LocalVariableName("X", 0);

            down.AddMethod(1, new object[] { X }, new[] { X },
                           TestUtils.Sequence(new object[] { toString, X }, new[] { "matched" }), 0,
                           null, 1);

            var test = new CompoundTask("test", 0);
            // ReSharper disable once InconsistentNaming
            var Y = new LocalVariableName("Y", 0);

            test.AddMethod(1, new object[0], new [] { Y },
                           TestUtils.Sequence(new object[] { up, Y }, new object[] { down, Y }), 0,
                           null, 1);

            Assert.AreEqual("Xyz matched", new Call(test, new object[0], null).Expand());
        }
예제 #4
0
    public PrimitiveTask(string n, CompoundTask p)
    {
        name = n;

        arguments          = new List <Term>();
        arguments.Capacity = 3;


        preconditions   = new List <Atom>();
        effects         = new List <Atom>();
        cuncurrentTasks = new List <CuncurrentTask> ();


        cost = 1;

        loop = false;

        logicalOperator = LogicalOperator.AND;

        actionType = ActionTypes.MOVEMENT;

        groundData = new GroundData();
        groundData.animationState = "";
        groundData.name           = "";

        parent = p;
    }
예제 #5
0
        public PlannerState(CompoundTask currentTask, Stack <PrimitiveTask> finalPlan, Stack <Task> tasksToProcess, Method currentMethod)
        {
            this.currentTask    = currentTask;
            this.finalPlan      = new Stack <PrimitiveTask>();
            this.tasksToProcess = new Stack <Task>();
            this.currentMethod  = currentMethod;

            Stack <PrimitiveTask> temp = new Stack <PrimitiveTask>();

            // Create shallow copy of finalPlan
            for (int i = 0; i < finalPlan.Count; i++)
            {
                temp.Push(finalPlan.Pop());
            }
            for (int i = 0; i < temp.Count; i++)
            {
                PrimitiveTask t = temp.Pop();
                this.finalPlan.Push(t);
                finalPlan.Push(t);
            }

            // Create shallow copy of tasksToProcess
            Stack <Task> temp2 = new Stack <Task>();

            for (int i = 0; i < tasksToProcess.Count; i++)
            {
                temp2.Push(tasksToProcess.Pop());
            }
            for (int i = 0; i < temp2.Count; i++)
            {
                Task t = temp2.Pop();
                this.tasksToProcess.Push(t);
                tasksToProcess.Push(t);
            }
        }
예제 #6
0
 public Method(string n, CompoundTask p)
 {
     name            = n;
     preconditions   = new List <Atom> ();
     subtasks        = new List <Task> ();
     preference      = "none";
     logicalOperator = LogicalOperator.AND;
     parent          = p;
     cost            = -1.0f;
 }
예제 #7
0
    void removeMethod(object data)
    {
        ArrayList list = (ArrayList)data;

        CompoundTask comp = (CompoundTask)list [0];

        Method method = (Method)list [1];

        comp.removeMethod(method);
    }
예제 #8
0
    /// <summary>
    /// 直前のCompoundTaskの状態まで遡れるように、現在のPlannerStateを記録
    /// </summary>
    private void RecordDecompositionOfTask(CompoundTask nextCompoundTask)
    {
        var copyOfPlannerState = new PlannerState(
            plannerState.WorkingWS.Clone(),
            new List <TaskBase>(plannerState.FinalPlanList),
            new List <TaskBase>(plannerState.TaskListToProcess),
            plannerState.NextMethodNumber);

        copyOfPlannerState.TaskListToProcess.Add(nextCompoundTask);
        plannerStateHistory.Add(copyOfPlannerState);
    }
예제 #9
0
        public void MatchingNoVariablesTest()
        {
            var t = new CompoundTask("test", 1);

            t.Flags |= CompoundTask.TaskFlags.Fallible;
            t.AddMethod(1, new object[] { 1 }, new LocalVariableName[0], new EmitStep(new [] { "1", "matched" }, null), 0, null, 1);
            t.AddMethod(1, new object[] { 2 }, new LocalVariableName[0], new EmitStep(new [] { "2", "matched" }, null), 0, null, 1);

            Assert.AreEqual("1 matched", new Call(t, new object[] { 1 }, null).Expand());
            Assert.AreEqual("2 matched", new Call(t, new object[] { 2 }, null).Expand());
            Assert.AreEqual(null, new Call(t, new object[] { 3 }, null).Expand());
        }
예제 #10
0
        protected override void Context()
        {
            _executionContext      = A.Fake <IExecutionContext>();
            _buildingBlockTask     = A.Fake <IBuildingBlockTask>();
            _applicationController = A.Fake <IApplicationController>();
            _compound = new Compound().WithId("Drug").WithName("Drug");
            _buildingBlockRepository = A.Fake <IBuildingBlockRepository>();
            _dialogCreator           = A.Fake <IDialogCreator>();
            sut = new CompoundTask(_executionContext, _buildingBlockTask, _applicationController, _buildingBlockRepository, _dialogCreator);

            A.CallTo(() => _buildingBlockTask.SaveAsTemplate(A <ICache <IPKSimBuildingBlock, IReadOnlyList <IPKSimBuildingBlock> > > ._, TemplateDatabaseType.User))
            .Invokes(x => _cache = x.GetArgument <ICache <IPKSimBuildingBlock, IReadOnlyList <IPKSimBuildingBlock> > >(0));
        }
예제 #11
0
        public void DownwardUnifyTest1()
        {
            var t = new CompoundTask("test", 1);
            // ReSharper disable once InconsistentNaming
            var X      = new LocalVariableName("X", 0);
            var locals = new[] { X };

            t.AddMethod(1, new object[] { X }, locals,
                        TestUtils.Sequence(new object[] { toString, X }, new[] { "matched" }), 0,
                        null, 1);

            Assert.AreEqual("1 matched", new Call(t, new object[] { 1 }, null).Expand());
            Assert.AreEqual("2 matched", new Call(t, new object[] { 2 }, null).Expand());
        }
예제 #12
0
    //-----------------------------------------------------------------------------------------------
    private static void ParseCompoundTaskMethods(XmlDocument xmlData, Domain domain)
    {
        XmlNodeList compoundTaskList = xmlData.GetElementsByTagName("CompoundTask");

        foreach (XmlNode compoundTaskNode in compoundTaskList)
        {
            string taskName = "";
            if (!TryLoadRequiredAttributeFromXmlNode(compoundTaskNode, "name", ref taskName))
            {
                throw new ArgumentNullException("CompoundTask missing name!");
            }

            CompoundTask task = domain.GetTaskByName(taskName) as CompoundTask;
            ParseMethodsFromNode(compoundTaskNode, task, domain);
        }
    }
예제 #13
0
    //-----------------------------------------------------------------------------------------------
    private static void ParseCompoundTasks(XmlDocument xmlData, Domain domain)
    {
        XmlNodeList compoundTaskList = xmlData.GetElementsByTagName("CompoundTask");

        foreach (XmlNode compoundTaskNode in compoundTaskList)
        {
            string taskName = "";
            if (!TryLoadRequiredAttributeFromXmlNode(compoundTaskNode, "name", ref taskName))
            {
                throw new ArgumentNullException("CompoundTask missing name!");
            }

            CompoundTask task = new CompoundTask(taskName);
            domain.TryRegisterTask(taskName, task);
        }
    }
예제 #14
0
    /// <summary>
    /// CompoundTaskが保有しているMethodの中から、現在のWorldStateに合致するMethodを返す。
    /// なければ、nullを返す。
    /// </summary>
    private Method FindSatisfiedMethod(CompoundTask currentCompoundTask, PlannerState plannerState)
    {
        var methodsWorldState = plannerState.WorkingWS.Clone();
        var methods           = currentCompoundTask.Methods;

        while (plannerState.NextMethodNumber < methods.Count)
        {
            var method = methods[plannerState.NextMethodNumber];
            plannerState.NextMethodNumber++;

            if (method.CheckPreCondition(methodsWorldState))
            {
                return(method);
            }
        }

        return(null);
    }
예제 #15
0
    public SerializedTask(CompoundTask t, SerializedTask p)
    {
        type   = "Compound";
        parent = p;

        name = t.name;

        methods = new List <SerializedMethod> ();

        foreach (Method m in t.methods)
        {
            methods.Add(new SerializedMethod(m, this));
        }

        cost            = 0;
        effects         = null;
        preconditions   = null;
        cuncurrentTasks = null;
    }
예제 #16
0
    public Task DeSerialize(CompoundTask p)
    {
        if (type == "Compound")
        {
            CompoundTask cp = new CompoundTask(name, p);

            foreach (SerializedMethod sm in methods)
            {
                Method m = sm.DeSerialize(cp);

                cp.addMethod(m);
            }

            return(cp);
        }
        else
        {
            PrimitiveTask tp = new PrimitiveTask(name, p);


            tp.cost = cost;


            tp.effects = effects;

            tp.cuncurrentTasks = cuncurrentTasks;

            tp.preconditions = preconditions;

            arguments.Capacity = 3;
            tp.arguments       = arguments;

            tp.actionType = actionType;

            tp.groundData = groundData;

            tp.loop = loop;

            tp.logicalOperator = logicalOperator;

            return(tp);
        }
    }
예제 #17
0
    //Check if node in hierarchy is forefather of this task
    public bool IsMyForeFather(CompoundTask node)
    {
        CompoundTask currentParent = new CompoundTask();

        Task currentTask = this;

        while (currentTask.parent != null)
        {
            currentParent = currentTask.parent;

            if (currentParent.Equals(node))
            {
                return(true);
            }

            currentTask = currentParent;
        }

        return(false);
    }
예제 #18
0
    public Method DeSerialize(CompoundTask p)
    {
        Method m = new Method(name, null);

        m = new Method(name, p);

        m.preference = preference;

        m.logicalOperator = logicalOperator;

        m.preconditions = preconditions;


        foreach (SerializedTask st in subtasks)
        {
            m.subtasks.Add(st.DeSerialize(p));
        }


        return(m);
    }
예제 #19
0
    Vector2 calcLastHeight(Task task, Vector2 pos)
    {
        if (task.GetType() == typeof(CompoundTask))
        {
            Vector2 lastPos = pos;

            CompoundTask cp = (CompoundTask)task;

            foreach (Method m in cp.methods)
            {
                foreach (Task t in m.subtasks)
                {
                    lastPos = calcLastHeight(t, new Vector2(lastPos.x + 30, lastPos.y + 60));
                }
            }


            return(lastPos);
        }

        return(pos);
    }
예제 #20
0
    public static void  ShowWindow(HTNAgent a, CompoundTask g)
    {
        goal  = g;
        agent = a;

        persIndex   = 0;
        varIndex    = 0;
        actionIndex = 0;



        if (agent.serializedGoal.name.Length > 0)
        {
            goal = (CompoundTask)agent.serializedGoal.DeSerialize(null);
        }

        EditorWindow window = EditorWindow.GetWindow(typeof(HTNEditorWindow));

        window.maxSize = new Vector2(700, 700);
        window.minSize = new Vector2(700, 700);

        window.position = new Rect(200, 200, 700, 700);
    }
예제 #21
0
    //Least cost plan found choosing this method
    public float leastCost()
    {
        float c = 0.0f;

        foreach (Task subtask in subtasks)
        {
            if (subtask.GetType() == typeof(CompoundTask))
            {
                CompoundTask ct = (CompoundTask)subtask;


                float leastCost = Mathf.Infinity;

                foreach (Method m in ct.methods)
                {
                    float currentCost = m.Cost;

                    if (currentCost < Mathf.Infinity)
                    {
                        leastCost = currentCost;
                    }
                }

                return(leastCost);
            }

            else if (subtask.GetType() == typeof(PrimitiveTask))
            {
                PrimitiveTask pt = (PrimitiveTask)subtask;

                c += pt.cost;
            }
        }

        return(c);
    }
예제 #22
0
 public CompoundTask(string n, CompoundTask p)
 {
     name    = n;
     methods = new List <Method> ();
     parent  = p;
 }
예제 #23
0
 public CompoundTask(CompoundTask p)
 {
     name    = "New Compound";
     methods = new List <Method> ();
     parent  = p;
 }
예제 #24
0
    public void InstantiateVariables(Task task, List <Term> variables)
    {
        if (task.GetType() == typeof(PrimitiveTask))
        {
            PrimitiveTask pt = (PrimitiveTask)task;

            foreach (Term variable in variables)
            {
                int index = pt.arguments.FindIndex((Term arg) => arg.key == variable.key);

                if (index >= 0)
                {
                    pt.arguments[index] = variable;
                }

                foreach (Atom pre in pt.preconditions)
                {
                    index = pre.terms.FindIndex((Term arg) => arg.key == variable.key);

                    if (index >= 0)
                    {
                        pre.terms[index] = variable;
                    }
                }


                foreach (Atom eff in pt.effects)
                {
                    index = eff.terms.FindIndex((Term arg) => arg.key == variable.key);

                    if (index >= 0)
                    {
                        eff.terms[index] = variable;
                    }
                }
            }
        }
        else if (task.GetType() == typeof(CompoundTask))
        {
            CompoundTask ct = (CompoundTask)task;

            foreach (Method m in ct.methods)
            {
                foreach (Atom pre in m.preconditions)
                {
                    foreach (Term variable in variables)
                    {
                        int index = pre.terms.FindIndex((Term arg) => arg.key == variable.key);

                        if (index >= 0)
                        {
                            pre.terms[index] = variable;
                        }
                    }
                }


                foreach (Task subTask in m.subtasks)
                {
                    InstantiateVariables(subTask, variables);
                }
            }
        }
    }
예제 #25
0
    // Use this for initialization
    void Start()
    {
        compileExpressionParser();


        //Knowledge update rate
        KnowledgeUpdateWindow.LoadFromFile();

        //Get goal
        goal = (CompoundTask)serializedGoal.DeSerialize(null);



        //Initialize knowledge

        foreach (SerializedFact fact in serializedKnowledge)
        {
            Atom newFact = new Atom(fact.name, fact.sign);

            foreach (string objName in fact.values)
            {
                newFact.addTerm(new Term(GameObject.Find(objName)));
            }

            state.addFact(newFact);
        }


        //Initialize variables


        foreach (SerializedVariable var in serializedDomainVariables)
        {
            if (var.key != "" && var.value != "")
            {
                domainVariables [serializedDomainVariables.IndexOf(var)].value = GameObject.Find(var.value);
            }
        }
        //Instantiate variables
        InstantiateVariables(goal, domainVariables);

        //Add sensor
        if (sensor == 0)
        {
            sensorySystem = new CameraSensor(this);
        }
        else if (sensor == 1)
        {
            sensorySystem = new RadiusSensor(this, radiusLength);
        }


        try {
            definitions = FactDefinitionsContainer.Load(FactsDefinitionWindow.definitionsPath).list;
        }

        catch (Exception e) {
            Debug.Log(e.Message);
        }



        //Agent FSM
        FSM = new AgentStateMachine(AgentState.IDLE, this);

        //Action manager
        actionManager = new ActionManager(this);



        //Coordination
        communicationSystem = new CommunicationSystem(this);

        groupMembers = new List <HTNAgent> ();

        //Personalities
        knownPersonalities = PersonalitiesContainer.Load(PersonalityEditorWindow.path).list;
    }
예제 #26
0
    public void Update()
    {
        if (current == AgentState.IDLE)
        {
            //Transizione a PLANNING: se l'agente ha un task obiettivo non completato, o non esiste una condizione obiettivo, ma il manager delle azioni è comunque in stato STOP

            if (agent.goal.methods.Count > 0 && !agent.goal.completed && (Time.frameCount % 60 == 0 || Time.frameCount == 1))
            {
                current = AgentState.PLANNING;
            }

            //Transizione a EXECUTING: se il manager delle azioni è in stato EXECUTE
            else if (agent.actionManager.state == ManagerState.EXECUTE)
            {
                current = AgentState.EXECUTING;
            }

            else if (agent.actionManager.state == ManagerState.PAUSE)
            {
                PrimitiveTask currentTask = (PrimitiveTask)agent.actionManager.currentAction;

                foreach (CuncurrentTask cuncurrent in currentTask.cuncurrentTasks)
                {
                    if (!currentTask.CheckCuncurrency(cuncurrent, agent))
                    {
                        return;
                    }
                }

                agent.actionManager.Resume();
            }
        }
        else if (current == AgentState.PLANNING)
        {
            /*In this state, agent plans to goal
             * Transition to EXECUTING : if agent has a plan towards goal (not empty actions list)
             * Transizion to IDLE: agent has no plan towards goal (empty actions list)*/


            //Generate or fix plan
            List <Task> tasks = new List <Task>();

            //If manager has stopped with INVALID state, fix plan and get a new plan
            if (agent.actionManager.state == ManagerState.INVALID)
            {
                //Climb the hierarchy and get the first valid node
                CompoundTask validNode = Planner.GetValidNode((PrimitiveTask)agent.actionManager.currentAction, agent.state);

                tasks.Add(validNode);


                //Generate first segment of fixed plan, planning from the node found

                List <PrimitiveTask> firstSegment = Planner.GeneratePlan(tasks, agent);

                if (firstSegment.Count > 0)
                {
                    //Get second segment from the current plan, deleting tasks who have node found as father or forefather
                    List <PrimitiveTask> secondSegment = new List <PrimitiveTask>();

                    foreach (PrimitiveTask task in agent.plan)
                    {
                        if (!task.IsMyForeFather(validNode) && !task.completed)
                        {
                            secondSegment.Add(task);
                        }
                    }

                    //Fix the plan concatenating first segment with second segment
                    agent.plan = firstSegment.Concat(secondSegment).ToList <PrimitiveTask>();
                }

                //No plan..
                else
                {
                    agent.plan = new List <PrimitiveTask>();

                    //If agent is a member of a group, notify it to the leader, who will stop execution of global plan
                    agent.communicationSystem.sendMessage(new Message(agent.leader, MessageContent.ORDER_FAILURE));
                }
            }

            //Otherwise generate plan
            else
            {
                tasks.Add(agent.goal);

                agent.plan = Planner.GeneratePlan(tasks, agent);
            }


            if (agent.plan != null)
            {
                foreach (IGroundAction action in agent.plan)
                {
                    agent.actionManager.ScheduleAction(action);
                }

                agent.actionManager.NextAction();

                current = AgentState.EXECUTING;

                agent.actionManager.state = ManagerState.EXECUTE;
            }
            else
            {
                agent.actionManager.state = ManagerState.STOP;

                current = AgentState.IDLE;
            }
        }
        else if (current == AgentState.EXECUTING)
        {
            //Dentro lo stato: esecuzione azione corrente del piano
            //Transizione a IDLE : se il piano è completato con successo, oppure il manager delle azioni è andato in pausa
            //Transizione a PLANNING : se il piano non è valido (precondizioni azione non valide)

            agent.actionManager.RunCurrentAction();

            if (agent.actionManager.state == ManagerState.EMPTY)
            {
                current = AgentState.IDLE;

                agent.actionManager.state = ManagerState.STOP;

                agent.goal.completed = true;
            }
            else if (agent.actionManager.state == ManagerState.INVALID)
            {
                current = AgentState.PLANNING;
            }

            else if (agent.actionManager.state == ManagerState.PAUSE)
            {
                current = AgentState.IDLE;
            }
        }
    }
예제 #27
0
    static List <PrimitiveTask> SHOPNoBack(List <Task> tasks, List <PrimitiveTask> plan, string personality, State state, HTNAgent agent)
    {
        Task task = tasks [0];

        if (task.GetType() == typeof(PrimitiveTask))
        {
            PrimitiveTask pt = (PrimitiveTask)task;


            PrimitiveTask groundAction = InstantiateAction(pt, state, agent);

            if (groundAction != null)
            {
                plan.Add(groundAction);

                tasks.Remove(pt);

                if (tasks.Count > 0)
                {
                    return(SHOPNoBack(tasks, plan, personality, pt.apply(state), agent));
                }
            }
            else
            {
                return(null);
            }
        }
        else if (task.GetType() == typeof(CompoundTask))
        {
            CompoundTask ct = (CompoundTask)task;


            List <Method> orderdedMethods = new List <Method>();

            switch (agent.methodsOrdering)
            {
            case MethodsOrdering.NONE:
                orderdedMethods = ct.methods;
                break;

            case MethodsOrdering.PREF:
                orderdedMethods = ct.methods.OrderBy(m => m.preference != personality).ToList();
                break;

            case MethodsOrdering.COSTANDPREF:
                orderdedMethods = ct.methods.OrderBy(m => m.leastCost()).ThenBy(m => m.preference != personality).ToList();
                break;
            }


            foreach (Method m in orderdedMethods)
            {
                if (RuleMatcher.MatchCondition(m.preconditions, state, m.logicalOperator))
                {
                    List <Task> tempTasks = new List <Task>(tasks);

                    tempTasks.Remove(task);

                    int j = 0;

                    foreach (Task subtask in m.subtasks)
                    {
                        tempTasks.Insert(0 + j, subtask);
                        j++;
                    }
                    List <PrimitiveTask> tempPlan = SHOPNoBack(tempTasks, plan, personality, state, agent);


                    if (tempPlan != null)
                    {
                        plan.Concat(tempPlan);
                        break;
                    }
                    else
                    {
                        return(null);
                    }
                }
            }
        }

        return(plan);
    }
예제 #28
0
    // Start is called before the first frame update
    void Start()
    {
        lvlMgr = FindObjectOfType <LevelManager>();
        player = FindObjectOfType <Self>();
        agent  = GetComponent <NavMeshAgent>();
        /* Build a HTN */
        // var root = new CompoundTask();
        // htn = new HTNPlanner(root);

        // var ApproachCrate = new ApproachObject("crate");
        // var PickUpCrate = new ObstaclePickUp("crate");
        // var ApproachPlayer = new ApproachPlayer();
        // var ThrowObstacle = new ThrowObstacle();

        // var ApproachRock = new ApproachObject("rock");
        // var PickUpRock = new ObstaclePickUp("rock");
        // var ApproachRandom = new ApproachRandom();

        // var getCrate = new CompoundTask();
        // getCrate.AddMethod(new List<Task>() { ApproachCrate, PickUpCrate});

        // var getRock = new CompoundTask();
        // getRock.AddMethod(new List<Task>() { ApproachRock, PickUpRock });

        // root.AddMethod(new List<Task>() { getCrate, ApproachPlayer, ThrowObstacle, ApproachRandom });
        // root.AddMethod(new List<Task>() { getRock, ApproachPlayer, ThrowObstacle, ApproachRandom });

        var root = new CompoundTask();

        htn = new HTNPlanner(root);

        var ApproachCrate  = new ApproachObject("crate");
        var PickUpCrate    = new ObstaclePickUp("crate");
        var ApproachPlayer = new ApproachPlayer();
        var ThrowObstacle  = new ThrowObstacle();

        var ApproachRock = new ApproachObject("rock");
        var PickUpRock   = new ObstaclePickUp("rock");

        var ApproachRandom = new ApproachRandom();

        var attackUsingCrate = new CompoundTask();

        attackUsingCrate.AddMethod(new List <Task>()
        {
            ApproachCrate, PickUpCrate, ApproachPlayer, ThrowObstacle
        });
        attackUsingCrate.AddMethod(new List <Task>()
        {
            ApproachPlayer, ThrowObstacle
        });

        var attackUsingRock = new CompoundTask();

        attackUsingRock.AddMethod(new List <Task>()
        {
            ApproachRock, PickUpRock, ApproachPlayer, ThrowObstacle
        });
        attackUsingRock.AddMethod(new List <Task>()
        {
            ApproachPlayer, ThrowObstacle
        });

        var move = new CompoundTask();

        move.AddMethod(new List <Task>()
        {
            ApproachRandom
        });
        move.AddMethod(new List <Task>()
        {
            ApproachPlayer
        });

        root.AddMethod(new List <Task>()
        {
            attackUsingCrate
        });
        root.AddMethod(new List <Task>()
        {
            attackUsingRock
        });
        root.AddMethod(new List <Task>()
        {
            move
        });
    }
예제 #29
0
    void SimpleForwardPlanner()
    {
        Plan.Clear();  // we clear the plan before we start populating it
        Stack <Task> tasks = new Stack <Task> ();

        tasks.Push(new CaveMonsterCompoundTask());   // HTN ROOT
        while (tasks.Count > 0)
        {
            Task task = tasks.Pop();

            if (task.isCompound())
            {
                // then we can safely cast it

                CompoundTask compoundTask = (CompoundTask)task;
                // not all compound tasks need to find a task
                if (compoundTask.NeedsToFindTask())
                {
                    CompoundTask method = compoundTask.FindTask();
                    // if we found a task
                    if (method != null)
                    {
                        // CODE TO SAVE STATE HERE NOT NEEDED BECAUSE OF PRE CONDITIONS

                        // we push the subtasks into our tasks stack
                        foreach (Task t in method.GetSubtasks())
                        {
                            tasks.Push(t);
                        }
                    }
                    else
                    {
                        // if method == null
                        // CODE TO RESTORE STATE HERE
                    }
                }
                // if don't need to find task, then we just add all subtasks of the compoundtask to tasks
                else
                {
                    foreach (Task t in compoundTask.GetSubtasks())
                    {
                        tasks.Push(t);
                    }
                }
            } // ELSE task is primitive
            else
            {
                // can safely cast
                PrimitiveTask primitiveTask = (PrimitiveTask)task;
                if (primitiveTask.ValidPreconditions())
                {
                    // Also need to Update State but we will do that when we execute the primitive task, not here
                    Plan.Add(primitiveTask);
                }
                else
                {
                    // if preconditions were false
                    // CODE TO RESTORE STATE HERE
                }
            }
        }
        hasPlan = true;
        Plan.Reverse(); // because we built it bottom up
    }
예제 #30
0
    public void plan(GameController.WorldState currentWorldState)
    {
        finalPlan = new Stack <PrimitiveTask>();
        Stack <PlannerState> decompHistory = new Stack <PlannerState>();

        GameController.WorldState WorkingWS = currentWorldState.Copy();

        tasksToProcess.Push(new PlayGame());

        while (tasksToProcess.Count > 0)
        {
            Task CurrentTask = tasksToProcess.Pop();
            if (CurrentTask.GetType().IsSubclassOf(typeof(CompoundTask)))
            {
                CompoundTask CurrentCompoundTask = (CompoundTask)CurrentTask;
                Method       SatisfiedMethod     = CurrentCompoundTask.FindSatisfiedMethod(WorkingWS);

                if (SatisfiedMethod != null)
                {
                    //PlannerState currentState = new PlannerState(CurrentCompoundTask, finalPlan, tasksToProcess, SatisfiedMethod);
                    // decompHistory.Push(currentState);
                    SatisfiedMethod.subTasks.Reverse();
                    foreach (Task t in SatisfiedMethod.subTasks)
                    {
                        tasksToProcess.Push(t);
                    }
                    SatisfiedMethod.subTasks.Reverse();
                }
                else if (decompHistory.Count > 0)
                {
                    //RestoreToLastDecomposedTask():
                    PlannerState lastState        = decompHistory.Pop();
                    CompoundTask lastCompoundTask = lastState.currentTask;
                    finalPlan      = lastState.finalPlan;
                    tasksToProcess = lastState.tasksToProcess;
                    // Remove the failed method and return CompoundTask to the stack. On the next iteration, it will be checked again for a valid method.
                    lastCompoundTask.InvalidateMethod(lastState.currentMethod);
                    tasksToProcess.Push(lastCompoundTask);
                }
            }
            else//Primitive Task
            {
                PrimitiveTask CurrentPrimitiveTask = (PrimitiveTask)CurrentTask;
                if (CurrentPrimitiveTask.PrimitiveConditionsMet(WorkingWS))
                {
                    // CurrentPrimitiveTask.ApplyEffects(this, WorkingWS);
                    // Add this PrimitiveTask to the bottom of the finalPlan
                    Stack <PrimitiveTask> temp = new Stack <PrimitiveTask>();
                    for (int i = 0; i < finalPlan.Count; i++)
                    {
                        PrimitiveTask nextTask = finalPlan.Pop();
                        temp.Push(nextTask);
                    }
                    temp.Push(CurrentPrimitiveTask);
                    finalPlan = new Stack <PrimitiveTask>();
                    for (int i = 0; i < temp.Count; i++)
                    {
                        PrimitiveTask nextTask = temp.Pop();
                        finalPlan.Push(nextTask);
                    }
                }
                else if (decompHistory.Count > 0)
                {
                    //RestoreToLastDecomposedTask();
                    PlannerState lastState        = decompHistory.Pop();
                    CompoundTask lastCompoundTask = lastState.currentTask;
                    finalPlan      = lastState.finalPlan;
                    tasksToProcess = lastState.tasksToProcess;
                    // Remove the failed method and return CompoundTask to the stack. On the next iteration, it will be checked again for a valid method.
                    lastCompoundTask.InvalidateMethod(lastState.currentMethod);
                    tasksToProcess.Push(lastCompoundTask);
                }
            }
        }
    }