mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-26 03:52:01 +02:00
NKAI: object graph fixes
This commit is contained in:
parent
3820f6f78b
commit
adfcb650e2
@ -50,7 +50,6 @@
|
|||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
using namespace tbb;
|
|
||||||
|
|
||||||
using dwellingContent = std::pair<ui32, std::vector<CreatureID>>;
|
using dwellingContent = std::pair<ui32, std::vector<CreatureID>>;
|
||||||
|
|
||||||
@ -246,48 +245,6 @@ uint64_t timeElapsed(std::chrono::time_point<std::chrono::high_resolution_clock>
|
|||||||
// todo: move to obj manager
|
// todo: move to obj manager
|
||||||
bool shouldVisit(const Nullkiller * ai, const CGHeroInstance * h, const CGObjectInstance * obj);
|
bool shouldVisit(const Nullkiller * ai, const CGHeroInstance * h, const CGObjectInstance * obj);
|
||||||
|
|
||||||
template<typename TFunc>
|
|
||||||
void pforeachTilePos(const int3 & mapSize, TFunc fn)
|
|
||||||
{
|
|
||||||
for(int z = 0; z < mapSize.z; ++z)
|
|
||||||
{
|
|
||||||
parallel_for(blocked_range<size_t>(0, mapSize.x), [&](const blocked_range<size_t>& r)
|
|
||||||
{
|
|
||||||
int3 pos(0, 0, z);
|
|
||||||
|
|
||||||
for(pos.x = r.begin(); pos.x != r.end(); ++pos.x)
|
|
||||||
{
|
|
||||||
for(pos.y = 0; pos.y < mapSize.y; ++pos.y)
|
|
||||||
{
|
|
||||||
fn(pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename TFunc>
|
|
||||||
void pforeachTilePaths(const int3 & mapSize, const Nullkiller * ai, TFunc fn)
|
|
||||||
{
|
|
||||||
for(int z = 0; z < mapSize.z; ++z)
|
|
||||||
{
|
|
||||||
parallel_for(blocked_range<size_t>(0, mapSize.x), [&](const blocked_range<size_t> & r)
|
|
||||||
{
|
|
||||||
int3 pos(0, 0, z);
|
|
||||||
std::vector<AIPath> paths;
|
|
||||||
|
|
||||||
for(pos.x = r.begin(); pos.x != r.end(); ++pos.x)
|
|
||||||
{
|
|
||||||
for(pos.y = 0; pos.y < mapSize.y; ++pos.y)
|
|
||||||
{
|
|
||||||
ai->pathfinder->calculatePathInfo(paths, pos);
|
|
||||||
fn(pos, paths);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class CDistanceSorter
|
class CDistanceSorter
|
||||||
{
|
{
|
||||||
const CGHeroInstance * hero;
|
const CGHeroInstance * hero;
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "DangerHitMapAnalyzer.h"
|
#include "DangerHitMapAnalyzer.h"
|
||||||
|
|
||||||
#include "../Engine/Nullkiller.h"
|
#include "../Engine/Nullkiller.h"
|
||||||
|
#include "../pforeach.h"
|
||||||
#include "../../../lib/CRandomGenerator.h"
|
#include "../../../lib/CRandomGenerator.h"
|
||||||
|
|
||||||
namespace NKAI
|
namespace NKAI
|
||||||
|
@ -235,9 +235,9 @@ void ObjectClusterizer::clusterize()
|
|||||||
ai->memory->visitableObjs.end());
|
ai->memory->visitableObjs.end());
|
||||||
|
|
||||||
#if NKAI_TRACE_LEVEL == 0
|
#if NKAI_TRACE_LEVEL == 0
|
||||||
parallel_for(blocked_range<size_t>(0, objs.size()), [&](const blocked_range<size_t> & r) {
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, objs.size()), [&](const tbb::blocked_range<size_t> & r) {
|
||||||
#else
|
#else
|
||||||
blocked_range<size_t> r(0, objs.size());
|
tbb::blocked_range<size_t> r(0, objs.size());
|
||||||
#endif
|
#endif
|
||||||
auto priorityEvaluator = ai->priorityEvaluators->acquire();
|
auto priorityEvaluator = ai->priorityEvaluators->acquire();
|
||||||
auto heroes = ai->cb->getHeroesInfo();
|
auto heroes = ai->cb->getHeroesInfo();
|
||||||
|
@ -69,7 +69,7 @@ Goals::TGoalVec GatherArmyBehavior::deliverArmyToHero(const CGHeroInstance * her
|
|||||||
logAi->trace("Checking ways to gaher army for hero %s, %s", hero->getObjectName(), pos.toString());
|
logAi->trace("Checking ways to gaher army for hero %s, %s", hero->getObjectName(), pos.toString());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto paths = ai->nullkiller->pathfinder->getPathInfo(pos);
|
auto paths = ai->nullkiller->pathfinder->getPathInfo(pos, ai->nullkiller->settings->isObjectGraphAllowed());
|
||||||
|
|
||||||
#if NKAI_TRACE_LEVEL >= 1
|
#if NKAI_TRACE_LEVEL >= 1
|
||||||
logAi->trace("Gather army found %d paths", paths.size());
|
logAi->trace("Gather army found %d paths", paths.size());
|
||||||
@ -231,7 +231,7 @@ Goals::TGoalVec GatherArmyBehavior::upgradeArmy(const CGTownInstance * upgrader)
|
|||||||
logAi->trace("Checking ways to upgrade army in town %s, %s", upgrader->getObjectName(), pos.toString());
|
logAi->trace("Checking ways to upgrade army in town %s, %s", upgrader->getObjectName(), pos.toString());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto paths = ai->nullkiller->pathfinder->getPathInfo(pos);
|
auto paths = ai->nullkiller->pathfinder->getPathInfo(pos, ai->nullkiller->settings->isObjectGraphAllowed());
|
||||||
auto goals = CaptureObjectsBehavior::getVisitGoals(paths);
|
auto goals = CaptureObjectsBehavior::getVisitGoals(paths);
|
||||||
|
|
||||||
std::vector<std::shared_ptr<ExecuteHeroChain>> waysToVisitObj;
|
std::vector<std::shared_ptr<ExecuteHeroChain>> waysToVisitObj;
|
||||||
|
@ -81,6 +81,7 @@ set(Nullkiller_HEADERS
|
|||||||
Pathfinding/Rules/AIPreviousNodeRule.h
|
Pathfinding/Rules/AIPreviousNodeRule.h
|
||||||
Pathfinding/ObjectGraph.h
|
Pathfinding/ObjectGraph.h
|
||||||
AIUtility.h
|
AIUtility.h
|
||||||
|
pforeach.h
|
||||||
Analyzers/ArmyManager.h
|
Analyzers/ArmyManager.h
|
||||||
Analyzers/HeroManager.h
|
Analyzers/HeroManager.h
|
||||||
Engine/Settings.h
|
Engine/Settings.h
|
||||||
|
@ -412,7 +412,6 @@ struct DelayedWork
|
|||||||
class HeroChainCalculationTask
|
class HeroChainCalculationTask
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
AISharedStorage & nodes;
|
|
||||||
AINodeStorage & storage;
|
AINodeStorage & storage;
|
||||||
std::vector<AIPathNode *> existingChains;
|
std::vector<AIPathNode *> existingChains;
|
||||||
std::vector<ExchangeCandidate> newChains;
|
std::vector<ExchangeCandidate> newChains;
|
||||||
@ -424,8 +423,8 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
HeroChainCalculationTask(
|
HeroChainCalculationTask(
|
||||||
AINodeStorage & storage, AISharedStorage & nodes, const std::vector<int3> & tiles, uint64_t chainMask, int heroChainTurn)
|
AINodeStorage & storage, const std::vector<int3> & tiles, uint64_t chainMask, int heroChainTurn)
|
||||||
:existingChains(), newChains(), delayedWork(), nodes(nodes), storage(storage), chainMask(chainMask), heroChainTurn(heroChainTurn), heroChain(), tiles(tiles)
|
:existingChains(), newChains(), delayedWork(), storage(storage), chainMask(chainMask), heroChainTurn(heroChainTurn), heroChain(), tiles(tiles)
|
||||||
{
|
{
|
||||||
existingChains.reserve(AIPathfinding::NUM_CHAINS);
|
existingChains.reserve(AIPathfinding::NUM_CHAINS);
|
||||||
newChains.reserve(AIPathfinding::NUM_CHAINS);
|
newChains.reserve(AIPathfinding::NUM_CHAINS);
|
||||||
@ -621,7 +620,6 @@ void HeroChainCalculationTask::cleanupInefectiveChains(std::vector<ExchangeCandi
|
|||||||
{
|
{
|
||||||
vstd::erase_if(result, [&](const ExchangeCandidate & chainInfo) -> bool
|
vstd::erase_if(result, [&](const ExchangeCandidate & chainInfo) -> bool
|
||||||
{
|
{
|
||||||
auto pos = chainInfo.coord;
|
|
||||||
auto isNotEffective = storage.hasBetterChain(chainInfo.carrierParent, chainInfo)
|
auto isNotEffective = storage.hasBetterChain(chainInfo.carrierParent, chainInfo)
|
||||||
|| storage.hasBetterChain(chainInfo.carrierParent, chainInfo, result);
|
|| storage.hasBetterChain(chainInfo.carrierParent, chainInfo, result);
|
||||||
|
|
||||||
|
@ -168,6 +168,37 @@ private:
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
auto obj = ai->cb->getTopObj(pos);
|
||||||
|
|
||||||
|
if(obj && obj->ID == Obj::BOAT)
|
||||||
|
{
|
||||||
|
ai->pathfinder->calculatePathInfo(pathCache, pos);
|
||||||
|
|
||||||
|
for(AIPath & path : pathCache)
|
||||||
|
{
|
||||||
|
auto from = path.targetHero->visitablePos();
|
||||||
|
auto fromObj = actorObjectMap[path.targetHero];
|
||||||
|
auto fromTile = cb->getTile(from);
|
||||||
|
|
||||||
|
auto danger = ai->pathfinder->getStorage()->evaluateDanger(pos, path.targetHero, true);
|
||||||
|
auto updated = target->tryAddConnection(
|
||||||
|
from,
|
||||||
|
pos,
|
||||||
|
path.movementCost(),
|
||||||
|
danger);
|
||||||
|
|
||||||
|
if(NKAI_GRAPH_TRACE_LEVEL >= 2 && updated)
|
||||||
|
{
|
||||||
|
logAi->trace(
|
||||||
|
"Connected %s[%s] -> %s[%s] through [%s], cost %2f",
|
||||||
|
fromObj ? fromObj->getObjectName() : "J", from.toString(),
|
||||||
|
"Boat", pos.toString(),
|
||||||
|
pos.toString(),
|
||||||
|
path.movementCost());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +230,9 @@ private:
|
|||||||
if(!cb->getTile(pos)->isWater())
|
if(!cb->getTile(pos)->isWater())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(obj1 && (obj1->ID != Obj::BOAT || obj1->ID != Obj::SHIPYARD))
|
auto startingObjIsBoatOrShipyard = obj1 && (obj1->ID == Obj::BOAT || obj1->ID == Obj::SHIPYARD);
|
||||||
|
|
||||||
|
if(!startingObjIsBoatOrShipyard)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,7 +320,7 @@ private:
|
|||||||
assert(objectActor->visitablePos() == visitablePos);
|
assert(objectActor->visitablePos() == visitablePos);
|
||||||
|
|
||||||
actorObjectMap[objectActor] = obj;
|
actorObjectMap[objectActor] = obj;
|
||||||
actors[objectActor] = obj->ID == Obj::TOWN || obj->ID == Obj::SHIPYARD ? HeroRole::MAIN : HeroRole::SCOUT;
|
actors[objectActor] = obj->ID == Obj::TOWN || obj->ID == Obj::SHIPYARD || obj->ID == Obj::BOAT ? HeroRole::MAIN : HeroRole::SCOUT;
|
||||||
|
|
||||||
target->addObject(obj);
|
target->addObject(obj);
|
||||||
}
|
}
|
||||||
@ -717,9 +750,6 @@ void GraphPaths::quickAddChainInfoWithBlocker(std::vector<AIPath> & paths, int3
|
|||||||
|
|
||||||
auto currentNode = currentTile->second[current.nodeType];
|
auto currentNode = currentTile->second[current.nodeType];
|
||||||
|
|
||||||
if(!currentNode.previous.valid())
|
|
||||||
break;
|
|
||||||
|
|
||||||
allowBattle = allowBattle || currentNode.nodeType == GrapthPathNodeType::BATTLE;
|
allowBattle = allowBattle || currentNode.nodeType == GrapthPathNodeType::BATTLE;
|
||||||
vstd::amax(danger, currentNode.danger);
|
vstd::amax(danger, currentNode.danger);
|
||||||
vstd::amax(cost, currentNode.cost);
|
vstd::amax(cost, currentNode.cost);
|
||||||
@ -777,7 +807,7 @@ void GraphPaths::quickAddChainInfoWithBlocker(std::vector<AIPath> & paths, int3
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!path.nodes.empty())
|
if(!path.nodes.empty())
|
||||||
break;
|
continue;
|
||||||
|
|
||||||
for(auto graphTile = tilesToPass.rbegin(); graphTile != tilesToPass.rend(); graphTile++)
|
for(auto graphTile = tilesToPass.rbegin(); graphTile != tilesToPass.rend(); graphTile++)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user