From f832a8b3cd5b7c43e91f492d6fd7165cd3fdd053 Mon Sep 17 00:00:00 2001 From: Andrii Danylchenko Date: Sun, 16 May 2021 14:45:48 +0300 Subject: [PATCH] Nullkiller: calibration and small behavior fixes --- AI/Nullkiller/Behaviors/StartupBehavior.cpp | 28 +++++++++++++++---- AI/Nullkiller/Engine/PriorityEvaluator.cpp | 4 +-- AI/Nullkiller/Goals/ExecuteHeroChain.cpp | 2 +- AI/Nullkiller/Pathfinding/AINodeStorage.h | 2 +- .../Pathfinding/AIPathfinderConfig.cpp | 11 ++++---- .../Pathfinding/AIPathfinderConfig.h | 2 +- 6 files changed, 34 insertions(+), 15 deletions(-) diff --git a/AI/Nullkiller/Behaviors/StartupBehavior.cpp b/AI/Nullkiller/Behaviors/StartupBehavior.cpp index 898ebf5dc..25627d235 100644 --- a/AI/Nullkiller/Behaviors/StartupBehavior.cpp +++ b/AI/Nullkiller/Behaviors/StartupBehavior.cpp @@ -92,7 +92,9 @@ bool needToRecruitHero(const CGTownInstance * startupTown) } auto basicCount = cb->getTownsInfo().size() + 2; - auto boost = (int)std::floor(std::pow(treasureSourcesCount / 3.0, 2)); + auto boost = (int)std::floor(std::pow(treasureSourcesCount / 2.0, 2)); + + logAi->trace("Startup allows %d+%d heroes", basicCount, boost); return cb->getHeroCount(ai->playerID, true) < basicCount + boost; } @@ -106,21 +108,24 @@ Goals::TGoalVec StartupBehavior::decompose() const return tasks; const CGTownInstance * startupTown = towns.front(); - bool canRecruitHero = needToRecruitHero(startupTown); if(towns.size() > 1) { startupTown = *vstd::maxElementByFun(towns, [](const CGTownInstance * town) -> float { + if(town->garrisonHero) + return ai->ah->evaluateHero(town->garrisonHero.get()); + auto closestHero = getNearestHero(town); - if(!closestHero) - return 0; + if(closestHero) + return ai->ah->evaluateHero(closestHero); - return ai->ah->evaluateHero(closestHero); + return 0; }); } + bool canRecruitHero = needToRecruitHero(startupTown); auto closestHero = getNearestHero(startupTown); if(closestHero) @@ -174,6 +179,19 @@ Goals::TGoalVec StartupBehavior::decompose() const tasks.push_back(Goals::sptr(Goals::RecruitHero(startupTown))); } + if(tasks.empty() && !startupTown->visitingHero) + { + for(auto town : towns) + { + if(!town->visitingHero && needToRecruitHero(town)) + { + tasks.push_back(Goals::sptr(Goals::RecruitHero(town))); + + break; + } + } + } + if(tasks.empty() && towns.size()) { for(const CGTownInstance * town : towns) diff --git a/AI/Nullkiller/Engine/PriorityEvaluator.cpp b/AI/Nullkiller/Engine/PriorityEvaluator.cpp index 4663775c1..0532d986f 100644 --- a/AI/Nullkiller/Engine/PriorityEvaluator.cpp +++ b/AI/Nullkiller/Engine/PriorityEvaluator.cpp @@ -310,10 +310,10 @@ float getStrategicalValue(const CGObjectInstance * target) switch(target->ID) { case Obj::MINE: - return target->subID == Res::GOLD ? 0.5f : 0.05f * getTotalResourceRequirementStrength(target->subID) + 0.05f * getResourceRequirementStrength(target->subID); + return target->subID == Res::GOLD ? 0.5f : 0.02f * getTotalResourceRequirementStrength(target->subID) + 0.02f * getResourceRequirementStrength(target->subID); case Obj::RESOURCE: - return target->subID == Res::GOLD ? 0 : 0.3f * getResourceRequirementStrength(target->subID); + return target->subID == Res::GOLD ? 0 : 0.1f * getResourceRequirementStrength(target->subID); case Obj::TOWN: return dynamic_cast(target)->hasFort() diff --git a/AI/Nullkiller/Goals/ExecuteHeroChain.cpp b/AI/Nullkiller/Goals/ExecuteHeroChain.cpp index 5ad14e079..14c9afb10 100644 --- a/AI/Nullkiller/Goals/ExecuteHeroChain.cpp +++ b/AI/Nullkiller/Goals/ExecuteHeroChain.cpp @@ -95,7 +95,7 @@ void ExecuteHeroChain::accept(VCAI * ai) } } - if(node.turns == 0 && node.coord != hero->visitablePos()) + if(node.turns == 0 && node.coord != hero->visitablePos()) { auto targetNode = cb->getPathsInfo(hero)->getPathInfo(node.coord); diff --git a/AI/Nullkiller/Pathfinding/AINodeStorage.h b/AI/Nullkiller/Pathfinding/AINodeStorage.h index de33caa7f..9c9266e6f 100644 --- a/AI/Nullkiller/Pathfinding/AINodeStorage.h +++ b/AI/Nullkiller/Pathfinding/AINodeStorage.h @@ -11,7 +11,7 @@ #pragma once #define PATHFINDER_TRACE_LEVEL 0 -#define AI_TRACE_LEVEL 1 +#define AI_TRACE_LEVEL 1 #include "../../../lib/CPathfinder.h" #include "../../../lib/mapObjects/CGHeroInstance.h" diff --git a/AI/Nullkiller/Pathfinding/AIPathfinderConfig.cpp b/AI/Nullkiller/Pathfinding/AIPathfinderConfig.cpp index 7547a2500..c976fd88a 100644 --- a/AI/Nullkiller/Pathfinding/AIPathfinderConfig.cpp +++ b/AI/Nullkiller/Pathfinding/AIPathfinderConfig.cpp @@ -43,13 +43,14 @@ namespace AIPathfinding CPathfinderHelper * AIPathfinderConfig::getOrCreatePathfinderHelper(const PathNodeInfo & source, CGameState * gs) { - if(!pathfindingHelper) - { - auto hero = aiNodeStorage->getHero(source.node); + auto hero = aiNodeStorage->getHero(source.node); + auto & helper = pathfindingHelpers[hero]; - pathfindingHelper.reset(new CPathfinderHelper(gs, hero, options)); + if(!helper) + { + helper.reset(new CPathfinderHelper(gs, hero, options)); } - return pathfindingHelper.get(); + return helper.get(); } } diff --git a/AI/Nullkiller/Pathfinding/AIPathfinderConfig.h b/AI/Nullkiller/Pathfinding/AIPathfinderConfig.h index fb8017780..98e295225 100644 --- a/AI/Nullkiller/Pathfinding/AIPathfinderConfig.h +++ b/AI/Nullkiller/Pathfinding/AIPathfinderConfig.h @@ -18,7 +18,7 @@ namespace AIPathfinding class AIPathfinderConfig : public PathfinderConfig { private: - std::unique_ptr pathfindingHelper; + std::map> pathfindingHelpers; std::shared_ptr aiNodeStorage; public: