// 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); }
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); }
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); }
// 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); }
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); }