static void Main(string[] args) { int[,] map = { { 0, -1, 0, 0, 0, 0 }, { 0, -1, 0, -1, 0, 0 }, { 0, -1, 0, -1, 0, 0 }, { 0, -1, 0, -1, 0, 0 }, { 0, 0, 0, -1, 0, 0 }, { 0, 0, 0, -1, 0, 0 } }; AstarHelper astar = new AstarHelper(map, 0.1f); var route = astar.Search(1, 1, 4, 4); if (route != null) { while (route.Count() > 0) { int[] pos = route.Dequeue(); Console.WriteLine("{0}, {1}", pos[0], pos[1]); } } }
private static void AddNeighbor(Dictionary<TileStatus, AstarHelper> OpenNodes, TileStatus lowest, TileStatus direction, TileStatus goal) { if(OpenNodes.ContainsKey(direction)) { AstarHelper helper = OpenNodes[direction]; helper.actual = OpenNodes[lowest].actual + GlobalConstants.A_STAR_MOVE_COST; helper.prev = lowest; OpenNodes[direction] = helper; } else { AstarHelper helper = new AstarHelper(); helper.actual = OpenNodes[lowest].actual + GlobalConstants.A_STAR_MOVE_COST; helper.heuristic = ManhattanDistance(direction.Position, goal.Position); helper.prev = lowest; OpenNodes[direction] = helper; } }
/// <summary> /// Gets the path between two tile coordinates /// </summary> /// <returns> /// The path in tiles /// </returns> /// <param name='start'> /// Starting tile coordinate /// </param> /// <param name='end'> /// Ending tile coordinate /// </param> /// <param name='type'> /// Type of ground to consider for pathing /// </param> public static List<TileStatus> GetPath(Vector2 start, Vector2 end, TileStatus.GroundType type) { List<TileStatus> retn = new List<TileStatus>(); TileStatus endNode = GetTileAt(end.x, end.y); TileStatus startNode = GetTileAt(start.x, start.y); Dictionary<TileStatus, AstarHelper> OpenNodes = new Dictionary<TileStatus, AstarHelper>(); Dictionary<TileStatus, AstarHelper> ClosedNodes = new Dictionary<TileStatus, AstarHelper>(); OpenNodes[startNode] = new AstarHelper(); while(OpenNodes.Count > 0 && !OpenNodes.ContainsKey(endNode)) { //Get the lowest cost Open Node int min = int.MaxValue; TileStatus lowest = null; foreach(TileStatus status in OpenNodes.Keys) { if(OpenNodes[status].combined < min) { min = OpenNodes[status].combined; lowest = status; } } //Compute the costs of the neighbors TileStatus up = GetTileAt(lowest.Position.x, lowest.Position.y + 1); TileStatus down = GetTileAt(lowest.Position.x, lowest.Position.y - 1); TileStatus left = GetTileAt(lowest.Position.x - 1, lowest.Position.y); TileStatus right = GetTileAt(lowest.Position.x + 1, lowest.Position.y); #region Up if(up != null && (up.groundType & type) != 0 && !ClosedNodes.ContainsKey(up)) { AddNeighbor(OpenNodes, lowest, up, endNode); } #endregion #region down if(down != null && (down.groundType & type) != 0 && !ClosedNodes.ContainsKey(down)) { AddNeighbor(OpenNodes, lowest, down, endNode); } #endregion #region left if(left != null && (left.groundType & type) != 0 && !ClosedNodes.ContainsKey(left)) { AddNeighbor(OpenNodes, lowest, left, endNode); } #endregion #region right if(right != null && (right.groundType & type) != 0 && !ClosedNodes.ContainsKey(right)) { AddNeighbor(OpenNodes, lowest, right, endNode); } #endregion ClosedNodes[lowest] = OpenNodes[lowest]; OpenNodes.Remove(lowest); } if(!OpenNodes.ContainsKey(endNode)) return null; retn.Add(endNode); TileStatus nextNode = OpenNodes[endNode].prev; while(!retn.Contains(startNode)) { retn.Insert(0, nextNode); nextNode = ClosedNodes[nextNode].prev; } //TODO: Complete this method return retn; }