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