Example #1
0
    private static Queue <GameObject> cubiclesAvailableQ;             //a qeueue to update the environment to determine the available cubicles


    static Environment()                                                      //constructor
    {
        environment        = new EnvironmentStates();                         //setup the enviornment states list (as an EnvironmentState type that holds the dictionary of states)
        patientsWaitingQ   = new Queue <GameObject>();                        //initialising the patient queue for use
        cubiclesAvailableQ = new Queue <GameObject>();                        //initialising the cubicles queue for use (this needs to be populated by the ones that exist in the world)

        GameObject[] cubicles = GameObject.FindGameObjectsWithTag("Cubicle"); //find the cubicles in the scene and store them in this list
        foreach (GameObject cubicle in cubicles)                              //populate the cubcicles queue with cubicles found in scene
        {
            cubiclesAvailableQ.Enqueue(cubicle);
        }

        if (cubicles.Length > 0)                                     //if cubicles are found in the world
        {
            environment.ModifyState("FreeCubicle", cubicles.Length); //update the environment states based on how many are available
        }

        Time.timeScale = 3; //speed up simulation (CHANGE WHEN TESTING)
    }
Example #2
0
    public void Awake()                                        //to initialize variables and required states before actions are used (avoid null)
    {
        agent = this.gameObject.GetComponent <NavMeshAgent>(); //get hold of the NavMesh agent performing the action

        //populate the preconditions and effects dictionaries with the values popluated from the inpsector by being added the preConditions and afterEffects
        if (preConditions != null)                        //ensure that they are set in the inspector to avoid a crash at runtime
        {
            foreach (EnvironmentState w in preConditions) //for every action precondition
            {
                preconditions.Add(w.key, w.value);        //add it to the preconditions dictionary for use in the planner
            }
        }
        //similary done for the effects
        if (afterEffects != null)
        {
            foreach (EnvironmentState w in afterEffects) //for every action after effect
            {
                effects.Add(w.key, w.value);             //add it to the actions dictionary for use in the planner
            }
        }

        inventory = this.GetComponent <Agent>().inventory; //get the resources available to the agent
        beliefs   = this.GetComponent <Agent>().beliefs;   //give the action access to the environment states the agent knows about  (agent instant that is performing "this" action)
    }
    public Queue <Action> plan(List <Action> actions, Dictionary <string, int> goal, EnvironmentStates beliefstates) //method to return a plan for an agent to simulate given the actions an agent can perform, the goals that need to be satisfied by the agent type, and the state of agent
    {
        List <Action> usableActions = new List <Action>();                                                           //to store the list of actions that are usable/can be matched

        foreach (Action a in actions)                                                                                //go through all actions
        {
            //discard actions that cannot be used
            if (a.IsAchievable())     //if an action can be performed
            {
                usableActions.Add(a); //then it is added to the usable list
            }
        }

        List <Node> leaves = new List <Node>();                                                                                 //create a list to store the nodes
        Node        start  = new Node(null, 0.0f, Environment.Instance.GetWorld().GetStates(), beliefstates.GetStates(), null); //the starting node from which the planner will construct the action chain for the agent to perform (given null parent and action with zero cost as it is the initial node)

        bool success = FindPlan(start, leaves, usableActions, goal);                                                            //return true or false based on if a succesful plan can be found (using called mehod) that leads to the goal

        if (!success)                                                                                                           //when no plan can be found, give feedback through output log and return null
        {
            Debug.Log("CANNOT FORMULATE PLAN"); return(null);
        }

        //if this point in the code is reached, that means a plan can be constructed to achieve the goal
        Node cheapest = null;                   //set cheapest node to null before finding it (in case not found or another issue occurs) The cheapest node is set as the initial node from which the planner will formulate the plan

        foreach (Node leaf in leaves)           //loop through all nodes being used to contruct potential plans
        {
            if (cheapest == null)               //if cheapest node has not been set
            {
                cheapest = leaf;                //use the first node checked
            }
            else if (leaf.cost < cheapest.cost) //if the current node being checked is less than the cheapest node
            {
                cheapest = leaf;                //then set the current node being checked as the cheapest one
            }
        }

        //when the cheapest node has been found, the planner will work backwards from it and across the chain to get a sequence of actions
        List <Action> result = new List <Action>(); //list to store actions that make up the resulting plan -> the action chain
        Node          n      = cheapest;            //make a copy of the cheapest node to modify it without what node it was

        while (n != null)                           //while the cheapest node does exist
        {
            if (n.action != null)                   //check that an action exists within this node (avoiding null error)
            {
                result.Insert(0, n.action);         //record it in the plan
            }
            n = n.parent;                           //move onto the successor node (an so on until a plan is formulated)
        }

        Queue <Action> queue = new Queue <Action>(); //creating the queue of actions which agents can use to simulate the plan

        foreach (Action a in result)                 //extract the actions from the plan onto this queue
        {
            queue.Enqueue(a);                        //the queue adds items starting from the end of the queue but since the planner worked bakcwards to formulate this plan, the there is not need to modify the order of the set of actions as a result
        }

        //debugging logs to observe the data during the simulation
        Debug.Log("PLAN FOUND");
        foreach (Action a in queue)
        {
            Debug.Log("Queue: " + a.actionName);
        }

        return(queue); //method returns the queue of actions that makes up the plan
    }