Example #1
0
        private static List<Node> getAdjacentNodes(Tile startingTile, Map map, List<Node> closedList, Node destinationNode)
        {
            List<Node> adjacentNodes = new List<Node>();
            List<Tile> tilesToCheck = new List<Tile>();
            Node startingNode = new Node(startingTile);

            int startingX = startingTile.xPos;
            int startingY = startingTile.yPos;

            if (map.coordinatesOnMap(startingX, startingY + 1))
                tilesToCheck.Add(map.tiles[startingX, startingY + 1]);

            if (map.coordinatesOnMap(startingX, startingY - 1))
                tilesToCheck.Add(map.tiles[startingX, startingY - 1]);

            if (map.coordinatesOnMap(startingX + 1, startingY))
                tilesToCheck.Add(map.tiles[startingX + 1, startingY]);

            if (map.coordinatesOnMap(startingX - 1, startingY))
                tilesToCheck.Add(map.tiles[startingX - 1, startingY]);

            foreach (Tile tile in tilesToCheck)
            {
                //make sure the tile isnt occupied and isnt in the checked list.
                if (!tile.isOccupied && !(closedList.FindIndex(node => node.nodeTile == tile) >= 0))
                {
                    Node newNode = new Node(tile);
                    newNode.FValue = calculateFValue(newNode, destinationNode);
                    newNode.parentNode = startingNode;
                    adjacentNodes.Add(newNode);
                }
            }

            return adjacentNodes;
        }
Example #2
0
        //calculate the heuristic value, currently using "Manhattan" method - distance formula, deltaX + deltaY
        private static int calculateHeuristic(Node currentNode, Node destinationNode)
        {
            int horizDist = Math.Abs(destinationNode.nodeTile.xPos - currentNode.nodeTile.xPos);
            int vertDist = Math.Abs(destinationNode.nodeTile.yPos - currentNode.nodeTile.yPos);

            return horizDist + vertDist;
        }
Example #3
0
        public static List<Tile> shortestPath(Map map, Tile startingTile, Tile destinationTile)
        {
            List<Tile> path = new List<Tile>();
            List<Node> openNodes = new List<Node>();
            List<Node> closedNodes = new List<Node>();
            List<Node> adjacentNodes = new List<Node>();
            bool reachedDestination = false;

            //initialize. Set starting tile to be the first open node.

            Node startingNode = new Node(startingTile);
            Node destinationNode = new Node(destinationTile);
            startingNode.FValue = calculateFValue(startingNode, destinationNode);
            openNodes.Add(startingNode);
            Node nodeToEval = startingNode;

            while (openNodes.Count > 0) // while nodeToEval != destinationNode ?
            {
                //get adjacent nodes and add them to openNodes
                adjacentNodes = getAdjacentNodes(nodeToEval.nodeTile, map, closedNodes, destinationNode);
                openNodes.AddRange(adjacentNodes);
                openNodes.Remove(nodeToEval);
                closedNodes.Add(nodeToEval);
                //remove nodeToEval from open list, add to closed list

                if (nodeToEval.nodeTile.xPos == destinationNode.nodeTile.xPos && nodeToEval.nodeTile.yPos == destinationNode.nodeTile.yPos)
                {
                    reachedDestination = true;
                    break;
                }

                //Now we find the NEXT node to evaluate

                //We search for the lowest F value in the whole open list after adding the ajacent nodes above
                int lowestFValue = openNodes.Min(node => node.FValue);

                //Now get the node with that lowest value - thats our next node to examine.
                Node nextNodeToEval = openNodes.Find(node => node.FValue == lowestFValue);

                nodeToEval = nextNodeToEval;

                }

            if (reachedDestination == true)
            {
                //done! collect the destination and all parent nodes in a list
                path.Add(nodeToEval.nodeTile);
                Node nextParentNode = nodeToEval.parentNode;

                while (nextParentNode != null)
                {
                    path.Add(nextParentNode.nodeTile);
                    //find parent node in the closed list
                    Node currentParentNode = closedNodes.Find(node => node.nodeTile.xPos == nextParentNode.nodeTile.xPos && node.nodeTile.yPos == nextParentNode.nodeTile.yPos);
                    nextParentNode = currentParentNode.parentNode;
                }

            }

                // find adjacent available nodes and add nodeToEval to the closed list afterwards.

                //adjacentNodes = getAdjacentNodes(nodeToEval.nodeTile, map, closedNodes, destinationNode);
                //openNodes.Remove(nodeToEval);
               // openNodes.AddRange(adjacentNodes);

            return path;
        }
Example #4
0
 //Returns the selection number F (F = G + H) to find the most likely step in the shortest path.
 private static int calculateFValue(Node nodeToEval, Node destinationNode)
 {
     return Node.baseCost + calculateHeuristic(nodeToEval, destinationNode);
 }
Example #5
0
        public static List<Tile> shortestPath(Map map, Tile startingTile, Tile destinationTile)
        {
            List<Tile> path = new List<Tile>();
            List<Node> openNodes = new List<Node>();
            List<Node> closedNodes = new List<Node>();
            List<Node> adjacentNodes = new List<Node>();
            bool reachedDestination = false;

            //initialize. Set starting tile to be the first open node.

            Node startingNode = new Node(startingTile);
            Node destinationNode = new Node(destinationTile);
            startingNode.FValue = calculateFValue(startingNode, destinationNode);
            openNodes.Add(startingNode);
            Node nodeToEval = startingNode;

            while (openNodes.Count > 0) // while nodeToEval != destinationNode ?
            {
                //get adjacent nodes and add them to openNodes
                adjacentNodes = getAdjacentNodes(nodeToEval.nodeTile, map, closedNodes, destinationNode);
                openNodes.AddRange(adjacentNodes);
                openNodes.Remove(nodeToEval);
                closedNodes.Add(nodeToEval);
                //remove nodeToEval from open list, add to closed list

                if (nodeToEval.nodeTile.xPos == destinationNode.nodeTile.xPos && nodeToEval.nodeTile.yPos == destinationNode.nodeTile.yPos)
                {
                    reachedDestination = true;
                    break;
                }

                //Now we find the NEXT node to evaluate

                //We search for the lowest F value in the whole open list after adding the ajacent nodes above
                int lowestFValue = openNodes.Min(node => node.FValue);

                //Now get the node with that lowest value - thats our next node to examine.
                Node nextNodeToEval = openNodes.Find(node => node.FValue == lowestFValue);

                //this method will give us boring L-shaped paths if two adjacent nodes have the same F value.
                //lets try forcing the game to prioritize the one that indicates a change in direction!

                if((openNodes.FindAll(node => node.FValue == lowestFValue).Count > 1))
                {
                    List<Node> potentialNextNodesToEval = openNodes.FindAll(node => node.FValue == lowestFValue);

                    foreach(Node node in potentialNextNodesToEval)
                    {
                        if (nodeToEval.parentNode != null){
                            if (nodeToEval.parentNode.nodeTile.xPos == nodeToEval.nodeTile.xPos && nodeToEval.nodeTile.xPos != node.nodeTile.xPos)
                            {
                                //change of direction in x, prioritize this node and exit
                                nextNodeToEval = node;
                                break;
                            }
                            else if (nodeToEval.parentNode.nodeTile.yPos == nodeToEval.nodeTile.yPos && nodeToEval.nodeTile.yPos != node.nodeTile.yPos)
                            {
                                //change of direction in y, prioritize this node and exit
                                nextNodeToEval = node;
                                break;
                            }
                        }
                    }
                }

                nodeToEval = nextNodeToEval;

                }

            if (reachedDestination == true)
            {
                //done! collect the destination and all parent nodes in a list
                path.Add(nodeToEval.nodeTile);
                Node nextParentNode = nodeToEval.parentNode;

                while (nextParentNode != null)
                {
                    path.Add(nextParentNode.nodeTile);
                    //find parent node in the closed list
                    Node currentParentNode = closedNodes.Find(node => node.nodeTile.xPos == nextParentNode.nodeTile.xPos && node.nodeTile.yPos == nextParentNode.nodeTile.yPos);
                    nextParentNode = currentParentNode.parentNode;
                }

            }

                // find adjacent available nodes and add nodeToEval to the closed list afterwards.

                //adjacentNodes = getAdjacentNodes(nodeToEval.nodeTile, map, closedNodes, destinationNode);
                //openNodes.Remove(nodeToEval);
               // openNodes.AddRange(adjacentNodes);

            return path;
        }