vector<Cell> GetClosestPath(const model::World& world, Cell const & start, Direction const start_dir, Cell const & finish, Game const & game) { static map<cashe_key, vector<Cell> > cacshe; static int bonus_hash = 0; int bonus_hash_cur = 0; auto const & map = world.getTilesXY(); vector<vector<int>> bonuses(map.size(), vector<int>(map[0].size(), 0)); for (Bonus const & bonus: world.getBonuses()) { bonus_hash_cur += bonus.getX() * bonus.getX() + bonus.getY() * bonus.getY(); auto bonus_cell= GetCell(bonus, game); bonuses[bonus_cell.m_x][bonus_cell.m_y] = (bonus.getType() == PURE_SCORE || bonus.getType() == REPAIR_KIT) ? 1 : 0; } if (bonus_hash != bonus_hash_cur) { bonus_hash = bonus_hash_cur; cacshe.clear(); } cashe_key ck = {start, start_dir, finish}; if (cacshe.count(ck) == 1) return cacshe[ck]; MapT data; DSF(world.getTilesXY(), {start, start_dir}, {start, start_dir}, finish, data, bonuses); // PrintMap(world.getTilesXY(), data); vector<Cell> res; int const INF = 1000000; int best = INF; MapKeyT cur = {finish, LEFT}; for (auto dir: AllDirections()) { if (data.count({finish,dir}) == 0) continue; if (data[{finish,dir}].first < best) { best = data[{finish,dir}].first; cur = {finish,dir}; } } if (best == INF) return res; while (cur.first != start) { res.push_back(cur.first); cur = data[cur].second; } res.push_back(start); reverse(res.begin(), res.end()); cacshe[ck] = res; return res; }
Map::Map(const model::Game& game, const model::World& world) : m_tiles(world.getTilesXY()) , m_game(&game) , m_world(&world) , m_tileSize((int)m_game->getTrackTileSize()) , m_tileCenter((int)m_game->getTrackTileSize() / 2, (int)m_game->getTrackTileSize() / 2) , m_worldWidthTiles(world.getWidth()) , m_worldHeightTiles(world.getHeight()) { m_tileNodes.resize(m_worldWidthTiles * m_worldHeightTiles); updateNodes(); }