TileVector PathFinder::FindPath() const { TileSet closed = {}; TileSet open = { &m_source }; CostMap g_score; // Cost from start to this node. CostMap f_score; // Cost to get to this node + estimated cost to dest. CameFromMap cameFrom; g_score[&m_source] = 0; f_score[&m_source] = _Heuristic(m_source, m_dest); while (!open.empty()) { // Take the element in the open set with least total estimated cost. Tile* curr = *std::min_element(open.begin(), open.end(), [&f_score](Tile* a, Tile* b) { return (f_score[a] < f_score[b]); }); if (curr == &m_dest) { // We've found the best path. return _Reconstruct(cameFrom, m_dest); } open.erase(curr); closed.insert(curr); for (Tile* neighbour : _Neighbours(m_map, *curr)) { if (closed.find(neighbour) != closed.end()) continue; int tentative_g_score = g_score[curr] + neighbour->MoveCost(); // If neighbour isn't in the open set, or we have found a better path to neighbour, update it. if ((open.find(neighbour) == open.end()) || (tentative_g_score < g_score[neighbour])) { // This could be done without recalculating the heuristic, if desired. cameFrom[neighbour] = curr; g_score[neighbour] = tentative_g_score; f_score[neighbour] = tentative_g_score + _Heuristic(*neighbour, m_dest); open.insert(neighbour); } } } // Failure printf("No path\n"); return{}; }
void Map::ForEachReachableTile( const Unit* unit, ForEachReachableTileCallback callback ) { assertion( unit, "Cannot find reachable tiles for null Unit!" ); assertion( callback.IsValid(), "Cannot call invalid callback on reachable tiles!" ); // Find all reachable tiles for the Unit. TileSet reachableTiles; FindReachableTiles( unit, reachableTiles ); for( auto it = reachableTiles.begin(); it != reachableTiles.end(); ++it ) { // Invoke the callback on all reachable tiles. callback.Invoke( *it, unit ); } }