Пример #1
0
        /// <summary>
        /// for debugging purposes. Provides a human readable string of all the preconditions.
        /// </summary>
        /// <param name="planner">Planner.</param>
        public string describe(ActionPlanner planner)
        {
            var sb = new StringBuilder();

            for (var i = 0; i < ActionPlanner.MAX_CONDITIONS; i++)
            {
                if ((dontCare & (1L << i)) == 0)
                {
                    var val = planner.conditionNames[i];
                    if (val == null)
                    {
                        continue;
                    }

                    bool set = ((values & (1L << i)) != 0L);

                    if (sb.Length > 0)
                    {
                        sb.Append(", ");
                    }
                    sb.Append(set ? val.ToUpper() : val);
                }
            }
            return(sb.ToString());
        }
        internal WorldState applyPostConditions(ActionPlanner ap, int actionnr, WorldState fr)
        {
            var  pst        = ap._postConditions[actionnr];
            long unaffected = pst.dontCare;
            long affected   = (unaffected ^ -1L);

            fr.values    = (fr.values & unaffected) | (pst.values & affected);
            fr.dontCare &= pst.dontCare;
            return(fr);
        }
Пример #3
0
 public Agent()
 {
     _planner = new ActionPlanner();
 }
Пример #4
0
 public WorldState(ActionPlanner planner, long values, long dontcare)
 {
     this.planner  = planner;
     this.values   = values;
     this.dontCare = dontcare;
 }
Пример #5
0
 public static WorldState create(ActionPlanner planner)
 {
     return(new WorldState(planner, 0, -1));
 }
Пример #6
0
        /* from: http://theory.stanford.edu/~amitp/GameProgramming/ImplementationNotes.html
         *      OPEN = priority queue containing START
         *      CLOSED = empty set
         *      while lowest rank in OPEN is not the GOAL:
         *        current = remove lowest rank item from OPEN
         *        add current to CLOSED
         *        for neighbors of current:
         *          cost = g(current) + movementcost(current, neighbor)
         *          if neighbor in OPEN and cost less than g(neighbor):
         *            remove neighbor from OPEN, because new path is better
         *          if neighbor in CLOSED and cost less than g(neighbor): **
         *            remove neighbor from CLOSED
         *          if neighbor not in OPEN and neighbor not in CLOSED:
         *            set g(neighbor) to cost
         *            add neighbor to OPEN
         *            set priority queue rank to g(neighbor) + h(neighbor)
         *            set neighbor's parent to current
         */

        /// <summary>
        /// Make a plan of actions that will reach desired world state
        /// </summary>
        /// <param name="ap">Ap.</param>
        /// <param name="start">Start.</param>
        /// <param name="goal">Goal.</param>
        /// <param name="storage">Storage.</param>
        public static Stack <Action> plan(ActionPlanner ap, WorldState start, WorldState goal, List <AStarNode> selectedNodes = null)
        {
            storage.clear();

            var currentNode = Utilities.Pool <AStarNode> .obtain();

            currentNode.worldState                = start;
            currentNode.parentWorldState          = start;
            currentNode.costSoFar                 = 0;                                                 // g
            currentNode.heuristicCost             = calculateHeuristic(start, goal);                   // h
            currentNode.costSoFarAndHeuristicCost = currentNode.costSoFar + currentNode.heuristicCost; // f
            currentNode.depth = 1;

            storage.addToOpenList(currentNode);

            while (true)
            {
                // nothing left open so we failed to find a path
                if (!storage.hasOpened())
                {
                    storage.clear();
                    return(null);
                }

                currentNode = storage.removeCheapestOpenNode();

                storage.addToClosedList(currentNode);

                // all done. we reached our goal
                if (goal.Equals(currentNode.worldState))
                {
                    var plan = reconstructPlan(currentNode, selectedNodes);
                    storage.clear();
                    return(plan);
                }

                var neighbors = ap.getPossibleTransitions(currentNode.worldState);
                for (var i = 0; i < neighbors.Count; i++)
                {
                    var cur    = neighbors[i];
                    var opened = storage.findOpened(cur);
                    var closed = storage.findClosed(cur);
                    var cost   = currentNode.costSoFar + cur.costSoFar;

                    // if neighbor in OPEN and cost less than g(neighbor):
                    if (opened != null && cost < opened.costSoFar)
                    {
                        // remove neighbor from OPEN, because new path is better
                        storage.removeOpened(opened);
                        opened = null;
                    }

                    // if neighbor in CLOSED and cost less than g(neighbor):
                    if (closed != null && cost < closed.costSoFar)
                    {
                        // remove neighbor from CLOSED
                        storage.removeClosed(closed);
                    }

                    // if neighbor not in OPEN and neighbor not in CLOSED:
                    if (opened == null && closed == null)
                    {
                        var nb = Utilities.Pool <AStarNode> .obtain();

                        nb.worldState                = cur.worldState;
                        nb.costSoFar                 = cost;
                        nb.heuristicCost             = calculateHeuristic(cur.worldState, goal);
                        nb.costSoFarAndHeuristicCost = nb.costSoFar + nb.heuristicCost;
                        nb.action           = cur.action;
                        nb.parentWorldState = currentNode.worldState;
                        nb.parent           = currentNode;
                        nb.depth            = currentNode.depth + 1;
                        storage.addToOpenList(nb);
                    }
                }

                // done with neighbors so release it back to the pool
                Utilities.ListPool <AStarNode> .free(neighbors);
            }
        }