Exemplo n.º 1
0
        /// <summary>
        /// Takes in a queue and it's most recently popped Vector2Path, then if applicable, enqueues a new Vector2Path, which is the old Vector2Path and the goal vector added on.
        /// </summary>
        /// <param name="nextStep"></param>
        /// <param name="queue"></param>
        /// <param name="soFar"></param>
        /// <param name="useWeights"></param>
        private void dijkstraEnqueue(Vector2 nextStep, DijkstraQueue queue, Vector2Path soFar, bool useWeights, Vector2 goalNode, bool moveThroughActors)
        {
            LinkedListNode <Vector2> currentNode = soFar.pathSoFar.Last;
            Vector2 currentPos = currentNode.Value;

            if (withinGrid(nextStep.X, nextStep.Y) && (!visited[(int)nextStep.X, (int)nextStep.Y] &&
                                                       connections[(int)currentPos.X, (int)currentPos.Y, (int)nextStep.X, (int)nextStep.Y] &&
                                                       moveThroughActors ? true : !spaceArray[(int)nextStep.X, (int)nextStep.Y].IsOccupied))
            {
                Vector2Path newPath = new Vector2Path(soFar.pathSoFar, nextStep,
                                                      soFar.totalCost + (useWeights ? movementCosts[(int)currentPos.X, (int)currentPos.Y, (int)nextStep.X, (int)nextStep.Y] : 1));
                //If we are using weights, add the weight, otherwise add 1 for constant weighting.
                queue.enqueue(newPath, goalNode);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Runs Dijkstra's Two Points Shortest Path algorithm
        /// </summary>
        /// <param name="sourceNodePos">Position at which the Vector2Path must start.</param>
        /// <param name="targetNodePos">Position at which the Vector2Path must end.</param>
        /// <param name="useWeights">Determines whether to use simple connection, or weighted paths.</param>
        /// <returns>The shortest Vector2Path between the two points</returns>
        public LinkedList <Vector2> Dijkstra(Vector2 sourceNodePos, Vector2 targetNodePos, bool useWeights, bool moveThroughActors)
        {
            LinkedList <Vector2> result = new LinkedList <Vector2>(), startingPath = new LinkedList <Vector2>();

            if (sourceNodePos == targetNodePos || (moveThroughActors && spaceArray[(int)targetNodePos.X, (int)targetNodePos.Y].IsOccupied))
            {
                return(result);
            }
            for (int i = 0; i < sizeX; ++i)
            {
                for (int j = 0; j < sizeY; ++j)
                {
                    visited[i, j] = false;
                }
            }
            int targetX = (int)targetNodePos.X;
            int targetY = (int)targetNodePos.Y;

            visited[(int)sourceNodePos.X, (int)sourceNodePos.Y] = true;
            Vector2Path   currentPath = new Vector2Path(startingPath, sourceNodePos, 0);
            DijkstraQueue dkQ         = new DijkstraQueue(visited);

            dkQ.enqueue(currentPath, targetNodePos);

            while (!visited[targetX, targetY] && dkQ.count > 0)
            {
                currentPath = dkQ.dequeue();
                currentPath.pathSoFar.AddLast(currentPath.nextStep);
                visited[(int)currentPath.nextStep.X, (int)currentPath.nextStep.Y] = true;
                //Enqueue the 4 cardinal directional neighbors
                dijkstraEnqueue(currentPath.nextStep + Vector2.UnitY, dkQ, currentPath, useWeights, targetNodePos, moveThroughActors);
                dijkstraEnqueue(currentPath.nextStep - Vector2.UnitY, dkQ, currentPath, useWeights, targetNodePos, moveThroughActors);
                dijkstraEnqueue(currentPath.nextStep + Vector2.UnitX, dkQ, currentPath, useWeights, targetNodePos, moveThroughActors);
                dijkstraEnqueue(currentPath.nextStep - Vector2.UnitX, dkQ, currentPath, useWeights, targetNodePos, moveThroughActors);

                //Enqueue the two off-kilter neighbors, which will either be above or below the horizontal neighbors.
                dijkstraEnqueue(currentPath.nextStep + Vector2.UnitX + Vector2.UnitY * (currentPath.nextStep.X % 2 == 0 ? -1 : 1),
                                dkQ, currentPath, useWeights, targetNodePos, moveThroughActors);
                dijkstraEnqueue(currentPath.nextStep - Vector2.UnitX + Vector2.UnitY * (currentPath.nextStep.X % 2 == 0 ? -1 : 1),
                                dkQ, currentPath, useWeights, targetNodePos, moveThroughActors);
            }
            result = currentPath.pathSoFar;
            return(result);
        }
Exemplo n.º 3
0
 /// <summary>
 /// Takes in a queue and it's most recently popped Vector2Path, then if applicable, enqueues a new Vector2Path, which is the old Vector2Path and the goal vector added on.
 /// </summary>
 /// <param name="nextStep"></param>
 /// <param name="queue"></param>
 /// <param name="soFar"></param>
 /// <param name="useWeights"></param>
 private void dijkstraEnqueue(Vector2 nextStep, DijkstraQueue queue, Vector2Path soFar, bool useWeights, Vector2 goalNode, bool moveThroughActors)
 {
     LinkedListNode<Vector2> currentNode = soFar.pathSoFar.Last;
     Vector2 currentPos = currentNode.Value;
     if (withinGrid(nextStep.X, nextStep.Y) && (!visited[(int)nextStep.X, (int)nextStep.Y] &&
             connections[(int)currentPos.X, (int)currentPos.Y, (int)nextStep.X, (int)nextStep.Y] 
             && moveThroughActors ? true : !spaceArray[(int)nextStep.X, (int)nextStep.Y].IsOccupied))
     {
         Vector2Path newPath = new Vector2Path(soFar.pathSoFar, nextStep,
             soFar.totalCost + (useWeights ? movementCosts[(int)currentPos.X, (int)currentPos.Y, (int)nextStep.X, (int)nextStep.Y] : 1));
             //If we are using weights, add the weight, otherwise add 1 for constant weighting.
         queue.enqueue(newPath, goalNode);
     }
 }
Exemplo n.º 4
0
        /// <summary>
        /// Runs Dijkstra's Two Points Shortest Path algorithm
        /// </summary>
        /// <param name="sourceNodePos">Position at which the Vector2Path must start.</param>
        /// <param name="targetNodePos">Position at which the Vector2Path must end.</param>
        /// <param name="useWeights">Determines whether to use simple connection, or weighted paths.</param>
        /// <returns>The shortest Vector2Path between the two points</returns>
        public LinkedList<Vector2> Dijkstra(Vector2 sourceNodePos, Vector2 targetNodePos, bool useWeights, bool moveThroughActors)
        {
            LinkedList<Vector2> result = new LinkedList<Vector2>(), startingPath = new LinkedList<Vector2>();
            if(sourceNodePos == targetNodePos || (moveThroughActors && spaceArray[(int)targetNodePos.X, (int)targetNodePos.Y].IsOccupied)) return result;
            for(int i = 0; i < sizeX; ++i)
            {
                for(int j = 0; j < sizeY; ++j)
                {
                    visited[i,j] = false;
                }
            }
            int targetX = (int) targetNodePos.X;
            int targetY = (int) targetNodePos.Y;
            visited[(int) sourceNodePos.X, (int) sourceNodePos.Y] = true;
            Vector2Path currentPath = new Vector2Path(startingPath, sourceNodePos, 0);
            DijkstraQueue dkQ = new DijkstraQueue(visited);
            dkQ.enqueue(currentPath, targetNodePos);

            while(!visited[targetX, targetY] && dkQ.count > 0)
            {
                currentPath = dkQ.dequeue();
                currentPath.pathSoFar.AddLast(currentPath.nextStep);
                visited[(int)currentPath.nextStep.X, (int)currentPath.nextStep.Y] = true;
                //Enqueue the 4 cardinal directional neighbors
                dijkstraEnqueue(currentPath.nextStep + Vector2.UnitY, dkQ, currentPath, useWeights, targetNodePos, moveThroughActors);
                dijkstraEnqueue(currentPath.nextStep - Vector2.UnitY, dkQ, currentPath, useWeights, targetNodePos, moveThroughActors);
                dijkstraEnqueue(currentPath.nextStep + Vector2.UnitX, dkQ, currentPath, useWeights, targetNodePos, moveThroughActors);
                dijkstraEnqueue(currentPath.nextStep - Vector2.UnitX, dkQ, currentPath, useWeights, targetNodePos, moveThroughActors);

                //Enqueue the two off-kilter neighbors, which will either be above or below the horizontal neighbors.
                dijkstraEnqueue(currentPath.nextStep + Vector2.UnitX + Vector2.UnitY * (currentPath.nextStep.X % 2 == 0 ? -1 : 1),
                    dkQ, currentPath, useWeights, targetNodePos, moveThroughActors);
                dijkstraEnqueue(currentPath.nextStep - Vector2.UnitX + Vector2.UnitY * (currentPath.nextStep.X % 2 == 0 ? -1 : 1),
                    dkQ, currentPath, useWeights, targetNodePos, moveThroughActors);
            }
            result = currentPath.pathSoFar;
            return result;
        }