예제 #1
0
        private List <AStarNode> GetAdjacentWalkableNodes(AStarNode fromNode)
        {
            List <AStarNode>    walkableNodes = new List <AStarNode>();
            IEnumerable <Point> nextLocations = IsWalkableFrom(fromNode);

            foreach (var location in nextLocations)
            {
                int x = location.X;
                int y = location.Y;

                // Stay within the grid's boundaries
                if (x < 0 || x >= this.width || y < 0 || y >= this.height)
                {
                    continue;
                }

                AStarNode node = this.nodes[x, y];

                //float traversalCost = GetTraversal(fromNode.Location, location, Finish.Location);   //1;
                float traversalCost = GetTraversal(fromNode, node, Finish);

                //node.ParentNode = fromNode;


                if (node.Location == this.Finish.Location)
                {
                    float gTemp = fromNode.G + traversalCost;
                    if (gTemp < node.G)
                    {
                        node.ParentNode = fromNode;
                        node.G          = fromNode.G + traversalCost;
                        node.F          = node.G + node.H;
                        walkableNodes.Add(node);
                        continue;
                    }
                }

                // Ignore non-walkable nodes
                if (!node.IsWalkable)
                {
                    continue;
                }

                // Ignore already-closed nodes
                if (node.State == AStarNodeState.Closed)
                {
                    continue;
                }

                /*
                 * {
                 *  float gTemp = fromNode.G + traversalCost;
                 *  if (gTemp < node.G)
                 *  {
                 *      node.ParentNode = fromNode;
                 *      walkableNodes.Add(node);
                 *  }
                 * }
                 */

                // Already-open nodes are only added to the list if their G-value is lower going via this route.
                if (node.State == AStarNodeState.Open)// || node.State == AStarNodeState.Closed)
                {
                    float gTemp = fromNode.G + traversalCost;
                    if (gTemp < node.G)
                    {
                        node.ParentNode = fromNode;
                        node.G          = fromNode.G + traversalCost;
                        node.F          = node.G + node.H;
                        walkableNodes.Add(node);
                    }
                }
                else
                {
                    // If it's untested, set the parent and flag it as 'Open' for consideration
                    node.ParentNode = fromNode;
                    node.G          = fromNode.G + traversalCost;
                    node.F          = node.G + node.H;
                    node.State      = AStarNodeState.Open;
                    walkableNodes.Add(node);
                }
            }

            return(walkableNodes);
        }
예제 #2
0
        float GetTraversal(AStarNode from, AStarNode to, AStarNode destination)
        {
            // Prefer reading order, meaning U, L, R, D (N, W, E, S)
            // This should also work for eight-direction or diagonals, though current intent is four cardinal directions.
            float _ret = to.Cost;

            /*
             * float diffX = to.Location.X - from.Location.X;
             * float diffY = to.Location.Y - from.Location.Y;
             *
             * if (diffX < 0 && diffY < 0) // up and left
             *  _ret -= 3f;
             *
             * else if (diffX == 0 && diffY < 0) // up
             *  _ret -= 2f;
             *
             * else if (diffX > 0 && diffY < 0) // up and right
             *  _ret += 1f;
             *
             * else if (diffX < 0 && diffY == 0) // left
             *  _ret += 0f;
             *
             * else if (diffX > 0 && diffY == 0) // right
             *  _ret += 1f;
             *
             * else if (diffX < 0 && diffY > 0) // down and left
             *  _ret += 2f;
             *
             * else if (diffX == 0 && diffY > 0) // down
             *  _ret += 3f;
             *
             * else if (diffX > 0 && diffY > 0) // down and right
             *  _ret += 4f;
             */
            /*
             * if (to.Location.Y < from.Location.Y)  // Up / North
             * {
             *  //_ret += 1.0f;
             *  _ret -= 0.5f;
             *  //_ret *= 1.0f;                       // No change in cost if up
             * }
             *
             * else if (to.Location.Y == from.Location.Y)  // Down / South
             * {
             *  //_ret += 4.0f;
             *  _ret += 0f;
             *  //_ret *= 1.003f;                       // Even hight increase in cost if down
             * }
             *
             * else if (to.Location.Y > from.Location.Y)  // Down / South
             * {
             *  //_ret += 4.0f;
             *  _ret += 0.5f;
             *  //_ret *= 1.003f;                       // Even hight increase in cost if down
             * }
             *
             * if (to.Location.X < from.Location.X)  // Left / West
             * {
             *  //_ret += 2.0f;
             *  _ret -= 0.5f;
             *  //_ret *= 1.001f;                       // Slight increase in cost if left
             * }
             *
             * else if (to.Location.X == from.Location.X)  // Down / South
             * {
             *  //_ret += 4.0f;
             *  _ret += 0f;
             *  //_ret *= 1.003f;                       // Even hight increase in cost if down
             * }
             *
             * else if (to.Location.X > from.Location.X)  // Right / East
             * {
             *  //_ret += 3.0f;
             *  _ret += 0.5f;
             *  //_ret *= 1.002f;                       // Slightly higher increase in cost if right
             * }
             */


            return(_ret);
        }