Sfoglia il codice sorgente

Move pathfinder bucket parameters to nkai-settings

Ivan Savenko 10 mesi fa
parent
commit
18f5d5bc70

+ 13 - 44
AI/Nullkiller/Engine/Settings.cpp

@@ -28,6 +28,8 @@ namespace NKAI
 		scoutHeroTurnDistanceLimit(5),
 		maxGoldPressure(0.3f), 
 		maxpass(10),
+		pathfinderBucketsCount(1),
+		pathfinderBucketSize(32),
 		allowObjectGraph(true),
 		useTroopsFromGarrisons(false),
 		openMap(true),
@@ -35,49 +37,16 @@ namespace NKAI
 	{
 		JsonNode node = JsonUtils::assembleFromFiles("config/ai/nkai/nkai-settings");
 
-		if(node.Struct()["maxRoamingHeroes"].isNumber())
-		{
-			maxRoamingHeroes = node.Struct()["maxRoamingHeroes"].Integer();
-		}
-
-		if(node.Struct()["mainHeroTurnDistanceLimit"].isNumber())
-		{
-			mainHeroTurnDistanceLimit = node.Struct()["mainHeroTurnDistanceLimit"].Integer();
-		}
-
-		if(node.Struct()["scoutHeroTurnDistanceLimit"].isNumber())
-		{
-			scoutHeroTurnDistanceLimit = node.Struct()["scoutHeroTurnDistanceLimit"].Integer();
-		}
-
-		if(node.Struct()["maxpass"].isNumber())
-		{
-			maxpass = node.Struct()["maxpass"].Integer();
-		}
-
-		if(node.Struct()["maxGoldPressure"].isNumber())
-		{
-			maxGoldPressure = node.Struct()["maxGoldPressure"].Float();
-		}
-
-		if(!node.Struct()["allowObjectGraph"].isNull())
-		{
-			allowObjectGraph = node.Struct()["allowObjectGraph"].Bool();
-		}
-
-		if(!node.Struct()["openMap"].isNull())
-		{
-			openMap = node.Struct()["openMap"].Bool();
-		}
-
-		if (!node.Struct()["useFuzzy"].isNull())
-		{
-			useFuzzy = node.Struct()["useFuzzy"].Bool();
-		}
-
-		if(!node.Struct()["useTroopsFromGarrisons"].isNull())
-		{
-			useTroopsFromGarrisons = node.Struct()["useTroopsFromGarrisons"].Bool();
-		}
+		maxRoamingHeroes = node["maxRoamingHeroes"].Integer();
+		mainHeroTurnDistanceLimit = node["mainHeroTurnDistanceLimit"].Integer();
+		scoutHeroTurnDistanceLimit = node["scoutHeroTurnDistanceLimit"].Integer();
+		maxpass = node["maxpass"].Integer();
+		pathfinderBucketsCount = node["pathfinderBucketsCount"].Integer();
+		pathfinderBucketSize = node["pathfinderBucketSize"].Integer();
+		maxGoldPressure = node["maxGoldPressure"].Float();
+		allowObjectGraph = node["allowObjectGraph"].Bool();
+		openMap = node["openMap"].Bool();
+		useFuzzy = node["useFuzzy"].Bool();
+		useTroopsFromGarrisons = node["useTroopsFromGarrisons"].Bool();
 	}
 }

+ 4 - 0
AI/Nullkiller/Engine/Settings.h

@@ -25,6 +25,8 @@ namespace NKAI
 		int mainHeroTurnDistanceLimit;
 		int scoutHeroTurnDistanceLimit;
 		int maxpass;
+		int pathfinderBucketsCount;
+		int pathfinderBucketSize;
 		float maxGoldPressure;
 		bool allowObjectGraph;
 		bool useTroopsFromGarrisons;
@@ -39,6 +41,8 @@ namespace NKAI
 		int getMaxRoamingHeroes() const { return maxRoamingHeroes; }
 		int getMainHeroTurnDistanceLimit() const { return mainHeroTurnDistanceLimit; }
 		int getScoutHeroTurnDistanceLimit() const { return scoutHeroTurnDistanceLimit; }
+		int getPathfinderBucketsCount() const { return pathfinderBucketsCount; }
+		int getPathfinderBucketSize() const { return pathfinderBucketSize; }
 		bool isObjectGraphAllowed() const { return allowObjectGraph; }
 		bool isGarrisonTroopsUsageAllowed() const { return useTroopsFromGarrisons; }
 		bool isOpenMap() const { return openMap; }

+ 19 - 9
AI/Nullkiller/Pathfinding/AINodeStorage.cpp

@@ -39,17 +39,17 @@ const uint64_t CHAIN_MAX_DEPTH = 4;
 
 const bool DO_NOT_SAVE_TO_COMMITTED_TILES = false;
 
-AISharedStorage::AISharedStorage(int3 sizes)
+AISharedStorage::AISharedStorage(int3 sizes, int numChains)
 {
 	if(!shared){
 		shared.reset(new boost::multi_array<AIPathNode, 4>(
-			boost::extents[sizes.z][sizes.x][sizes.y][AIPathfinding::NUM_CHAINS]));
+			boost::extents[sizes.z][sizes.x][sizes.y][numChains]));
 
 		nodes = shared;
 
 		foreach_tile_pos([&](const int3 & pos)
 			{
-				for(auto i = 0; i < AIPathfinding::NUM_CHAINS; i++)
+				for(auto i = 0; i < numChains; i++)
 				{
 					auto & node = get(pos)[i];
 						
@@ -92,8 +92,18 @@ void AIPathNode::addSpecialAction(std::shared_ptr<const SpecialAction> action)
 	}
 }
 
+int AINodeStorage::getBucketCount() const
+{
+	return ai->settings->getPathfinderBucketsCount();
+}
+
+int AINodeStorage::getBucketSize() const
+{
+	return ai->settings->getPathfinderBucketSize();
+}
+
 AINodeStorage::AINodeStorage(const Nullkiller * ai, const int3 & Sizes)
-	: sizes(Sizes), ai(ai), cb(ai->cb.get()), nodes(Sizes)
+	: sizes(Sizes), ai(ai), cb(ai->cb.get()), nodes(Sizes, ai->settings->getPathfinderBucketSize() * ai->settings->getPathfinderBucketsCount())
 {
 	accessibility = std::make_unique<boost::multi_array<EPathAccessibility, 4>>(
 		boost::extents[sizes.z][sizes.x][sizes.y][EPathfindingLayer::NUM_LAYERS]);
@@ -169,8 +179,8 @@ std::optional<AIPathNode *> AINodeStorage::getOrCreateNode(
 	const EPathfindingLayer layer, 
 	const ChainActor * actor)
 {
-	int bucketIndex = ((uintptr_t)actor + static_cast<uint32_t>(layer)) % AIPathfinding::BUCKET_COUNT;
-	int bucketOffset = bucketIndex * AIPathfinding::BUCKET_SIZE;
+	int bucketIndex = ((uintptr_t)actor + static_cast<uint32_t>(layer)) % ai->settings->getPathfinderBucketsCount();
+	int bucketOffset = bucketIndex * ai->settings->getPathfinderBucketSize();
 	auto chains = nodes.get(pos);
 
 	if(blocked(pos, layer))
@@ -178,7 +188,7 @@ std::optional<AIPathNode *> AINodeStorage::getOrCreateNode(
 		return std::nullopt;
 	}
 
-	for(auto i = AIPathfinding::BUCKET_SIZE - 1; i >= 0; i--)
+	for(auto i = ai->settings->getPathfinderBucketSize() - 1; i >= 0; i--)
 	{
 		AIPathNode & node = chains[i + bucketOffset];
 
@@ -486,8 +496,8 @@ public:
 		AINodeStorage & storage, const std::vector<int3> & tiles, uint64_t chainMask, int heroChainTurn)
 		:existingChains(), newChains(), delayedWork(), storage(storage), chainMask(chainMask), heroChainTurn(heroChainTurn), heroChain(), tiles(tiles)
 	{
-		existingChains.reserve(AIPathfinding::NUM_CHAINS);
-		newChains.reserve(AIPathfinding::NUM_CHAINS);
+		existingChains.reserve(storage.getBucketCount() * storage.getBucketSize());
+		newChains.reserve(storage.getBucketCount() * storage.getBucketSize());
 	}
 
 	void execute(const tbb::blocked_range<size_t>& r)

+ 5 - 5
AI/Nullkiller/Pathfinding/AINodeStorage.h

@@ -29,9 +29,6 @@ namespace NKAI
 {
 namespace AIPathfinding
 {
-	const int BUCKET_COUNT = 1;
-	const int BUCKET_SIZE = 32;
-	const int NUM_CHAINS = BUCKET_COUNT * BUCKET_SIZE;
 	const int CHAIN_MAX_DEPTH = 4;
 }
 
@@ -157,7 +154,7 @@ public:
 	static boost::mutex locker;
 	static uint32_t version;
 
-	AISharedStorage(int3 mapSize);
+	AISharedStorage(int3 sizes, int numChains);
 	~AISharedStorage();
 
 	STRONG_INLINE
@@ -197,6 +194,9 @@ public:
 	bool selectFirstActor();
 	bool selectNextActor();
 
+	int getBucketCount() const;
+	int getBucketSize() const;
+
 	std::vector<CGPathNode *> getInitialNodes() override;
 
 	virtual void calculateNeighbours(
@@ -298,7 +298,7 @@ public:
 
 	inline int getBucket(const ChainActor * actor) const
 	{
-		return ((uintptr_t)actor * 395) % AIPathfinding::BUCKET_COUNT;
+		return ((uintptr_t)actor * 395) % getBucketCount();
 	}
 
 	void calculateTownPortalTeleportations(std::vector<CGPathNode *> & neighbours);

+ 3 - 0
config/ai/nkai/nkai-settings.json

@@ -7,4 +7,7 @@
 	"useTroopsFromGarrisons" : true,
 	"openMap": true,
 	"allowObjectGraph": false
+	"pathfinderBucketsCount" : 1, // old value: 3,
+	"pathfinderBucketSize" : 32 // old value: 7,
+	"useFuzzy" : false
 }