Преглед изворни кода

Nullkiller: improved citadel priority

Andrii Danylchenko пре 4 година
родитељ
комит
0d5ae20e64

+ 31 - 5
AI/Nullkiller/Analyzers/BuildAnalyzer.cpp

@@ -10,6 +10,7 @@
 #include "../StdInc.h"
 #include "../Engine/Nullkiller.h"
 #include "../../../lib/mapping/CMap.h" //for victory conditions
+#include "../Engine/Nullkiller.h"
 
 extern boost::thread_specific_ptr<CCallback> cb;
 
@@ -172,7 +173,7 @@ void BuildAnalyzer::reset()
 }
 
 BuildingInfo BuildAnalyzer::getBuildingOrPrerequisite(
-	const CGTownInstance* town,
+	const CGTownInstance * town,
 	BuildingID toBuild,
 	bool excludeDwellingDependencies) const
 {
@@ -193,7 +194,7 @@ BuildingInfo BuildAnalyzer::getBuildingOrPrerequisite(
 		creature = creatureID.toCreature();
 	}
 
-	auto info = BuildingInfo(buildPtr, creature, baseCreatureID);
+	auto info = BuildingInfo(buildPtr, creature, baseCreatureID, town, ai);
 
 	logAi->trace("checking %s", buildPtr->Name());
 	logAi->trace("buildInfo %s", info.toString());
@@ -298,6 +299,7 @@ void TownDevelopmentInfo::addExistingDwelling(const BuildingInfo & existingDwell
 	existingDwellings.push_back(existingDwelling);
 
 	armyCost += existingDwelling.creatureCost * existingDwelling.creatureGrows;
+	armyStrength += existingDwelling.armyStrength;
 }
 
 void TownDevelopmentInfo::addBuildingToBuild(const BuildingInfo & nextToBuild)
@@ -325,17 +327,22 @@ BuildingInfo::BuildingInfo()
 	buildCostWithPrerequisits = 0;
 	prerequisitesCount = 0;
 	name = "";
+	armyStrength = 0;
 }
 
-BuildingInfo::BuildingInfo(const CBuilding * building, const CCreature * creature, CreatureID baseCreature)
+BuildingInfo::BuildingInfo(
+	const CBuilding * building,
+	const CCreature * creature,
+	CreatureID baseCreature,
+	const CGTownInstance * town,
+	Nullkiller * ai)
 {
 	id = building->bid;
 	buildCost = building->resources;
 	buildCostWithPrerequisits = building->resources;
 	dailyIncome = building->produce;
-	exists = false;;
+	exists = town->hasBuilt(id);
 	prerequisitesCount = 1;
-	name = building->Name();
 
 	if(creature)
 	{
@@ -344,6 +351,23 @@ BuildingInfo::BuildingInfo(const CBuilding * building, const CCreature * creatur
 		creatureCost = creature->cost;
 		creatureLevel = creature->level;
 		baseCreatureID = baseCreature;
+
+		if(exists)
+		{
+			creatureGrows = town->creatureGrowth(creatureID);
+		}
+		else
+		{
+			creatureGrows = creature->growth;
+
+			if(town->hasBuilt(BuildingID::CASTLE))
+				creatureGrows *= 2;
+			else if(town->hasBuilt(BuildingID::CITADEL))
+				creatureGrows += creatureGrows / 2;
+		}
+
+		armyStrength = ai->armyManager->evaluateStackPower(creature, creatureGrows);
+		armyCost = creatureCost * creatureGrows;
 	}
 	else
 	{
@@ -351,7 +375,9 @@ BuildingInfo::BuildingInfo(const CBuilding * building, const CCreature * creatur
 		creatureID = CreatureID::NONE;
 		baseCreatureID = CreatureID::NONE;
 		creatureCost = TResources();
+		armyCost = TResources();
 		creatureLevel = 0;
+		armyStrength = 0;
 	}
 }
 

+ 13 - 4
AI/Nullkiller/Analyzers/BuildAnalyzer.h

@@ -12,6 +12,7 @@
 #include "../AIUtility.h"
 #include "../../../lib/ResourceSet.h"
 
+class Nullkiller;
 
 class DLL_EXPORT BuildingInfo
 {
@@ -26,6 +27,8 @@ public:
 	CreatureID baseCreatureID;
 	TResources dailyIncome;
 	uint8_t prerequisitesCount;
+	uint64_t armyStrength;
+	TResources armyCost;
 	std::string name;
 	bool exists = false;
 	bool canBuild = false;
@@ -33,7 +36,12 @@ public:
 
 	BuildingInfo();
 
-	BuildingInfo(const CBuilding* building, const CCreature* creature, CreatureID baseCreatureID);
+	BuildingInfo(
+		const CBuilding * building,
+		const CCreature * creature,
+		CreatureID baseCreature,
+		const CGTownInstance * town,
+		Nullkiller * ai);
 
 	std::string toString() const;
 };
@@ -47,13 +55,12 @@ public:
 	TResources townDevelopmentCost;
 	TResources requiredResources;
 	TResources armyCost;
-	int armyScore;
-	int economicsScore;
+	uint64_t armyStrength;
 	HeroRole townRole;
 	bool hasSomethingToBuild;
 
 	TownDevelopmentInfo(const CGTownInstance* town)
-		:town(town), armyScore(0), economicsScore(0), toBuild(), townDevelopmentCost(), requiredResources(), townRole(HeroRole::SCOUT), hasSomethingToBuild(false)
+		:town(town), armyStrength(0), toBuild(), townDevelopmentCost(), requiredResources(), townRole(HeroRole::SCOUT), hasSomethingToBuild(false)
 	{
 	}
 
@@ -72,8 +79,10 @@ private:
 	TResources armyCost;
 	TResources dailyIncome;
 	float goldPreasure;
+	Nullkiller * ai;
 
 public:
+	BuildAnalyzer(Nullkiller * ai) : ai(ai) {}
 	void update();
 
 	TResources getResourcesRequiredNow() const;

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

@@ -603,7 +603,7 @@ public:
 		evaluationContext.goldReward += 7 * bi.dailyIncome[Res::GOLD] / 2; // 7 day income but half we already have
 		evaluationContext.heroRole = HeroRole::MAIN;
 		evaluationContext.movementCostByRole[evaluationContext.heroRole] += bi.prerequisitesCount;
-		evaluationContext.strategicalValue += buildThis.townInfo.armyScore / 50000.0;
+		evaluationContext.strategicalValue += buildThis.townInfo.armyStrength / 50000.0;
 		evaluationContext.goldCost += bi.buildCostWithPrerequisits[Res::GOLD];
 
 		if(bi.creatureID != CreatureID::NONE)
@@ -611,7 +611,7 @@ public:
 			if(bi.baseCreatureID == bi.creatureID)
 			{
 				evaluationContext.strategicalValue += 0.5f + 0.1f * bi.creatureLevel / (float)bi.prerequisitesCount;
-				evaluationContext.armyReward += evaluationContext.evaluator.ai->armyManager->evaluateStackPower(bi.creatureID.toCreature(), bi.creatureGrows);
+				evaluationContext.armyReward += bi.armyStrength;
 			}
 			else
 			{
@@ -619,6 +619,11 @@ public:
 				evaluationContext.armyReward += evaluationContext.evaluator.getUpgradeArmyReward(buildThis.town, bi);
 			}
 		}
+		else if(bi.id == BuildingID::CITADEL || bi.id == BuildingID::CASTLE)
+		{
+			evaluationContext.strategicalValue += buildThis.town->creatures.size() * 0.2f;
+			evaluationContext.armyReward += buildThis.townInfo.armyStrength / 2;
+		}
 		else
 		{
 			evaluationContext.strategicalValue += evaluationContext.evaluator.ai->buildAnalyzer->getGoldPreasure() * evaluationContext.goldReward / 2200.0f;