mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-17 01:32:21 +02:00
Try to reduce amount of time AI spends on pathfinding
This commit is contained in:
@ -97,6 +97,8 @@ void AIGateway::heroMoved(const TryMoveHero & details, bool verbose)
|
|||||||
if(!hero)
|
if(!hero)
|
||||||
validateObject(details.id); //enemy hero may have left visible area
|
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 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));
|
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);
|
LOG_TRACE(logAi);
|
||||||
NET_EVENT_HANDLER;
|
NET_EVENT_HANDLER;
|
||||||
|
nullkiller->invalidatePathfinderData();
|
||||||
if(obj->isVisitable())
|
if(obj->isVisitable())
|
||||||
addVisitableObj(obj);
|
addVisitableObj(obj);
|
||||||
}
|
}
|
||||||
@ -582,6 +585,7 @@ void AIGateway::yourTurn(QueryID queryID)
|
|||||||
{
|
{
|
||||||
LOG_TRACE_PARAMS(logAi, "queryID '%i'", queryID);
|
LOG_TRACE_PARAMS(logAi, "queryID '%i'", queryID);
|
||||||
NET_EVENT_HANDLER;
|
NET_EVENT_HANDLER;
|
||||||
|
nullkiller->invalidatePathfinderData();
|
||||||
status.addQuery(queryID, "YourTurn");
|
status.addQuery(queryID, "YourTurn");
|
||||||
requestActionASAP([=](){ answerQuery(queryID, 0); });
|
requestActionASAP([=](){ answerQuery(queryID, 0); });
|
||||||
status.startedTurn();
|
status.startedTurn();
|
||||||
|
@ -37,6 +37,7 @@ Nullkiller::Nullkiller()
|
|||||||
: activeHero(nullptr)
|
: activeHero(nullptr)
|
||||||
, scanDepth(ScanDepth::MAIN_FULL)
|
, scanDepth(ScanDepth::MAIN_FULL)
|
||||||
, useHeroChain(true)
|
, useHeroChain(true)
|
||||||
|
, pathfinderInvalidated(false)
|
||||||
, memory(std::make_unique<AIMemory>())
|
, memory(std::make_unique<AIMemory>())
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -239,6 +240,11 @@ void Nullkiller::resetAiState()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Nullkiller::invalidatePathfinderData()
|
||||||
|
{
|
||||||
|
pathfinderInvalidated = true;
|
||||||
|
}
|
||||||
|
|
||||||
void Nullkiller::updateAiState(int pass, bool fast)
|
void Nullkiller::updateAiState(int pass, bool fast)
|
||||||
{
|
{
|
||||||
boost::this_thread::interruption_point();
|
boost::this_thread::interruption_point();
|
||||||
@ -253,7 +259,10 @@ void Nullkiller::updateAiState(int pass, bool fast)
|
|||||||
decomposer->reset();
|
decomposer->reset();
|
||||||
buildAnalyzer->update();
|
buildAnalyzer->update();
|
||||||
|
|
||||||
if(!fast)
|
if (!pathfinderInvalidated)
|
||||||
|
logAi->trace("Skipping paths regeneration - up to date");
|
||||||
|
|
||||||
|
if(!fast && pathfinderInvalidated)
|
||||||
{
|
{
|
||||||
memory->removeInvisibleObjects(cb.get());
|
memory->removeInvisibleObjects(cb.get());
|
||||||
|
|
||||||
@ -304,11 +313,13 @@ void Nullkiller::updateAiState(int pass, bool fast)
|
|||||||
boost::this_thread::interruption_point();
|
boost::this_thread::interruption_point();
|
||||||
|
|
||||||
objectClusterizer->clusterize();
|
objectClusterizer->clusterize();
|
||||||
|
|
||||||
|
pathfinderInvalidated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
armyManager->update();
|
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
|
bool Nullkiller::isHeroLocked(const CGHeroInstance * hero) const
|
||||||
@ -379,7 +390,7 @@ void Nullkiller::makeTurn()
|
|||||||
|
|
||||||
Goals::TTask bestTask = taskptr(Goals::Invalid());
|
Goals::TTask bestTask = taskptr(Goals::Invalid());
|
||||||
|
|
||||||
while(true)
|
for(int j = 1; j <= settings->getMaxPriorityPass() && cb->getPlayerStatus(playerID) == EPlayerStatus::INGAME; j++)
|
||||||
{
|
{
|
||||||
bestTasks.clear();
|
bestTasks.clear();
|
||||||
|
|
||||||
|
@ -78,6 +78,7 @@ private:
|
|||||||
AIGateway * gateway;
|
AIGateway * gateway;
|
||||||
bool openMap;
|
bool openMap;
|
||||||
bool useObjectGraph;
|
bool useObjectGraph;
|
||||||
|
bool pathfinderInvalidated;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<ObjectGraph> baseGraph;
|
static std::unique_ptr<ObjectGraph> baseGraph;
|
||||||
@ -121,6 +122,7 @@ public:
|
|||||||
bool isOpenMap() const { return openMap; }
|
bool isOpenMap() const { return openMap; }
|
||||||
bool isObjectGraphAllowed() const { return useObjectGraph; }
|
bool isObjectGraphAllowed() const { return useObjectGraph; }
|
||||||
bool handleTrading();
|
bool handleTrading();
|
||||||
|
void invalidatePathfinderData();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void resetAiState();
|
void resetAiState();
|
||||||
|
@ -32,7 +32,8 @@ namespace NKAI
|
|||||||
retreatThresholdRelative(0.3),
|
retreatThresholdRelative(0.3),
|
||||||
retreatThresholdAbsolute(10000),
|
retreatThresholdAbsolute(10000),
|
||||||
safeAttackRatio(1.1),
|
safeAttackRatio(1.1),
|
||||||
maxpass(10),
|
maxPass(10),
|
||||||
|
maxPriorityPass(10),
|
||||||
pathfinderBucketsCount(1),
|
pathfinderBucketsCount(1),
|
||||||
pathfinderBucketSize(32),
|
pathfinderBucketSize(32),
|
||||||
allowObjectGraph(true),
|
allowObjectGraph(true),
|
||||||
@ -48,7 +49,8 @@ namespace NKAI
|
|||||||
maxRoamingHeroes = node["maxRoamingHeroes"].Integer();
|
maxRoamingHeroes = node["maxRoamingHeroes"].Integer();
|
||||||
mainHeroTurnDistanceLimit = node["mainHeroTurnDistanceLimit"].Integer();
|
mainHeroTurnDistanceLimit = node["mainHeroTurnDistanceLimit"].Integer();
|
||||||
scoutHeroTurnDistanceLimit = node["scoutHeroTurnDistanceLimit"].Integer();
|
scoutHeroTurnDistanceLimit = node["scoutHeroTurnDistanceLimit"].Integer();
|
||||||
maxpass = node["maxpass"].Integer();
|
maxPass = node["maxPass"].Integer();
|
||||||
|
maxPriorityPass = node["maxPriorityPass"].Integer();
|
||||||
pathfinderBucketsCount = node["pathfinderBucketsCount"].Integer();
|
pathfinderBucketsCount = node["pathfinderBucketsCount"].Integer();
|
||||||
pathfinderBucketSize = node["pathfinderBucketSize"].Integer();
|
pathfinderBucketSize = node["pathfinderBucketSize"].Integer();
|
||||||
maxGoldPressure = node["maxGoldPressure"].Float();
|
maxGoldPressure = node["maxGoldPressure"].Float();
|
||||||
|
@ -24,7 +24,8 @@ namespace NKAI
|
|||||||
int maxRoamingHeroes;
|
int maxRoamingHeroes;
|
||||||
int mainHeroTurnDistanceLimit;
|
int mainHeroTurnDistanceLimit;
|
||||||
int scoutHeroTurnDistanceLimit;
|
int scoutHeroTurnDistanceLimit;
|
||||||
int maxpass;
|
int maxPass;
|
||||||
|
int maxPriorityPass;
|
||||||
int pathfinderBucketsCount;
|
int pathfinderBucketsCount;
|
||||||
int pathfinderBucketSize;
|
int pathfinderBucketSize;
|
||||||
float maxGoldPressure;
|
float maxGoldPressure;
|
||||||
@ -41,7 +42,8 @@ namespace NKAI
|
|||||||
public:
|
public:
|
||||||
explicit Settings(int difficultyLevel);
|
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 getMaxGoldPressure() const { return maxGoldPressure; }
|
||||||
float getRetreatThresholdRelative() const { return retreatThresholdRelative; }
|
float getRetreatThresholdRelative() const { return retreatThresholdRelative; }
|
||||||
float getRetreatThresholdAbsolute() const { return retreatThresholdAbsolute; }
|
float getRetreatThresholdAbsolute() const { return retreatThresholdAbsolute; }
|
||||||
|
@ -106,7 +106,7 @@ void AIPathfinder::updatePaths(const std::map<const CGHeroInstance *, HeroRole>
|
|||||||
|
|
||||||
if(!pathfinderSettings.useHeroChain)
|
if(!pathfinderSettings.useHeroChain)
|
||||||
{
|
{
|
||||||
logAi->trace("Recalculated paths in %ld", timeElapsed(start));
|
logAi->trace("Recalculated paths in %ld ms", timeElapsed(start));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -141,7 +141,7 @@ void AIPathfinder::updatePaths(const std::map<const CGHeroInstance *, HeroRole>
|
|||||||
}
|
}
|
||||||
} while(storage->increaseHeroChainTurnLimit());
|
} while(storage->increaseHeroChainTurnLimit());
|
||||||
|
|
||||||
logAi->trace("Recalculated paths in %ld", timeElapsed(start));
|
logAi->trace("Recalculated paths in %ld ms", timeElapsed(start));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AIPathfinder::updateGraphs(
|
void AIPathfinder::updateGraphs(
|
||||||
|
@ -33,17 +33,18 @@
|
|||||||
|
|
||||||
|
|
||||||
"pawn" : {
|
"pawn" : {
|
||||||
"maxRoamingHeroes" : 4, //H3 value: 3,
|
"maxRoamingHeroes" : 3, //H3 value: 3,
|
||||||
"maxpass" : 30,
|
"maxPass" : 30,
|
||||||
|
"maxPriorityPass" : 10,
|
||||||
"mainHeroTurnDistanceLimit" : 10,
|
"mainHeroTurnDistanceLimit" : 10,
|
||||||
"scoutHeroTurnDistanceLimit" : 5,
|
"scoutHeroTurnDistanceLimit" : 5,
|
||||||
"maxGoldPressure" : 0.3,
|
"maxGoldPressure" : 0.3,
|
||||||
"updateHitmapOnTileReveal" : false,
|
"updateHitmapOnTileReveal" : false,
|
||||||
"useTroopsFromGarrisons" : true,
|
"useTroopsFromGarrisons" : true,
|
||||||
"openMap": true,
|
"openMap": true,
|
||||||
"allowObjectGraph": false,
|
"allowObjectGraph": true,
|
||||||
"pathfinderBucketsCount" : 1, // old value: 3,
|
"pathfinderBucketsCount" : 4, // old value: 3,
|
||||||
"pathfinderBucketSize" : 32, // old value: 7,
|
"pathfinderBucketSize" : 8, // old value: 7,
|
||||||
"retreatThresholdRelative" : 0,
|
"retreatThresholdRelative" : 0,
|
||||||
"retreatThresholdAbsolute" : 0,
|
"retreatThresholdAbsolute" : 0,
|
||||||
"safeAttackRatio" : 1.1,
|
"safeAttackRatio" : 1.1,
|
||||||
@ -52,17 +53,18 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"knight" : {
|
"knight" : {
|
||||||
"maxRoamingHeroes" : 6, //H3 value: 3,
|
"maxRoamingHeroes" : 3, //H3 value: 3,
|
||||||
"maxpass" : 30,
|
"maxPass" : 30,
|
||||||
|
"maxPriorityPass" : 10,
|
||||||
"mainHeroTurnDistanceLimit" : 10,
|
"mainHeroTurnDistanceLimit" : 10,
|
||||||
"scoutHeroTurnDistanceLimit" : 5,
|
"scoutHeroTurnDistanceLimit" : 5,
|
||||||
"maxGoldPressure" : 0.3,
|
"maxGoldPressure" : 0.3,
|
||||||
"updateHitmapOnTileReveal" : false,
|
"updateHitmapOnTileReveal" : false,
|
||||||
"useTroopsFromGarrisons" : true,
|
"useTroopsFromGarrisons" : true,
|
||||||
"openMap": true,
|
"openMap": true,
|
||||||
"allowObjectGraph": false,
|
"allowObjectGraph": true,
|
||||||
"pathfinderBucketsCount" : 1, // old value: 3,
|
"pathfinderBucketsCount" : 4, // old value: 3,
|
||||||
"pathfinderBucketSize" : 32, // old value: 7,
|
"pathfinderBucketSize" : 8, // old value: 7,
|
||||||
"retreatThresholdRelative" : 0.1,
|
"retreatThresholdRelative" : 0.1,
|
||||||
"retreatThresholdAbsolute" : 5000,
|
"retreatThresholdAbsolute" : 5000,
|
||||||
"safeAttackRatio" : 1.1,
|
"safeAttackRatio" : 1.1,
|
||||||
@ -71,17 +73,18 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"rook" : {
|
"rook" : {
|
||||||
"maxRoamingHeroes" : 8, //H3 value: 4
|
"maxRoamingHeroes" : 4, //H3 value: 4
|
||||||
"maxpass" : 30,
|
"maxPass" : 30,
|
||||||
|
"maxPriorityPass" : 10,
|
||||||
"mainHeroTurnDistanceLimit" : 10,
|
"mainHeroTurnDistanceLimit" : 10,
|
||||||
"scoutHeroTurnDistanceLimit" : 5,
|
"scoutHeroTurnDistanceLimit" : 5,
|
||||||
"maxGoldPressure" : 0.3,
|
"maxGoldPressure" : 0.3,
|
||||||
"updateHitmapOnTileReveal" : false,
|
"updateHitmapOnTileReveal" : false,
|
||||||
"useTroopsFromGarrisons" : true,
|
"useTroopsFromGarrisons" : true,
|
||||||
"openMap": true,
|
"openMap": true,
|
||||||
"allowObjectGraph": false,
|
"allowObjectGraph": true,
|
||||||
"pathfinderBucketsCount" : 1, // old value: 3,
|
"pathfinderBucketsCount" : 4, // old value: 3,
|
||||||
"pathfinderBucketSize" : 32, // old value: 7,
|
"pathfinderBucketSize" : 8, // old value: 7,
|
||||||
"retreatThresholdRelative" : 0.3,
|
"retreatThresholdRelative" : 0.3,
|
||||||
"retreatThresholdAbsolute" : 10000,
|
"retreatThresholdAbsolute" : 10000,
|
||||||
"safeAttackRatio" : 1.1,
|
"safeAttackRatio" : 1.1,
|
||||||
@ -90,17 +93,18 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"queen" : {
|
"queen" : {
|
||||||
"maxRoamingHeroes" : 8, //H3 value: 5
|
"maxRoamingHeroes" : 6, //H3 value: 5
|
||||||
"maxpass" : 30,
|
"maxPass" : 30,
|
||||||
|
"maxPriorityPass" : 10,
|
||||||
"mainHeroTurnDistanceLimit" : 10,
|
"mainHeroTurnDistanceLimit" : 10,
|
||||||
"scoutHeroTurnDistanceLimit" : 5,
|
"scoutHeroTurnDistanceLimit" : 5,
|
||||||
"maxGoldPressure" : 0.3,
|
"maxGoldPressure" : 0.3,
|
||||||
"updateHitmapOnTileReveal" : false,
|
"updateHitmapOnTileReveal" : false,
|
||||||
"useTroopsFromGarrisons" : true,
|
"useTroopsFromGarrisons" : true,
|
||||||
"openMap": true,
|
"openMap": true,
|
||||||
"allowObjectGraph": false,
|
"allowObjectGraph": true,
|
||||||
"pathfinderBucketsCount" : 1, // old value: 3,
|
"pathfinderBucketsCount" : 4, // old value: 3,
|
||||||
"pathfinderBucketSize" : 32, // old value: 7,
|
"pathfinderBucketSize" : 8, // old value: 7,
|
||||||
"retreatThresholdRelative" : 0.3,
|
"retreatThresholdRelative" : 0.3,
|
||||||
"retreatThresholdAbsolute" : 10000,
|
"retreatThresholdAbsolute" : 10000,
|
||||||
"safeAttackRatio" : 1.1,
|
"safeAttackRatio" : 1.1,
|
||||||
@ -110,16 +114,17 @@
|
|||||||
|
|
||||||
"king" : {
|
"king" : {
|
||||||
"maxRoamingHeroes" : 8, //H3 value: 6
|
"maxRoamingHeroes" : 8, //H3 value: 6
|
||||||
"maxpass" : 30,
|
"maxPass" : 30,
|
||||||
|
"maxPriorityPass" : 10,
|
||||||
"mainHeroTurnDistanceLimit" : 10,
|
"mainHeroTurnDistanceLimit" : 10,
|
||||||
"scoutHeroTurnDistanceLimit" : 5,
|
"scoutHeroTurnDistanceLimit" : 5,
|
||||||
"maxGoldPressure" : 0.3,
|
"maxGoldPressure" : 0.3,
|
||||||
"updateHitmapOnTileReveal" : false,
|
"updateHitmapOnTileReveal" : false,
|
||||||
"useTroopsFromGarrisons" : true,
|
"useTroopsFromGarrisons" : true,
|
||||||
"openMap": true,
|
"openMap": true,
|
||||||
"allowObjectGraph": false,
|
"allowObjectGraph": true,
|
||||||
"pathfinderBucketsCount" : 1, // old value: 3,
|
"pathfinderBucketsCount" : 4, // old value: 3,
|
||||||
"pathfinderBucketSize" : 32, // old value: 7,
|
"pathfinderBucketSize" : 8, // old value: 7,
|
||||||
"retreatThresholdRelative" : 0.3,
|
"retreatThresholdRelative" : 0.3,
|
||||||
"retreatThresholdAbsolute" : 10000,
|
"retreatThresholdAbsolute" : 10000,
|
||||||
"safeAttackRatio" : 1.1,
|
"safeAttackRatio" : 1.1,
|
||||||
|
Reference in New Issue
Block a user