Quellcode durchsuchen

Nullkiller: stabilization

Andrii Danylchenko vor 4 Jahren
Ursprung
Commit
37f49f2ac5

+ 11 - 0
AI/Nullkiller/Analyzers/BuildAnalyzer.cpp

@@ -283,6 +283,17 @@ void BuildAnalyzer::updateDailyIncome()
 	}
 }
 
+bool BuildAnalyzer::hasAnyBuilding(int32_t alignment, BuildingID bid) const
+{
+	for(auto tdi : developmentInfos)
+	{
+		if(tdi.town->alignment == alignment && tdi.town->hasBuilt(bid))
+			return true;
+	}
+
+	return false;
+}
+
 void TownDevelopmentInfo::addExistingDwelling(const BuildingInfo & existingDwelling)
 {
 	existingDwellings.push_back(existingDwelling);

+ 1 - 0
AI/Nullkiller/Analyzers/BuildAnalyzer.h

@@ -81,6 +81,7 @@ public:
 	const std::vector<TownDevelopmentInfo> & getDevelopmentInfo() const { return developmentInfos; }
 	TResources getDailyIncome() const { return dailyIncome; }
 	float getGoldPreasure() const { return goldPreasure; }
+	bool hasAnyBuilding(int32_t alignment, BuildingID bid) const;
 
 private:
 	BuildingInfo getBuildingOrPrerequisite(

+ 5 - 0
AI/Nullkiller/Analyzers/ObjectClusterizer.cpp

@@ -72,6 +72,11 @@ std::vector<const CGObjectInstance *> ObjectClusterizer::getNearbyObjects() cons
 	return nearObjects.getObjects();
 }
 
+std::vector<const CGObjectInstance *> ObjectClusterizer::getFarObjects() const
+{
+	return farObjects.getObjects();
+}
+
 std::vector<std::shared_ptr<ObjectCluster>> ObjectClusterizer::getLockedClusters() const
 {
 	std::vector<std::shared_ptr<ObjectCluster>> result;

+ 1 - 0
AI/Nullkiller/Analyzers/ObjectClusterizer.h

@@ -55,6 +55,7 @@ private:
 public:
 	void clusterize();
 	std::vector<const CGObjectInstance *> getNearbyObjects() const;
+	std::vector<const CGObjectInstance *> getFarObjects() const;
 	std::vector<std::shared_ptr<ObjectCluster>> getLockedClusters() const;
 	const CGObjectInstance * getBlocker(const AIPath & path) const;
 

+ 8 - 5
AI/Nullkiller/Behaviors/CaptureObjectsBehavior.cpp

@@ -178,6 +178,11 @@ Goals::TGoalVec CaptureObjectsBehavior::decompose() const
 #endif
 			vstd::concatenate(tasks, getVisitGoals(paths, objToVisit));
 		}
+
+		vstd::erase_if(tasks, [](TSubgoal task) -> bool
+		{
+			return task->invalid();
+		});
 	};
 
 	if(specificObjects)
@@ -187,12 +192,10 @@ Goals::TGoalVec CaptureObjectsBehavior::decompose() const
 	else
 	{
 		captureObjects(ai->nullkiller->objectClusterizer->getNearbyObjects());
-	}
 
-	vstd::erase_if(tasks, [](TSubgoal task) -> bool
-	{
-		return task->invalid();
-	});
+		if(tasks.empty())
+			captureObjects(ai->nullkiller->objectClusterizer->getFarObjects());
+	}
 
 	return tasks;
 }

+ 8 - 3
AI/Nullkiller/Behaviors/StartupBehavior.cpp

@@ -73,7 +73,9 @@ bool needToRecruitHero(const CGTownInstance * startupTown)
 	auto heroToCheck = startupTown->garrisonHero ? startupTown->garrisonHero.get() : startupTown->visitingHero.get();
 	auto paths = cb->getPathsInfo(heroToCheck);
 
-	for(auto obj : ai->visitableObjs)
+	int treasureSourcesCount = 0;
+
+	for(auto obj : ai->nullkiller->objectClusterizer->getNearbyObjects())
 	{
 		if(obj->ID == Obj::RESOURCE && obj->subID == Res::GOLD
 			|| obj->ID == Obj::TREASURE_CHEST
@@ -84,12 +86,15 @@ bool needToRecruitHero(const CGTownInstance * startupTown)
 			if((path->accessible == CGPathNode::BLOCKVIS || path->accessible == CGPathNode::VISIT) 
 				&& path->reachable())
 			{
-				return true;
+				treasureSourcesCount++;
 			}
 		}
 	}
 
-	return false;
+	auto basicCount = cb->getTownsInfo().size() + 2;
+	auto boost = (int)std::floor(std::pow(treasureSourcesCount / 3.0, 2));
+
+	return cb->getHeroCount(ai->playerID, true) < basicCount + boost;
 }
 
 Goals::TGoalVec StartupBehavior::decompose() const

+ 7 - 4
AI/Nullkiller/Engine/PriorityEvaluator.cpp

@@ -530,6 +530,8 @@ public:
 			evaluationContext.movementCostByRole[role] += objInfo.second.movementCost / boost;
 			evaluationContext.movementCost += objInfo.second.movementCost / boost;
 
+			vstd::amax(evaluationContext.turn, objInfo.second.turn / boost);
+
 			boost <<= 1;
 
 			if(boost > 8)
@@ -538,7 +540,6 @@ public:
 
 		const AIPath & pathToCenter = clusterGoal.getPathToCenter();
 
-		vstd::amax(evaluationContext.turn, pathToCenter.turn());
 	}
 };
 
@@ -561,10 +562,9 @@ public:
 
 		if(bi.creatureID != CreatureID::NONE)
 		{
-			evaluationContext.strategicalValue += (0.5f + 0.1f * bi.creatureLevel) / (float)bi.prerequisitesCount;
-
 			if(bi.baseCreatureID == bi.creatureID)
 			{
+				evaluationContext.strategicalValue += 0.5f + 0.1f * bi.creatureLevel / (float)bi.prerequisitesCount;
 				evaluationContext.armyReward += ai->ah->evaluateStackPower(bi.creatureID.toCreature(), bi.creatureGrows);
 			}
 			else
@@ -572,7 +572,10 @@ public:
 				auto creaturesToUpgrade = ai->ah->getTotalCreaturesAvailable(bi.baseCreatureID);
 				auto upgradedPower = ai->ah->evaluateStackPower(bi.creatureID.toCreature(), creaturesToUpgrade.count);
 
-				evaluationContext.armyReward += upgradedPower - creaturesToUpgrade.power;
+				evaluationContext.strategicalValue += 0.05f * bi.creatureLevel / (float)bi.prerequisitesCount;
+
+				if(!ai->nullkiller->buildAnalyzer->hasAnyBuilding(buildThis.town->alignment, bi.id))
+					evaluationContext.armyReward += upgradedPower - creaturesToUpgrade.power;
 			}
 		}
 		else

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

@@ -11,7 +11,7 @@
 #pragma once
 
 #define PATHFINDER_TRACE_LEVEL 0
-#define AI_TRACE_LEVEL 1
+#define AI_TRACE_LEVEL 1	
 
 #include "../../../lib/CPathfinder.h"
 #include "../../../lib/mapObjects/CGHeroInstance.h"