Vector2d findBestPositionToAttack(const model::World& w, const model::Trooper& trooper, const model::Trooper& enemy){ Vector2d res(-1,-1); PathFinder pf; int bestDist = 1 << 20; const std::vector<std::vector<model::CellType> >& cells = w.getCells(); for (int i = 0; i < w.getWidth(); i++){ for (int j = 0; j < w.getHeight(); j++){ // if (enemy.getDistanceTo(i,j) > 8 || cells[i][j] != model::FREE || PathFinder::isTropperInCell(w,Vector2d(i,j))) //dist to check. Too much??? if (trooper.getDistanceTo(i,j) > 5 || cells[i][j] != model::FREE || PathFinder::isTropperInCell(w,Vector2d(i,j))) //dist to check. Too much??? continue; if (!w.isVisible(trooper.getShootingRange(), i, j, model::STANDING, enemy.getX(), enemy.getY(), enemy.getStance())) continue; std::list<Vector2d> path = pf.calcOptimalPath(w, Vector2d(trooper.getX(), trooper.getY()), Vector2d(i, j)); if(path.empty()) continue; std::list<Vector2d> pathWithoutPlayers = pf.calcOptimalPath(w, Vector2d(trooper.getX(), trooper.getY()), Vector2d(i, j), true); if (pathWithoutPlayers.size() + 3 < path.size()) continue; int dist = path.size(); if (dist < bestDist){ bestDist = dist; res = Vector2d(i,j); } } } return res; }
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; }
void EntityLinkRenderer::getAllLinks(Vertex::List& links) const { View::MapDocumentSPtr document = lock(m_document); const Model::EditorContext& editorContext = document->editorContext(); CollectAllLinksVisitor collectLinks(editorContext, m_defaultColor, m_selectedColor, links); Model::World* world = document->world(); if (world != NULL) world->acceptAndRecurse(collectLinks); }
Vector2d processApproximate(const model::World& w, const Vector2d& appr){ Vector2d res; const std::vector<std::vector<model::CellType> >& cells = w.getCells(); float min = 1 << 20; for (int i = 0; i < w.getWidth(); i++) for (int j = 0; j < w.getHeight(); j++){ float d = dist(appr, Vector2d(i, j)); if (cells[i][j] == model::FREE && min > d){ min = d; res = Vector2d (i, j); } } 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(); }
std::vector<Vector2d> getDstsWithDir(const model::World& w, const Vector2d susanin_v, const Vector2d dir){ std::vector<Vector2d> res; const std::vector<std::vector<model::CellType> >& cells = w.getCells(); for (int i = 0; i < w.getWidth(); i++) for (int j = 0; j < w.getHeight(); j++){ float d = dist(susanin_v, Vector2d(i, j)); if (d > kMinDist && d < kMaxDist && cells[i][j] == model::FREE && !PathFinder::isTropperInCell(w, Vector2d(i, j)) && isFeetDirection(susanin_v, i, j, dir)) res.push_back(Vector2d(i, j)); } return res; }
bool isTypeAlive(const model::World& w, model::TrooperType type){ bool res = false; const std::vector<model::Trooper> t = w.getTroopers(); std::vector<model::Trooper>::const_iterator it = t.begin(); for (; it != t.end(); ++it){ if (!(it->isTeammate())) continue; if (it->getType() == type && it->getHitpoints() > 0){ res = true; break; } } return res; }
Action DriveStrategy::makeDecision(ITank &tank, model::World world) { Action action; action.setLeft(0); action.setRight(0); std::vector<model::Bonus> bonuses = world.bonuses(); if (bonuses.empty()) return action; model::Bonus best = bonuses[0]; for (int i = 1; i < (int)bonuses.size(); i++) { model::Bonus cur = bonuses[i]; if (tank.distanceTo(cur) < tank.distanceTo(best)) best = cur; } //std::cerr << "Move to " << best.x() << " " << best.y() << std::endl; moveTo(tank, best.x(), best.y(), action); return action; }
std::list<ActionChain*> ActionFactory::createChains(const model::World& w, const model::Trooper& trooper, std::list<Tactician::Tactic> tactics, bool isFirstMove){ std::list<ActionChain*> res_chains; ActionChain* new_chain = NULL; const std::vector<model::Trooper>& troopers = w.getTroopers(); ActionChain* heal_chain = ActionFactory::heal(w, trooper, tactics, isFirstMove); if (heal_chain){ ActionChunk first = *((heal_chain->chain).begin()); model::ActionType firstType = first.action_type; if (isActionAvailable(trooper, firstType)) res_chains.push_back(heal_chain); else delete heal_chain; } ActionChain* atack_chain = ActionFactory::atack(w, trooper, tactics, isFirstMove); if (atack_chain){//TODO: avoid copy-paste ActionChunk first = *((atack_chain->chain).begin()); model::ActionType firstType = first.action_type; if (isActionAvailable(trooper, firstType)) res_chains.push_back(atack_chain); else delete atack_chain; } if (gMainDst == Vector2d(-1, -1)){ if (model::COMMANDER == trooper.getType()){ const std::vector<model::Player>players = w.getPlayers(); if (players[0].getApproximateX() != -1 || players[1].getApproximateX() != -1 || players[2].getApproximateX() != -1 || players[3].getApproximateX() != -1){ //already we have this info std::vector<model::Player>::const_iterator it = players.begin(); float min = 1 << 20; Vector2d approximate(-1, -1); for (; it != players.end(); ++it){ if (it->getName() == "m16a" || it->getName() == "MyStrategy"|| it->getApproximateX() == -1) continue; Vector2d tmp(it->getApproximateX(), it->getApproximateY()); float d = dist(tmp, Vector2d(trooper.getX(), trooper.getY())); if (min > d){ min = d; approximate = tmp; } } gMainDst = processApproximate(w, approximate); } else if (isActionAvailable(trooper, model::REQUEST_ENEMY_DISPOSITION)){ std::list<ActionChunk> c; ActionChunk chunk(model::REQUEST_ENEMY_DISPOSITION, Vector2d(-1, -1)); c.push_back(chunk); ActionChain *new_chain = new ActionChain(); new_chain->executor = &trooper; new_chain->chain = c; res_chains.push_back(new_chain); } } } if (tactics.end() != std::find(tactics.begin(), tactics.end(), Tactician::MOVE) && isActionAvailable(trooper, model::MOVE)) { do{ if (trooper.getStance() != model::STANDING){ std::list<ActionChunk> c; ActionChunk chunk(model::RAISE_STANCE, Vector2d(-1, -1)); c.push_back(chunk); new_chain = new ActionChain(); new_chain->executor = &trooper; new_chain->chain = c; if (isActionAvailable(trooper, model::RAISE_STANCE)) res_chains.push_back(new_chain); break; } model::TrooperType Susanin_type = model::UNKNOWN_TROOPER; if (gMove_head.empty()){ gMove_head.push_back(model::SOLDIER); gMove_head.push_back(model::COMMANDER); gMove_head.push_back(model::FIELD_MEDIC); } const model::Trooper *susanin = NULL; while(susanin == NULL){ std::list<model::TrooperType>::iterator type_it = gMove_head.begin(); for (; type_it != gMove_head.end() && susanin == NULL; ++type_it){ std::vector<model::Trooper>::const_iterator tr_it = troopers.begin(); for (; tr_it != troopers.end(); ++tr_it){ if (tr_it->isTeammate() && tr_it->getType() == *type_it){ susanin = &(*tr_it); break; } } } if (susanin == NULL){ gMove_head.push_back(*(gMove_head.begin())); gMove_head.erase(gMove_head.begin()); } } Vector2d dst = Vector2d(susanin->getX(), susanin->getY()); Vector2d src(trooper.getX(), trooper.getY()); if (isFirstMove){ if (trooper.getDistanceTo(*susanin) == 0) gMediatorDst = findDest(w, dst); else gMediatorDst = findNearestFree(w, src, dst); } dst = gMediatorDst; PathFinder pf; std::list<Vector2d> path = pf.calcOptimalPath(w, src, dst); if (!path.empty()){ path.pop_front(); std::list<Vector2d>::iterator it = path.begin(); std::list<ActionChunk> c; for (; it != path.end(); ++it){ if (!PathFinder::isTropperInCell(w, *it)){//TODO: eliminate ActionChunk chunk(model::MOVE, *it); c.push_back(chunk); } } new_chain = new ActionChain(); new_chain->executor = &trooper; new_chain->chain = c; if (isActionAvailable(trooper, model::MOVE)) res_chains.push_back(new_chain); } else if (susanin->getDistanceTo(trooper) == 0){//try to change susanin gMove_head.push_back(*(gMove_head.begin())); gMove_head.erase(gMove_head.begin()); } }while(0); } return res_chains; }