예제 #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PathingAStar"/> class.
 /// </summary>
 /// <param name="heapInitialSize">Initial size of the heap.</param>
 /// <param name="moveCostProvider">The move cost provider.</param>
 /// <param name="pathSmoother">The path smoother to use.</param>
 public PathingAStar(int heapInitialSize, IMoveCost moveCostProvider, ICellCostStrategy cellCostStrategy, ISmoothPaths pathSmoother)
     : base(moveCostProvider, cellCostStrategy, pathSmoother)
 {
     _openSet = new BinaryHeap<IPathNode>(heapInitialSize, new PathNodeComparer());
     _expandedSet = new List<IPathNode>();
     _successorArray = new DynamicArray<IPathNode>(15);
 }
예제 #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PathingAStar"/> class.
 /// </summary>
 /// <param name="heapInitialSize">Initial size of the heap.</param>
 /// <param name="moveCostProvider">The move cost provider.</param>
 /// <param name="cellCostStrategy">The cell cost provider.</param>
 /// <param name="pathSmoother">The path smoother to use.</param>
 /// <param name="requestPreprocessors">The list of request preprocessors to use.</param>
 public PathingAStar(int heapInitialSize, IMoveCost moveCostProvider, ICellCostStrategy cellCostStrategy, ISmoothPaths pathSmoother, IRequestPreProcessor[] requestPreprocessors)
     : base(moveCostProvider, cellCostStrategy, pathSmoother, requestPreprocessors)
 {
     _openSet        = new BinaryHeap <IPathNode>(heapInitialSize, new PathNodeComparer());
     _expandedSet    = new List <IPathNode>();
     _successorArray = new DynamicArray <IPathNode>(15);
 }
예제 #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PathingEngineBase"/> class.
        /// </summary>
        /// <param name="moveCostProvider">The move cost provider.</param>
        /// <param name="smoother">The path smoother to use</param>
        protected PathingEngineBase(IMoveCost moveCostProvider, ISmoothPaths smoother)
        {
            Ensure.ArgumentNotNull(moveCostProvider, "moveCostProvider");
            Ensure.ArgumentNotNull(smoother, "smoother");

            _costProvider = moveCostProvider;
            _smoother = smoother;
        }
예제 #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PathingEngineBase"/> class.
        /// </summary>
        /// <param name="moveCostProvider">The move cost provider.</param>
        /// <param name="smoother">The path smoother to use</param>
        protected PathingEngineBase(IMoveCost moveCostProvider, ICellCostStrategy cellCostStrategy, ISmoothPaths smoother)
        {
            Ensure.ArgumentNotNull(moveCostProvider, "moveCostProvider");
            Ensure.ArgumentNotNull(cellCostStrategy, "cellCostStrategy");
            Ensure.ArgumentNotNull(smoother, "smoother");

            _costProvider     = moveCostProvider;
            _smoother         = smoother;
            _cellCostStrategy = cellCostStrategy;
            _coroutineIter    = new SafeIterator(this);
        }
예제 #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PathingEngineBase"/> class.
        /// </summary>
        /// <param name="moveCostProvider">The move cost provider.</param>
        /// <param name="smoother">The path smoother to use</param>
        protected PathingEngineBase(IMoveCost moveCostProvider, ICellCostStrategy cellCostStrategy, ISmoothPaths smoother)
        {
            Ensure.ArgumentNotNull(moveCostProvider, "moveCostProvider");
            Ensure.ArgumentNotNull(cellCostStrategy, "cellCostStrategy");
            Ensure.ArgumentNotNull(smoother, "smoother");

            _costProvider = moveCostProvider;
            _smoother = smoother;
            _cellCostStrategy = cellCostStrategy;
            _coroutineIter = new SafeIterator(this);
        }
        /// <summary>
        /// Gets the action cost.
        /// </summary>
        /// <param name="from">The node from which the action will start.</param>
        /// <param name="to">The node at which the action will end.</param>
        /// <param name="costProvider">The cost provider in use by the path finder.</param>
        /// <returns>
        /// The cost
        /// </returns>
        public int GetActionCost(IPositioned from, IPositioned to, IMoveCost costProvider)
        {
            //This is kind of an arbitrary thing. Under normal circumstances the cost of moving from one cell to another is equal to the distance between the cells.
            //Based on that the cost here would be the length of the arc of the jump. However speed is also a factor. One could get a reference to the IDefine speed component and use the current speed setting,
            //but we want to use a different speed for jumps, so to be accurate we would need to determine the speed difference and take that into account.
            //We do not want this calculation to be overly complex however, so for this example we keep it simple by using assumptions. This will produce a less accurate cost but...
            var halfDistance       = (to.position - from.position).magnitude / 2.0f;
            var hmax               = this.heightFactor * halfDistance * 2.0f;
            var assumedNormalSpeed = 3.0f;

            return((int)(2 * Mathf.Sqrt((halfDistance * halfDistance) + (hmax * hmax)) / (this.groundSpeed / assumedNormalSpeed)) * costProvider.baseMoveCost);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="PathingEngineBase"/> class.
        /// </summary>
        /// <param name="moveCostProvider">The move cost provider.</param>
        /// <param name="cellCostStrategy">The cell cost provider.</param>
        /// <param name="smoother">The path smoother to use</param>
        /// <param name="requestPreprocessors">The list of request preprocessors to use.</param>
        protected PathingEngineBase(IMoveCost moveCostProvider, ICellCostStrategy cellCostStrategy, ISmoothPaths smoother, IRequestPreProcessor[] requestPreprocessors)
        {
            Ensure.ArgumentNotNull(moveCostProvider, "moveCostProvider");
            Ensure.ArgumentNotNull(cellCostStrategy, "cellCostStrategy");
            Ensure.ArgumentNotNull(smoother, "smoother");

            _costProvider         = moveCostProvider;
            _smoother             = smoother;
            _cellCostStrategy     = cellCostStrategy;
            _coroutineIter        = new SafeIterator(this);
            _segmentRequest       = new SegmentRequest();
            _segments             = new DynamicArray <Path>(10);
            _requestPreprocessors = requestPreprocessors;
        }
예제 #8
0
        /// <summary>
        /// Gets the heuristic for a node in relation to this portal. This is only used for Shortcut portals, but is valid for all types.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="goal">The goal.</param>
        /// <param name="moveCostProvider">The move cost provider.</param>
        /// <returns>The heuristic</returns>
        public int GetHeuristic(IPathNode node, IPathNode goal, IMoveCost moveCostProvider)
        {
            //The logic here is that we want to shortest possible distance from the node to this portal cell,
            //combined with the shortest possible distance from our partner portal cell to the goal, again combined with the
            // cost of making the portal move using those two entry points.
            int mx = _matrixBounds.AdjustColumnToBounds(node.matrixPosX);
            int mz = _matrixBounds.AdjustRowToBounds(node.matrixPosZ);
            var closestCellToNode = this.parent.rawMatrix[mx, mz];

            mx = _partner._matrixBounds.AdjustColumnToBounds(goal.matrixPosX);
            mz = _partner._matrixBounds.AdjustRowToBounds(goal.matrixPosZ);
            var closestCellToGoal = _partner.parent.rawMatrix[mx, mz];

            return(moveCostProvider.GetHeuristic(node, closestCellToNode) + _action.GetActionCost(closestCellToNode, closestCellToGoal, moveCostProvider) + moveCostProvider.GetHeuristic(closestCellToGoal, goal));
        }
예제 #9
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PathingJumpPointSearch"/> class.
 /// </summary>
 /// <param name="heapInitialSize">Initial size of the heap.</param>
 /// <param name="moveCostProvider">The move cost provider.</param>
 /// <param name="pathSmoother">The path smoother to use.</param>
 public PathingJumpPointSearch(int heapInitialSize, IMoveCost moveCostProvider, ICellCostStrategy cellCostStrategy, ISmoothPaths pathSmoother)
     : base(heapInitialSize, moveCostProvider, cellCostStrategy, pathSmoother)
 {
     _neighbours = new DynamicArray<IPathNode>(8);
 }
예제 #10
0
 /// <summary>
 /// Gets the heuristic for a node in relation to this portal.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="goal">The goal.</param>
 /// <param name="moveCostProvider">The move cost provider.</param>
 /// <returns>The heuristic</returns>
 public int GetHeuristic(IPathNode node, IPathNode goal, IMoveCost moveCostProvider)
 {
     return moveCostProvider.GetHeuristic(node, this) + moveCostProvider.GetHeuristic(_partner, goal);
 }
예제 #11
0
        /// <summary>
        /// Dijkstra's algorithm, shortest paths between nodes in a graph
        /// https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
        /// Computes the distance table between two nodes in a graph
        /// All positions have 8 degrees of freedom, and the cost of moving between positions are equal to
        /// 1 + the absolute difference in value.
        /// </summary>
        /// <param name="items">2D value array</param>
        /// <param name="initial">Start position</param>
        /// <param name="end">End positions</param>
        public static int[,] Dijkstra(IMoveCost[,] items, Position initial, Position end)
        {
            // Let the node at which we are starting be called the initial node. Let the distance of node Y be the distance from the initial node to Y.
            // Dijkstra's algorithm will assign some initial distance values and will try to improve them step by step.
            int W = items.GetLength(0);
            int H = items.GetLength(1);

            int[,] distance = new int[W, H];
            bool[,] visited = new bool[W, H];

            // 1. Assign to every node a tentative distance value: set it to zero for our initial node and to infinity for all other nodes.
            // 2. Set the initial node as current. Mark all other nodes unvisited. Create a set of all the unvisited nodes called the unvisited set.
            List<Position> unvisited = new List<Position>();
            for (int x = 0; x < W; x++)
                for (int y = 0; y < H; y++)
                {
                    distance[x, y] = int.MaxValue;
                    visited[x, y] = false;
                    if (!(initial.x == x && initial.y == y))
                        unvisited.Add(new Position(x,y));
                }

            distance[initial.x, initial.y] = 0;

            Position current = initial;

            while (true) {
                // For the current node, consider all of its unvisited neighbors and calculate their tentative distances.
                // Compare the newly calculated tentative distance to the current assigned value and assign the smaller one.
                // For example, if the current node A is marked with a distance of 6, and the edge connecting it with a neighbor B
                // has length 2, then the distance to B (through A) will be 6 + 2 = 8. If B was previously marked with a distance
                // greater than 8 then change it to 8. Otherwise, keep the current value.
                var neighbors = GetUnvisitedNeighbors(visited, current);

                foreach (Position neighbor in neighbors)
                {
                    // get the cost of moving to the neighbor
                    int cost = items[neighbor.x, neighbor.y].MoveCost(items[current.x, current.y]);

                    // if the path is shorter than a previous path to the neighbor, update it
                    int path = MOVE_PENALTY + cost + distance[current.x, current.y];
                    if (path < distance[neighbor.x, neighbor.y])
                        distance[neighbor.x, neighbor.y] = path;
                }

                // When we are done considering all of the neighbors of the current node, mark the current node as visited
                // and remove it from the unvisited set. A visited node will never be checked again.
                unvisited.Remove(current);
                visited[current.x, current.y] = true;

                // If the destination node has been marked visited (when planning a route between two specific nodes)
                // or if the smallest tentative distance among the nodes in the unvisited set is infinity
                // (when planning a complete traversal; occurs when there is no connection between the initial node and
                // remaining unvisited nodes), then stop. The algorithm has finished.
                if (visited[end.x, end.y])
                    break;

                // Otherwise, select the unvisited node that is marked with the smallest tentative distance,
                // set it as the new "current node", and go back to step 3.
                current = (from p in unvisited
                                 orderby distance[p.x, p.y] ascending
                                 select new Position(p.x, p.y)).First();

            }

            return distance;
        }
 /// <summary>
 /// Gets the action cost.
 /// </summary>
 /// <param name="from">The node from which the action will start.</param>
 /// <param name="to">The node at which the action will end.</param>
 /// <param name="costProvider">The cost provider in use by the path finder.</param>
 /// <returns></returns>
 public int GetActionCost(IPositioned from, IPositioned to, IMoveCost costProvider)
 {
     return 0;
 }
 /// <summary>
 /// Gets the action cost.
 /// </summary>
 /// <param name="from">The node from which the action will start.</param>
 /// <param name="to">The node at which the action will end.</param>
 /// <param name="costProvider">The cost provider in use by the path finder.</param>
 /// <returns>The cost</returns>
 public int GetCost(IPositioned from, IPositioned to, IMoveCost costProvider)
 {
     return _action.GetActionCost(from, to, costProvider);
 }
        /// <summary>
        /// Gets the heuristic for a node in relation to this portal. This is only used for Shortcut portals, but is valid for all types.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="goal">The goal.</param>
        /// <param name="moveCostProvider">The move cost provider.</param>
        /// <returns>The heuristic</returns>
        public int GetHeuristic(IPathNode node, IPathNode goal, IMoveCost moveCostProvider)
        {
            //The logic here is that we want to shortest possible distance from the node to this portal cell,
            //combined with the shortest possible distance from our partner portal cell to the goal, again combined with the
            // cost of making the portal move using those two entry points.
            int mx = _matrixBounds.AdjustColumnToBounds(node.matrixPosX);
            int mz = _matrixBounds.AdjustRowToBounds(node.matrixPosZ);
            var closestCellToNode = this.parent.rawMatrix[mx, mz];

            mx = _partner._matrixBounds.AdjustColumnToBounds(goal.matrixPosX);
            mz = _partner._matrixBounds.AdjustRowToBounds(goal.matrixPosZ);
            var closestCellToGoal = _partner.parent.rawMatrix[mx, mz];

            return moveCostProvider.GetHeuristic(node, closestCellToNode) + _action.GetActionCost(closestCellToNode, closestCellToGoal, moveCostProvider) + moveCostProvider.GetHeuristic(closestCellToGoal, goal);
        }
예제 #15
0
 /// <summary>
 /// Computes the shortest path between two positions, in a 2D table. 
 /// All positions have 8 degrees of freedom, and the cost of moving between positions are equal to
 /// 1 + the absolute difference in value.
 /// </summary>
 /// <param name="values">2D Cell array</param>
 /// <param name="initial">Start position</param>
 /// <param name="end">End positions</param>
 /// <returns></returns>
 public static List<Position> GetShortestPath(IMoveCost[,] values, Position initial, Position end)
 {
     // Use Dijkstra's algorithm to compute the distance table for the given values
     int[,] dist = Dijkstra(values, initial, end);
     // traverse the shortest path and return list
     return GetShortestPathFromDistance(dist, initial, end);
 }
 /// <summary>
 /// Gets the action cost.
 /// </summary>
 /// <param name="from">The node from which the action will start.</param>
 /// <param name="to">The node at which the action will end.</param>
 /// <param name="costProvider">The cost provider in use by the path finder.</param>
 /// <returns></returns>
 public int GetActionCost(IPositioned from, IPositioned to, IMoveCost costProvider)
 {
     return(0);
 }
예제 #17
0
 /// <summary>
 /// Gets the action cost.
 /// </summary>
 /// <param name="from">The node from which the action will start.</param>
 /// <param name="to">The node at which the action will end.</param>
 /// <param name="costProvider">The cost provider in use by the path finder.</param>
 /// <returns></returns>
 public int GetActionCost(IPositioned from, IPositioned to, IMoveCost costProvider)
 {
     return costProvider.GetHeuristic(from, to);
 }
 public VisualizedJPS(int heapInitialSize, IMoveCost moveCostProvider, ICellCostStrategy cellCostStrategy, ISmoothPaths pathSmoother, IRequestPreProcessor[] requestPreprocessors)
     : base(heapInitialSize, moveCostProvider, cellCostStrategy, pathSmoother, requestPreprocessors)
 {
 }
 /// <summary>
 /// Gets the action cost.
 /// </summary>
 /// <param name="from">The node from which the action will start.</param>
 /// <param name="to">The node at which the action will end.</param>
 /// <param name="costProvider">The cost provider in use by the path finder.</param>
 /// <returns></returns>
 public int GetActionCost(IPositioned from, IPositioned to, IMoveCost costProvider)
 {
     return(costProvider.GetHeuristic(from, to));
 }
예제 #20
0
 /// <summary>
 ///  Calculates the cost of moving between two IMoveCost objects
 /// </summary>
 /// <param name="B">Object to move to</param>
 /// <returns>Cost</returns>
 public int MoveCost(IMoveCost B)
 {
     return(Math.Abs(this.Value - B.Value));
 }
예제 #21
0
 /// <summary>
 /// Gets the heuristic from this portal to the goal.
 /// </summary>
 /// <param name="goal">The goal.</param>
 /// <param name="moveCostProvider">The move cost provider.</param>
 /// <returns>The heuristic</returns>
 //TODO: this si not used, so remove it
 public int GetHeuristic(IPathNode goal, IMoveCost moveCostProvider)
 {
     return(moveCostProvider.GetHeuristic(_partner, goal));
 }
예제 #22
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PathingJumpPointSearch"/> class.
 /// </summary>
 /// <param name="heapInitialSize">Initial size of the heap.</param>
 /// <param name="moveCostProvider">The move cost provider.</param>
 /// <param name="cellCostStrategy">The cell cost provider.</param>
 /// <param name="pathSmoother">The path smoother to use.</param>
 /// <param name="requestPreprocessors">The list of request preprocessors to use.</param>
 public PathingJumpPointSearch(int heapInitialSize, IMoveCost moveCostProvider, ICellCostStrategy cellCostStrategy, ISmoothPaths pathSmoother, IRequestPreProcessor[] requestPreprocessors)
     : base(heapInitialSize, moveCostProvider, cellCostStrategy, pathSmoother, requestPreprocessors)
 {
     _neighbours = new DynamicArray <IPathNode>(8);
 }
예제 #23
0
 /// <summary>
 /// Gets the action cost.
 /// </summary>
 /// <param name="from">The node from which the action will start.</param>
 /// <param name="to">The node at which the action will end.</param>
 /// <param name="costProvider">The cost provider in use by the path finder.</param>
 /// <returns>The cost</returns>
 public int GetCost(IPositioned from, IPositioned to, IMoveCost costProvider)
 {
     return(_action.GetActionCost(from, to, costProvider));
 }
예제 #24
0
파일: CellTable.cs 프로젝트: martsve/arpath
 /// <summary>
 ///  Calculates the cost of moving between two IMoveCost objects
 /// </summary>
 /// <param name="B">Object to move to</param>
 /// <returns>Cost</returns>
 public int MoveCost(IMoveCost B)
 {
     return Math.Abs(this.Value - B.Value);
 }