/// <summary> /// call this to plan a path between points /// </summary> /// <param name="begin"></param> /// <param name="end"></param> /// <returns></returns> public Route FindRoute(Location begin, Location end) { HashSet<MapTile> tilesToReset = new HashSet<MapTile>();//all tiles that need to be reset MapTile mapEnd = Map[end.Row, end.Col]; MapTile mapBegin = Map[begin.Row, begin.Col]; tilesToReset.Add(mapBegin); mapBegin.CostKnown = 0; mapBegin.Heuristic = Globals.state.GetDistance(begin, end); mapBegin.CostEstimate = mapBegin.CostKnown + mapBegin.Heuristic; MinHeap<MapTile> OpenSet = new MinHeap<MapTile>(); OpenSet.Add(mapBegin); while (!OpenSet.IsEmpty) { MapTile current = OpenSet.ExtractMin(); if (current == mapEnd) return BuildRoute(mapEnd, tilesToReset);//reset after the oath is build, we need those pi pointers foreach (Direction d in (Direction[])Enum.GetValues(typeof(Direction))) { Location tile = Globals.state.GetDestination(current.GetLocation, d); MapTile neighbour = Map[tile.Row, tile.Col]; bool succesful = Relax(current, neighbour, mapEnd); tilesToReset.Add(neighbour);//hashset will not contain duplicates if (!neighbour.InOpenSet && succesful) { OpenSet.Add(neighbour); neighbour.InOpenSet = true;//openset is a min heap, no O(1) lookup so store this in the tile } else { if (neighbour.InOpenSet && succesful) { OpenSet.ChangeKey(neighbour, neighbour.CostEstimate); } } } } foreach (MapTile t in tilesToReset)//no route found, still need to reset t.Reset(); return null; }