123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- /*
- * Nullkiller.cpp, part of VCMI engine
- *
- * Authors: listed in file AUTHORS in main folder
- *
- * License: GNU General Public License v2.0 or later
- * Full text of license available in license.txt file, in main folder
- *
- */
- #include "StdInc.h"
- #include "Nullkiller.h"
- #include "../VCAI.h"
- #include "../AIhelper.h"
- #include "../Behaviors/CaptureObjectsBehavior.h"
- #include "../Behaviors/RecruitHeroBehavior.h"
- #include "../Behaviors/BuyArmyBehavior.h"
- #include "../Behaviors/StartupBehavior.h"
- #include "../Behaviors/DefenceBehavior.h"
- #include "../Goals/Invalid.h"
- extern boost::thread_specific_ptr<CCallback> cb;
- extern boost::thread_specific_ptr<VCAI> ai;
- Nullkiller::Nullkiller()
- {
- priorityEvaluator.reset(new PriorityEvaluator());
- dangerHitMap.reset(new DangerHitMapAnalyzer());
- }
- Goals::TSubgoal Nullkiller::choseBestTask(Goals::TGoalVec & tasks) const
- {
- Goals::TSubgoal bestTask = *vstd::maxElementByFun(tasks, [](Goals::TSubgoal goal) -> float{
- return goal->priority;
- });
- return bestTask;
- }
- Goals::TSubgoal Nullkiller::choseBestTask(std::shared_ptr<Behavior> behavior) const
- {
- logAi->debug("Checking behavior %s", behavior->toString());
- auto tasks = behavior->getTasks();
- if(tasks.empty())
- {
- logAi->debug("Behavior %s found no tasks", behavior->toString());
- return Goals::sptr(Goals::Invalid());
- }
- logAi->trace("Evaluating priorities, tasks count %d", tasks.size());
- for(auto task : tasks)
- {
- task->setpriority(priorityEvaluator->evaluate(task));
- }
- auto task = choseBestTask(tasks);
- logAi->debug("Behavior %s returns %s(%s), priority %f", behavior->toString(), task->name(), task->tile.toString(), task->priority);
- return task;
- }
- void Nullkiller::resetAiState()
- {
- lockedHeroes.clear();
- dangerHitMap->updateHitMap();
- }
- void Nullkiller::updateAiState()
- {
- ai->validateVisitableObjs();
- // TODO: move to hero manager
- auto activeHeroes = ai->getMyHeroes();
- vstd::erase_if(activeHeroes, [&](const HeroPtr & hero) -> bool{
- return vstd::contains(lockedHeroes, hero);
- });
- ai->ah->updatePaths(activeHeroes, true);
- ai->ah->updateHeroRoles();
- }
- void Nullkiller::makeTurn()
- {
- resetAiState();
- while(true)
- {
- updateAiState();
- Goals::TGoalVec bestTasks = {
- choseBestTask(std::make_shared<BuyArmyBehavior>()),
- choseBestTask(std::make_shared<CaptureObjectsBehavior>()),
- choseBestTask(std::make_shared<RecruitHeroBehavior>()),
- choseBestTask(std::make_shared<DefenceBehavior>())
- };
- if(cb->getDate(Date::DAY) == 1)
- {
- bestTasks.push_back(choseBestTask(std::make_shared<StartupBehavior>()));
- }
- Goals::TSubgoal bestTask = choseBestTask(bestTasks);
- if(bestTask->invalid())
- {
- logAi->trace("No goals found. Ending turn.");
- return;
- }
- logAi->debug("Trying to realize %s (value %2.3f)", bestTask->name(), bestTask->priority);
- try
- {
- activeHero = bestTask->hero;
- bestTask->accept(ai.get());
- }
- catch(goalFulfilledException &)
- {
- logAi->trace(bestTask->completeMessage());
- }
- catch(std::exception & e)
- {
- logAi->debug("Failed to realize subgoal of type %s, I will stop.", bestTask->name());
- logAi->debug("The error message was: %s", e.what());
- return;
- }
- }
- }
|