Nullkiller.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. * Nullkiller.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "Nullkiller.h"
  12. #include "../VCAI.h"
  13. #include "../AIhelper.h"
  14. #include "../Behaviors/CaptureObjectsBehavior.h"
  15. #include "../Behaviors/RecruitHeroBehavior.h"
  16. #include "../Behaviors/BuyArmyBehavior.h"
  17. #include "../Behaviors/StartupBehavior.h"
  18. #include "../Behaviors/DefenceBehavior.h"
  19. #include "../Goals/Invalid.h"
  20. extern boost::thread_specific_ptr<CCallback> cb;
  21. extern boost::thread_specific_ptr<VCAI> ai;
  22. Nullkiller::Nullkiller()
  23. {
  24. priorityEvaluator.reset(new PriorityEvaluator());
  25. dangerHitMap.reset(new DangerHitMapAnalyzer());
  26. }
  27. Goals::TSubgoal Nullkiller::choseBestTask(Goals::TGoalVec & tasks) const
  28. {
  29. Goals::TSubgoal bestTask = *vstd::maxElementByFun(tasks, [](Goals::TSubgoal goal) -> float{
  30. return goal->priority;
  31. });
  32. return bestTask;
  33. }
  34. Goals::TSubgoal Nullkiller::choseBestTask(std::shared_ptr<Behavior> behavior) const
  35. {
  36. logAi->debug("Checking behavior %s", behavior->toString());
  37. auto tasks = behavior->getTasks();
  38. if(tasks.empty())
  39. {
  40. logAi->debug("Behavior %s found no tasks", behavior->toString());
  41. return Goals::sptr(Goals::Invalid());
  42. }
  43. logAi->trace("Evaluating priorities, tasks count %d", tasks.size());
  44. for(auto task : tasks)
  45. {
  46. task->setpriority(priorityEvaluator->evaluate(task));
  47. }
  48. auto task = choseBestTask(tasks);
  49. logAi->debug("Behavior %s returns %s(%s), priority %f", behavior->toString(), task->name(), task->tile.toString(), task->priority);
  50. return task;
  51. }
  52. void Nullkiller::resetAiState()
  53. {
  54. lockedHeroes.clear();
  55. dangerHitMap->updateHitMap();
  56. }
  57. void Nullkiller::updateAiState()
  58. {
  59. ai->validateVisitableObjs();
  60. // TODO: move to hero manager
  61. auto activeHeroes = ai->getMyHeroes();
  62. vstd::erase_if(activeHeroes, [this](const HeroPtr & hero) -> bool{
  63. return isHeroLocked(hero.h);
  64. });
  65. ai->ah->updatePaths(activeHeroes, true);
  66. ai->ah->updateHeroRoles();
  67. }
  68. void Nullkiller::makeTurn()
  69. {
  70. resetAiState();
  71. while(true)
  72. {
  73. updateAiState();
  74. Goals::TGoalVec bestTasks = {
  75. choseBestTask(std::make_shared<BuyArmyBehavior>()),
  76. choseBestTask(std::make_shared<CaptureObjectsBehavior>()),
  77. choseBestTask(std::make_shared<RecruitHeroBehavior>())
  78. };
  79. if(cb->getDate(Date::DAY) == 1)
  80. {
  81. bestTasks.push_back(choseBestTask(std::make_shared<StartupBehavior>()));
  82. }
  83. else
  84. {
  85. bestTasks.push_back(choseBestTask(std::make_shared<DefenceBehavior>()));
  86. }
  87. Goals::TSubgoal bestTask = choseBestTask(bestTasks);
  88. if(bestTask->invalid())
  89. {
  90. logAi->trace("No goals found. Ending turn.");
  91. return;
  92. }
  93. logAi->debug("Trying to realize %s (value %2.3f)", bestTask->name(), bestTask->priority);
  94. try
  95. {
  96. activeHero = bestTask->hero.get();
  97. bestTask->accept(ai.get());
  98. }
  99. catch(goalFulfilledException &)
  100. {
  101. logAi->trace(bestTask->completeMessage());
  102. }
  103. catch(std::exception & e)
  104. {
  105. logAi->debug("Failed to realize subgoal of type %s, I will stop.", bestTask->name());
  106. logAi->debug("The error message was: %s", e.what());
  107. return;
  108. }
  109. }
  110. }