// calculating the path between two nodes
        private List <Node> CalculatePath(Node start, Node target)
        {
            List <Node> pathResult = new List <Node>();

            // create the lists
            Heap <Node>    openList   = new Heap <Node>(grid.MaxSize); // nodes to evaluate
            HashSet <Node> closedList = new HashSet <Node>();          // evaluated nodes

            // add the start node to the open list
            openList.Add(start);

            while (openList.Count > 0)
            {
                Node currentNode = openList.RemoveFirstElement();
                closedList.Add(currentNode);

                // check if the current node is the target
                if (currentNode.Equals(target))
                {
                    // recreate the path
                    pathResult = Backtrack(start, target);
                    break; // done <3
                }

                // else, continue on and get all neighbor nodes from the current node
                foreach (Node neighbor in GetNeighbors(currentNode, true))
                {
                    if (!closedList.Contains(neighbor)) // neighbor has not been evaluated yet
                    {
                        // calculate movement cost to node
                        float movementCostToNeighbor = currentNode.gCost + GetHCost(currentNode, neighbor);

                        // check if its lower than neighbors gCost or the neighbor is not yet in the open list
                        if (movementCostToNeighbor < neighbor.gCost || !openList.ContainsElement(neighbor))
                        {
                            // update gCost and hCost and set the parent
                            neighbor.gCost      = movementCostToNeighbor;
                            neighbor.hCost      = GetHCost(neighbor, target);
                            neighbor.parentNode = currentNode;

                            //add the neighbor to the open list
                            if (!openList.ContainsElement(neighbor))
                            {
                                openList.Add(neighbor);
                            }
                        }
                    }
                }
            }
            // done <3
            return(pathResult);
        }
Пример #2
0
        private List <Node> FindPathActual(Node start, Node target)
        {
            //Typical A* algorythm...
            List <Node> foundPath = new List <Node>();

            //We need two lists, one for the nodes we need to check, and one for nodes we've already checked.
            List <Node>    openSet   = new List <Node>();
            HashSet <Node> closedSet = new HashSet <Node>();

            openSet.Add(start);

            while (openSet.Count > 0)
            {
                Node currentNode = openSet[0];

                for (int i = 0; i < openSet.Count; i++)
                {
                    //We check the costs for the current node. More is possible but not important now.
                    if (openSet[i].fCost < currentNode.fCost ||
                        (openSet[i].fCost == currentNode.fCost &&
                         openSet[i].hCost < currentNode.hCost))
                    {
                        //We assign a new current node.
                        if (!currentNode.Equals(openSet[i]))
                        {
                            currentNode = openSet[i];
                        }
                    }
                }

                //We remove the current node from the open set and add to the closed set.
                openSet.Remove(currentNode);
                closedSet.Add(currentNode);

                //If our current node is the target node...
                if (currentNode.Equals(target))
                {
                    //We've found our destination, it's time to trace our path.
                    foundPath = RetracePath(start, currentNode);
                    break;
                }

                //If we haven't reached the target, we need to start looking at the neighbors.
                foreach (Node neighbor in GetNeighbors(currentNode, true))
                {
                    if (!closedSet.Contains(neighbor))
                    {
                        //We create a new movement cost for our neighbors
                        float newMovementCostToNeighbor = currentNode.gCost + GetDistance(currentNode, neighbor);

                        //And if it is lower than the neighbor's cost...
                        if (newMovementCostToNeighbor < neighbor.gCost || !openSet.Contains(neighbor))
                        {
                            //We allocate new costs
                            neighbor.gCost = newMovementCostToNeighbor;
                            neighbor.hCost = GetDistance(neighbor, target);

                            //Assign the parent node
                            neighbor.parentNode = currentNode;

                            //And add the neighbor node to the open set
                            if (!openSet.Contains(neighbor))
                            {
                                openSet.Add(neighbor);
                            }
                        }
                    }
                }
            }

            //We return the path at the end.
            return(foundPath);
        }
Пример #3
0
        private List <Node> FindPathActual(Node start, Node target)
        {
            //Typical A* algorythm from here and on

            List <Node> foundPath = new List <Node>();

            //We need two lists, one for the nodes we need to check and one for the nodes we've already checked
            List <Node>    openSet   = new List <Node>();
            HashSet <Node> closedSet = new HashSet <Node>();

            //We start adding to the open set
            openSet.Add(start);

            while (openSet.Count > 0)
            {
                Node currentNode = openSet[0];

                for (int i = 0; i < openSet.Count; i++)
                {
                    //We check the costs for the current node
                    //You can have more opt. here but that's not important now
                    if (openSet[i].fCost < currentNode.fCost ||
                        (openSet[i].fCost == currentNode.fCost &&
                         openSet[i].hCost < currentNode.hCost))
                    {
                        //and then we assign a new current node
                        if (!currentNode.Equals(openSet[i]))
                        {
                            currentNode = openSet[i];
                        }
                    }
                }

                //we remove the current node from the open set and add to the closed set
                openSet.Remove(currentNode);
                closedSet.Add(currentNode);

                //if the current node is the target node
                if (currentNode.Equals(target))
                {
                    //that means we reached our destination, so we are ready to retrace our path
                    foundPath = RetracePath(start, currentNode);
                    break;
                }

                //if we haven't reached our target, then we need to start looking the neighbours
                foreach (Node neighbour in GetNeighbours(currentNode, true))
                {
                    if (!closedSet.Contains(neighbour))
                    {
                        //we create a new movement cost for our neighbours
                        float newMovementCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbour);

                        //and if it's lower than the neighbour's cost
                        if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour))
                        {
                            //we calculate the new costs
                            neighbour.gCost = newMovementCostToNeighbour;
                            neighbour.hCost = GetDistance(neighbour, target);
                            //Assign the parent node
                            neighbour.parentNode = currentNode;
                            //And add the neighbour node to the open set
                            if (!openSet.Contains(neighbour))
                            {
                                openSet.Add(neighbour);
                            }
                        }
                    }
                }
            }

            //we return the path at the end
            return(foundPath);
        }
        private List <Node> FindPathActual(Node start, Node target)
        {
            List <Node> foundPath = new List <Node>();

            List <Node>    openSet   = new List <Node>();
            HashSet <Node> closedSet = new HashSet <Node>();

            openSet.Add(start);

            while (openSet.Count > 0)
            {
                Node currentNode = openSet[0];

                if (currentNode.Equals(target))
                {
                    foundPath = RetracePath(start, currentNode);
                    break;
                }

                openSet.Remove(currentNode);
                closedSet.Add(currentNode);

                for (int i = 0; i < openSet.Count; i++)
                {
                    if (openSet[i].fCost < currentNode.fCost ||
                        (openSet[i].fCost == currentNode.fCost &&
                         openSet[i].hCost < currentNode.hCost))
                    {
                        if (!currentNode.Equals(openSet[i]))
                        {
                            currentNode = openSet[i];
                        }
                    }
                }

                //				openSet.Remove (currentNode);
                //				closedSet.Add (currentNode);
                //
                //				if (currentNode.Equals (target)) {
                //					foundPath = RetracePath (start, currentNode);
                //					break;
                //				}

                foreach (Node neighbor in GetNeighbors(currentNode))
                {
                    if (!closedSet.Contains(neighbor))
                    {
                        float newMovementCostToNeighbor = currentNode.gCost + GetDistance(currentNode, neighbor) + neighbor.movementPenalty;

                        if (newMovementCostToNeighbor < neighbor.gCost || !openSet.Contains(neighbor))
                        {
                            neighbor.gCost      = newMovementCostToNeighbor;
                            neighbor.hCost      = GetDistance(neighbor, target);
                            neighbor.parentNode = currentNode;

                            if (!openSet.Contains(neighbor))
                            {
                                openSet.Add(neighbor);
                            }
                        }
                    }
                }
            }

            return(foundPath);
        }
Пример #5
0
        // grid:         grid to search in
        // startPos:     starting position
        // targetPos:    ending position
        // mask:         the walkable nodes for this path
        // path:         an array for holding the path
        public static int Find(Grid grid,
                               Point2 startPos,
                               Point2 targetPos,
                               int mask,
                               ref PathData[]    path)
        {
            Node startNode  = Grid.GetNode(grid, startPos.x, startPos.y);
            Node targetNode = Grid.GetNode(grid, targetPos.x, targetPos.y);
            int  gridwidth  = Grid.GetWidth(grid);

            Grid.ClearBuffer(grid);
            Grid.AddToOpenSet(grid, startNode);

            while (Grid.GetOpenSetCount(grid) > 0)
            {
                Node currentNode = Grid.RemoveFirstFromOpenSet(grid);
                int  ci          = Grid.GetIndex(gridwidth, currentNode.x, currentNode.y);
                Grid.AddToClosedSet(grid, ci);

                // Return when looking for a path that goes from and to the
                // same node
                if (currentNode.Equals(targetNode))
                {
                    return(RetracePath(grid, startNode, targetNode, ref path));
                }

                int nodeIndex = Grid.GetIndex(gridwidth, currentNode.x, currentNode.y);

                int numNeighbours = Grid.UpdateNeighboursCache(grid, nodeIndex);
                for (int i = 0; i < numNeighbours; ++i)
                {
                    Node neighbour  = Grid.GetNeighbour(grid, i);
                    int  ni         = Grid.GetIndex(gridwidth, neighbour.x, neighbour.y);
                    int  nt         = Node.GetType(neighbour);
                    bool isWalkable = (mask & nt) == 0;

                    // Continue searching when neighbour is not walkable,
                    // or already checked
                    if (!isWalkable || Grid.ClosedSetContains(grid, ni))
                    {
                        continue;
                    }

                    int newMovementCostToNeighbour = currentNode.gCost + GetDistance(currentNode.x,
                                                                                     currentNode.y,
                                                                                     neighbour.x,
                                                                                     neighbour.y);
                    bool openContainsNeighbour = Grid.OpenSetContains(grid, neighbour);
                    if (newMovementCostToNeighbour >= neighbour.gCost && openContainsNeighbour)
                    {
                        continue;
                    }

                    neighbour.gCost = newMovementCostToNeighbour;
                    neighbour.hCost = GetDistance(neighbour.x, neighbour.y, targetNode.x, targetNode.y);
                    neighbour.fCost = neighbour.gCost + neighbour.hCost;

                    Grid.LinkNode(grid, ni, ci);

                    if (!openContainsNeighbour)
                    {
                        Grid.AddToOpenSet(grid, neighbour);
                    }
                }
            }

            return(0);
        }
Пример #6
0
        private List <Node> FindPathActual(Node start, Node target)
        {
            //A* algorithm

            List <Node> foundPath = new List <Node>();

            //Two lists, one for the nodes that needs to be checked and one for the ones that already are checked
            List <Node>    openSet   = new List <Node>();
            HashSet <Node> closedSet = new HashSet <Node>();

            //Adding to open set
            openSet.Add(start);

            while (openSet.Count > 0)
            {
                Node currentNode = openSet[0];

                for (int i = 0; i < openSet.Count; i++)
                {
                    //Check cost for current node
                    if (openSet[i].fCost < currentNode.fCost ||
                        (openSet[i].fCost == currentNode.fCost &&
                         openSet[i].hCost < currentNode.hCost))
                    {
                        //assign new current node
                        if (!currentNode.Equals(openSet[i]))
                        {
                            currentNode = openSet[i];
                        }
                    }
                }

                //remove the current node from the open set and add to the closed set
                openSet.Remove(currentNode);
                closedSet.Add(currentNode);

                //if the current node is the target node
                if (currentNode.Equals(target))
                {
                    //reached destination, retrace path
                    foundPath = RetracePath(start, currentNode);
                    break;
                }

                //if target isn't reached, look at neighbours
                foreach (Node neighbour in GetNeighbours(currentNode, true))
                {
                    if (!closedSet.Contains(neighbour))
                    {
                        //create movement cost for neighbours
                        float newMovementCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbour);

                        //if lower than neighbour cost
                        if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour))
                        {
                            //calculate new cost
                            neighbour.gCost = newMovementCostToNeighbour;
                            neighbour.hCost = GetDistance(neighbour, target);
                            //assign the parent node
                            neighbour.parentNode = currentNode;
                            //add neighbour node to open set
                            if (!openSet.Contains(neighbour))
                            {
                                openSet.Add(neighbour);
                            }
                        }
                    }
                }
            }

            //return the path in the end
            return(foundPath);
        }