/// <summary> /// Checks the neiboring nodes /// </summary> /// <param name="inDirection">0-7, counter-clockwise starting at 0 degrees. (degrees = direction*45)</param> private static void checkNeighborNode(Node inNode, int inDirection) { int nodeX = inNode.getX(); int nodeY = inNode.getY(); int checkX = nodeX; int checkY = nodeY; //Simple equation to set the distance multiplication float distanceMultiplication = (inDirection % 2 == 0) ? 1.0f : 1.414f; //Get the neighboring node's position switch (inDirection) { case 0: checkX += 1; break; case 1: checkX += 1; checkY -= 1; break; case 2: checkY -= 1; break; case 3: checkX -= 1; checkY -= 1; break; case 4: checkX -= 1; break; case 5: checkX -= 1; checkY += 1; break; case 6: checkY += 1; break; case 7: checkX += 1; checkY += 1; break; } //Only continue if the check position is still on the grid if (checkX < gridWidth && checkX >= 0 && checkY < gridHeight && checkY >= 0) { //Now that we know it's still on the grid, get the node at that position Node checkNode = getNodeAtPosition(checkX, checkY); //Now only continue if the checkNode hasn't been circled and it's passable if (!checkNode.getCircled() && checkNode.getValue() != IMPASSABLE_VALUE) { //Now calculate the various values for the check node float currentNodeDistanceFromStart = inNode.getDistanceFromStart(); float toNodeDistance = checkNode.getValue() * distanceMultiplication; float estimatedDistance = currentNodeDistanceFromStart + toNodeDistance + checkNode.getManhattanDistance(); //Update the estimated distance if it'll be smaller //or if it hasn't been set yet if (estimatedDistance < checkNode.getEstimatedDistance() || checkNode.getEstimatedDistance() < 0) { checkNode.setParent(inNode); checkNode.setDistanceFromStart(currentNodeDistanceFromStart + toNodeDistance); checkNode.setEstimatedDistance(estimatedDistance); addToCheckList(checkNode); } } } }
//The base method for finding a path using A* private static void findPath() { bool foundPath = false; //Whether or not a path has been found Node startingNode = getNodeAtPosition(startX, startY); //The starting node startingNode.setPath(true); //Tell the starting node it's on the final path Node currentNode = startingNode; //It should start at the beginning Node endingNode = getNodeAtPosition(endX, endY); //It should end at the end while (!foundPath) { //Circle the current node //and set the estimated distances for all nodes surrounding the current node currentNode.setCircled(true); for (int ii = 0; ii < 8; ii += 1) { checkNeighborNode(currentNode, ii); } Node nextNode; //Get the next node if there is one in the check list if (checkNodes.Count > 0) { nextNode = (Node)checkNodes[0]; } else { nextNode = null; } //If the nextNode isn't null if (nextNode != null) { //Remove it from the check list because we're using it now checkNodes.RemoveAt(0); //Circle it nextNode.setCircled(true); //Now set it as the current node currentNode = nextNode; //Now see if we've found the end if (currentNode == endingNode) { Console.WriteLine("Found the end node"); Console.WriteLine("Total distance is: " + currentNode.getDistanceFromStart()); Console.WriteLine("The backtracking path is: "); foundPath = true; //We know for sure that we've found the end because the end node was in the top of the check list } } else //We're all out of nodes to check and there isn't an end anywhere { throw new Exception("End not reachable"); } } //Now that the path is found, backtrack and build the path Node backTrackCurrent = currentNode; Console.WriteLine(backTrackCurrent.getSimpleString()); while (backTrackCurrent != startingNode) { backTrackCurrent.setPath(true); backTrackCurrent = backTrackCurrent.getParent(); Console.WriteLine(backTrackCurrent.getSimpleString()); } //Print the path if it can be printed if (shouldPrintGrid) { printPath(); } }