1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-19 21:10:12 +02:00

Try to reduce amount of time AI spends on pathfinding

This commit is contained in:
Ivan Savenko 2024-12-23 13:26:54 +00:00
parent e035cf9e63
commit 1caab5100a
7 changed files with 59 additions and 33 deletions

View File

@ -97,6 +97,8 @@ void AIGateway::heroMoved(const TryMoveHero & details, bool verbose)
if(!hero)
validateObject(details.id); //enemy hero may have left visible area
nullkiller->invalidatePathfinderData();
const int3 from = hero ? hero->convertToVisitablePos(details.start) : (details.start - int3(0,1,0));
const int3 to = hero ? hero->convertToVisitablePos(details.end) : (details.end - int3(0,1,0));
@ -358,6 +360,7 @@ void AIGateway::newObject(const CGObjectInstance * obj)
{
LOG_TRACE(logAi);
NET_EVENT_HANDLER;
nullkiller->invalidatePathfinderData();
if(obj->isVisitable())
addVisitableObj(obj);
}
@ -582,6 +585,7 @@ void AIGateway::yourTurn(QueryID queryID)
{
LOG_TRACE_PARAMS(logAi, "queryID '%i'", queryID);
NET_EVENT_HANDLER;
nullkiller->invalidatePathfinderData();
status.addQuery(queryID, "YourTurn");
requestActionASAP([=](){ answerQuery(queryID, 0); });
status.startedTurn();

View File

@ -37,6 +37,7 @@ Nullkiller::Nullkiller()
: activeHero(nullptr)
, scanDepth(ScanDepth::MAIN_FULL)
, useHeroChain(true)
, pathfinderInvalidated(false)
, memory(std::make_unique<AIMemory>())
{
@ -239,6 +240,11 @@ void Nullkiller::resetAiState()
}
}
void Nullkiller::invalidatePathfinderData()
{
pathfinderInvalidated = true;
}
void Nullkiller::updateAiState(int pass, bool fast)
{
boost::this_thread::interruption_point();
@ -253,7 +259,10 @@ void Nullkiller::updateAiState(int pass, bool fast)
decomposer->reset();
buildAnalyzer->update();
if(!fast)
if (!pathfinderInvalidated)
logAi->trace("Skipping paths regeneration - up to date");
if(!fast && pathfinderInvalidated)
{
memory->removeInvisibleObjects(cb.get());
@ -304,11 +313,13 @@ void Nullkiller::updateAiState(int pass, bool fast)
boost::this_thread::interruption_point();
objectClusterizer->clusterize();
pathfinderInvalidated = false;
}
armyManager->update();
logAi->debug("AI state updated in %ld", timeElapsed(start));
logAi->debug("AI state updated in %ld ms", timeElapsed(start));
}
bool Nullkiller::isHeroLocked(const CGHeroInstance * hero) const
@ -379,7 +390,7 @@ void Nullkiller::makeTurn()
Goals::TTask bestTask = taskptr(Goals::Invalid());
while(true)
for(int j = 1; j <= settings->getMaxPriorityPass() && cb->getPlayerStatus(playerID) == EPlayerStatus::INGAME; j++)
{
bestTasks.clear();

View File

@ -78,6 +78,7 @@ private:
AIGateway * gateway;
bool openMap;
bool useObjectGraph;
bool pathfinderInvalidated;
public:
static std::unique_ptr<ObjectGraph> baseGraph;
@ -121,6 +122,7 @@ public:
bool isOpenMap() const { return openMap; }
bool isObjectGraphAllowed() const { return useObjectGraph; }
bool handleTrading();
void invalidatePathfinderData();
private:
void resetAiState();

View File

@ -32,7 +32,8 @@ namespace NKAI
retreatThresholdRelative(0.3),
retreatThresholdAbsolute(10000),
safeAttackRatio(1.1),
maxpass(10),
maxPass(10),
maxPriorityPass(10),
pathfinderBucketsCount(1),
pathfinderBucketSize(32),
allowObjectGraph(true),
@ -48,7 +49,8 @@ namespace NKAI
maxRoamingHeroes = node["maxRoamingHeroes"].Integer();
mainHeroTurnDistanceLimit = node["mainHeroTurnDistanceLimit"].Integer();
scoutHeroTurnDistanceLimit = node["scoutHeroTurnDistanceLimit"].Integer();
maxpass = node["maxpass"].Integer();
maxPass = node["maxPass"].Integer();
maxPriorityPass = node["maxPriorityPass"].Integer();
pathfinderBucketsCount = node["pathfinderBucketsCount"].Integer();
pathfinderBucketSize = node["pathfinderBucketSize"].Integer();
maxGoldPressure = node["maxGoldPressure"].Float();

View File

@ -24,7 +24,8 @@ namespace NKAI
int maxRoamingHeroes;
int mainHeroTurnDistanceLimit;
int scoutHeroTurnDistanceLimit;
int maxpass;
int maxPass;
int maxPriorityPass;
int pathfinderBucketsCount;
int pathfinderBucketSize;
float maxGoldPressure;
@ -41,7 +42,8 @@ namespace NKAI
public:
explicit Settings(int difficultyLevel);
int getMaxPass() const { return maxpass; }
int getMaxPass() const { return maxPass; }
int getMaxPriorityPass() const { return maxPriorityPass; }
float getMaxGoldPressure() const { return maxGoldPressure; }
float getRetreatThresholdRelative() const { return retreatThresholdRelative; }
float getRetreatThresholdAbsolute() const { return retreatThresholdAbsolute; }

View File

@ -106,7 +106,7 @@ void AIPathfinder::updatePaths(const std::map<const CGHeroInstance *, HeroRole>
if(!pathfinderSettings.useHeroChain)
{
logAi->trace("Recalculated paths in %ld", timeElapsed(start));
logAi->trace("Recalculated paths in %ld ms", timeElapsed(start));
return;
}
@ -141,7 +141,7 @@ void AIPathfinder::updatePaths(const std::map<const CGHeroInstance *, HeroRole>
}
} while(storage->increaseHeroChainTurnLimit());
logAi->trace("Recalculated paths in %ld", timeElapsed(start));
logAi->trace("Recalculated paths in %ld ms", timeElapsed(start));
}
void AIPathfinder::updateGraphs(

View File

@ -33,17 +33,18 @@
"pawn" : {
"maxRoamingHeroes" : 4, //H3 value: 3,
"maxpass" : 30,
"maxRoamingHeroes" : 3, //H3 value: 3,
"maxPass" : 30,
"maxPriorityPass" : 10,
"mainHeroTurnDistanceLimit" : 10,
"scoutHeroTurnDistanceLimit" : 5,
"maxGoldPressure" : 0.3,
"updateHitmapOnTileReveal" : false,
"useTroopsFromGarrisons" : true,
"openMap": true,
"allowObjectGraph": false,
"pathfinderBucketsCount" : 1, // old value: 3,
"pathfinderBucketSize" : 32, // old value: 7,
"allowObjectGraph": true,
"pathfinderBucketsCount" : 4, // old value: 3,
"pathfinderBucketSize" : 8, // old value: 7,
"retreatThresholdRelative" : 0,
"retreatThresholdAbsolute" : 0,
"safeAttackRatio" : 1.1,
@ -52,17 +53,18 @@
},
"knight" : {
"maxRoamingHeroes" : 6, //H3 value: 3,
"maxpass" : 30,
"maxRoamingHeroes" : 3, //H3 value: 3,
"maxPass" : 30,
"maxPriorityPass" : 10,
"mainHeroTurnDistanceLimit" : 10,
"scoutHeroTurnDistanceLimit" : 5,
"maxGoldPressure" : 0.3,
"updateHitmapOnTileReveal" : false,
"useTroopsFromGarrisons" : true,
"openMap": true,
"allowObjectGraph": false,
"pathfinderBucketsCount" : 1, // old value: 3,
"pathfinderBucketSize" : 32, // old value: 7,
"allowObjectGraph": true,
"pathfinderBucketsCount" : 4, // old value: 3,
"pathfinderBucketSize" : 8, // old value: 7,
"retreatThresholdRelative" : 0.1,
"retreatThresholdAbsolute" : 5000,
"safeAttackRatio" : 1.1,
@ -71,17 +73,18 @@
},
"rook" : {
"maxRoamingHeroes" : 8, //H3 value: 4
"maxpass" : 30,
"maxRoamingHeroes" : 4, //H3 value: 4
"maxPass" : 30,
"maxPriorityPass" : 10,
"mainHeroTurnDistanceLimit" : 10,
"scoutHeroTurnDistanceLimit" : 5,
"maxGoldPressure" : 0.3,
"updateHitmapOnTileReveal" : false,
"useTroopsFromGarrisons" : true,
"openMap": true,
"allowObjectGraph": false,
"pathfinderBucketsCount" : 1, // old value: 3,
"pathfinderBucketSize" : 32, // old value: 7,
"allowObjectGraph": true,
"pathfinderBucketsCount" : 4, // old value: 3,
"pathfinderBucketSize" : 8, // old value: 7,
"retreatThresholdRelative" : 0.3,
"retreatThresholdAbsolute" : 10000,
"safeAttackRatio" : 1.1,
@ -90,17 +93,18 @@
},
"queen" : {
"maxRoamingHeroes" : 8, //H3 value: 5
"maxpass" : 30,
"maxRoamingHeroes" : 6, //H3 value: 5
"maxPass" : 30,
"maxPriorityPass" : 10,
"mainHeroTurnDistanceLimit" : 10,
"scoutHeroTurnDistanceLimit" : 5,
"maxGoldPressure" : 0.3,
"updateHitmapOnTileReveal" : false,
"useTroopsFromGarrisons" : true,
"openMap": true,
"allowObjectGraph": false,
"pathfinderBucketsCount" : 1, // old value: 3,
"pathfinderBucketSize" : 32, // old value: 7,
"allowObjectGraph": true,
"pathfinderBucketsCount" : 4, // old value: 3,
"pathfinderBucketSize" : 8, // old value: 7,
"retreatThresholdRelative" : 0.3,
"retreatThresholdAbsolute" : 10000,
"safeAttackRatio" : 1.1,
@ -110,16 +114,17 @@
"king" : {
"maxRoamingHeroes" : 8, //H3 value: 6
"maxpass" : 30,
"maxPass" : 30,
"maxPriorityPass" : 10,
"mainHeroTurnDistanceLimit" : 10,
"scoutHeroTurnDistanceLimit" : 5,
"maxGoldPressure" : 0.3,
"updateHitmapOnTileReveal" : false,
"useTroopsFromGarrisons" : true,
"openMap": true,
"allowObjectGraph": false,
"pathfinderBucketsCount" : 1, // old value: 3,
"pathfinderBucketSize" : 32, // old value: 7,
"allowObjectGraph": true,
"pathfinderBucketsCount" : 4, // old value: 3,
"pathfinderBucketSize" : 8, // old value: 7,
"retreatThresholdRelative" : 0.3,
"retreatThresholdAbsolute" : 10000,
"safeAttackRatio" : 1.1,