Nullkiller.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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 "../Goals/Invalid.h"
  19. extern boost::thread_specific_ptr<CCallback> cb;
  20. extern boost::thread_specific_ptr<VCAI> ai;
  21. Nullkiller::Nullkiller()
  22. {
  23. priorityEvaluator.reset(new PriorityEvaluator());
  24. dangerHitMap.reset(new DangerHitMapAnalyzer());
  25. }
  26. Goals::TSubgoal Nullkiller::choseBestTask(Goals::TGoalVec & tasks) const
  27. {
  28. Goals::TSubgoal bestTask = *vstd::maxElementByFun(tasks, [](Goals::TSubgoal goal) -> float{
  29. return goal->priority;
  30. });
  31. return bestTask;
  32. }
  33. Goals::TSubgoal Nullkiller::choseBestTask(std::shared_ptr<Behavior> behavior) const
  34. {
  35. logAi->debug("Checking behavior %s", behavior->toString());
  36. auto tasks = behavior->getTasks();
  37. if(tasks.empty())
  38. {
  39. logAi->debug("Behavior %s found no tasks", behavior->toString());
  40. return Goals::sptr(Goals::Invalid());
  41. }
  42. logAi->trace("Evaluating priorities, tasks count %d", tasks.size());
  43. for(auto task : tasks)
  44. {
  45. task->setpriority(priorityEvaluator->evaluate(task));
  46. }
  47. auto task = choseBestTask(tasks);
  48. logAi->debug("Behavior %s returns %s(%s), priority %f", behavior->toString(), task->name(), task->tile.toString(), task->priority);
  49. return task;
  50. }
  51. void Nullkiller::resetAiState()
  52. {
  53. lockedHeroes.clear();
  54. dangerHitMap->updateHitMap();
  55. }
  56. void Nullkiller::updateAiState()
  57. {
  58. ai->validateVisitableObjs();
  59. // TODO: move to hero manager
  60. auto activeHeroes = ai->getMyHeroes();
  61. vstd::erase_if(activeHeroes, [&](const HeroPtr & hero) -> bool{
  62. return vstd::contains(lockedHeroes, hero);
  63. });
  64. ai->ah->updatePaths(activeHeroes, true);
  65. ai->ah->updateHeroRoles();
  66. }
  67. void Nullkiller::makeTurn()
  68. {
  69. resetAiState();
  70. while(true)
  71. {
  72. updateAiState();
  73. Goals::TGoalVec bestTasks = {
  74. choseBestTask(std::make_shared<BuyArmyBehavior>()),
  75. choseBestTask(std::make_shared<CaptureObjectsBehavior>()),
  76. choseBestTask(std::make_shared<RecruitHeroBehavior>())
  77. };
  78. if(cb->getDate(Date::DAY) == 1)
  79. {
  80. bestTasks.push_back(choseBestTask(std::make_shared<StartupBehavior>()));
  81. }
  82. Goals::TSubgoal bestTask = choseBestTask(bestTasks);
  83. if(bestTask->invalid())
  84. {
  85. logAi->trace("No goals found. Ending turn.");
  86. return;
  87. }
  88. logAi->debug("Trying to realize %s (value %2.3f)", bestTask->name(), bestTask->priority);
  89. try
  90. {
  91. activeHero = bestTask->hero;
  92. bestTask->accept(ai.get());
  93. }
  94. catch(goalFulfilledException &)
  95. {
  96. logAi->trace(bestTask->completeMessage());
  97. }
  98. catch(std::exception & e)
  99. {
  100. logAi->debug("Failed to realize subgoal of type %s, I will stop.", bestTask->name());
  101. logAi->debug("The error message was: %s", e.what());
  102. return;
  103. }
  104. }
  105. }