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; }
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; }