From 1210f0bf9936a6e6e435bc77a63c911b5f952414 Mon Sep 17 00:00:00 2001 From: kdmcser Date: Sat, 26 Apr 2025 23:47:24 +0800 Subject: [PATCH 1/2] fix hang in AI's turn --- AI/Nullkiller/AIGateway.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/AI/Nullkiller/AIGateway.cpp b/AI/Nullkiller/AIGateway.cpp index 0e8a62395..9d5847dd1 100644 --- a/AI/Nullkiller/AIGateway.cpp +++ b/AI/Nullkiller/AIGateway.cpp @@ -1039,6 +1039,8 @@ void AIGateway::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance auto equipBest = [](const CGHeroInstance * h, const CGHeroInstance * otherh, bool giveStuffToFirstHero) -> void { bool changeMade = false; + int swapCount = 0; + const int maxSwapCount = 100; do { changeMade = false; @@ -1100,6 +1102,7 @@ void AIGateway::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance cb->swapArtifacts(location, destLocation); //just put into empty slot emptySlotFound = true; changeMade = true; + swapCount++; break; } } @@ -1138,6 +1141,7 @@ void AIGateway::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance } changeMade = true; + swapCount++; break; } } @@ -1147,7 +1151,9 @@ void AIGateway::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance break; //start evaluating artifacts from scratch } } - while(changeMade); + while(changeMade && swapCount < maxSwapCount); + if (swapCount >= maxSwapCount) + logAi->warn("Maximum artifact swap count exceeded!"); }; equipBest(h, other, true); From 9dc07b00ff2d0014353b142dc2a80c1101298a5a Mon Sep 17 00:00:00 2001 From: kdmcser Date: Sun, 27 Apr 2025 00:34:44 +0800 Subject: [PATCH 2/2] record swap info, if A swap to B,not allow A <-> B in both side --- AI/Nullkiller/AIGateway.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/AI/Nullkiller/AIGateway.cpp b/AI/Nullkiller/AIGateway.cpp index 9d5847dd1..f75ef4bdd 100644 --- a/AI/Nullkiller/AIGateway.cpp +++ b/AI/Nullkiller/AIGateway.cpp @@ -1039,8 +1039,7 @@ void AIGateway::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance auto equipBest = [](const CGHeroInstance * h, const CGHeroInstance * otherh, bool giveStuffToFirstHero) -> void { bool changeMade = false; - int swapCount = 0; - const int maxSwapCount = 100; + std::set > swappedSet; do { changeMade = false; @@ -1102,7 +1101,6 @@ void AIGateway::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance cb->swapArtifacts(location, destLocation); //just put into empty slot emptySlotFound = true; changeMade = true; - swapCount++; break; } } @@ -1122,6 +1120,15 @@ void AIGateway::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance //combined artifacts are not always allowed to move if(artifactScore > otherArtifactScore && artifact->canBePutAt(target, slot, true)) { + auto swapPair = std::minmax(artifact, otherSlot->artifact); + if (swappedSet.find(swapPair) != swappedSet.end()) + { + logAi->warn( + "Artifacts % s < -> % s have already swapped before, ignored.", + artifact->getType()->getJsonKey(), + otherSlot->artifact->getType()->getJsonKey()); + continue; + } logAi->trace( "Exchange artifacts %s <-> %s", artifact->getType()->getJsonKey(), @@ -1141,7 +1148,7 @@ void AIGateway::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance } changeMade = true; - swapCount++; + swappedSet.insert(swapPair); break; } } @@ -1151,9 +1158,7 @@ void AIGateway::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance break; //start evaluating artifacts from scratch } } - while(changeMade && swapCount < maxSwapCount); - if (swapCount >= maxSwapCount) - logAi->warn("Maximum artifact swap count exceeded!"); + while(changeMade); }; equipBest(h, other, true);