Browse Source

BuildAnalyzer.cpp cleanup and renaming

Mircea TheHonestCTO 3 months ago
parent
commit
6eb7bb2ca5

+ 35 - 63
AI/Nullkiller2/Analyzers/BuildAnalyzer.cpp

@@ -9,8 +9,6 @@
 */
 #include <boost/range/algorithm/sort.hpp>
 
-#include "../StdInc.h"
-#include "../Engine/Nullkiller.h"
 #include "../Engine/Nullkiller.h"
 #include "../../../lib/entities/building/CBuilding.h"
 #include "../../../lib/IGameSettings.h"
@@ -43,12 +41,11 @@ bool BuildAnalyzer::isGoldPressureOverMax() const
 void BuildAnalyzer::update()
 {
 	logAi->trace("Start BuildAnalyzer::update");
-	BuildingInfo bi;
 	reset();
-	auto towns = aiNk->cbc->getTownsInfo();
+	const auto towns = aiNk->cbc->getTownsInfo();
 	float economyDevelopmentCost = 0;
 
-	for(const CGTownInstance* town : towns)
+	for(const CGTownInstance * town : towns)
 	{
 		if(town->built >= cbcTl->getSettings().getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP))
 			continue; // Not much point in trying anything - can't built in this town anymore today
@@ -60,7 +57,7 @@ void BuildAnalyzer::update()
 		developmentInfos.push_back(TownDevelopmentInfo(town));
 		TownDevelopmentInfo & tdi = developmentInfos.back();
 
-		updateTownDwellings(tdi, aiNk->armyManager, aiNk->cbc);
+		updateCreatureBuildings(tdi, aiNk->armyManager, aiNk->cbc);
 		updateOtherBuildings(tdi, aiNk->armyManager, aiNk->cbc);
 		requiredResources += tdi.requiredResources;
 		totalDevelopmentCost += tdi.townDevelopmentCost;
@@ -74,8 +71,8 @@ void BuildAnalyzer::update()
 		armyCost += tdi.armyCost;
 
 #if NKAI_TRACE_LEVEL >= 1
-		for(const auto & bi : tdi.toBuild)
-			logAi->trace("Building preferences %s", bi.toString());
+		for(const auto & biToBuild : tdi.toBuild)
+			logAi->trace("Building preferences %s", biToBuild.toString());
 #endif
 	}
 
@@ -88,10 +85,10 @@ void BuildAnalyzer::update()
 
 	dailyIncome = calculateDailyIncome(aiNk->cbc->getMyObjects(), aiNk->cbc->getTownsInfo());
 	goldPressure = calculateGoldPressure(aiNk->getLockedResources()[EGameResID::GOLD],
-	                                     (float)armyCost[EGameResID::GOLD],
+	                                     static_cast<float>(armyCost[EGameResID::GOLD]),
 	                                     economyDevelopmentCost,
 	                                     aiNk->getFreeGold(),
-	                                     (float)dailyIncome[EGameResID::GOLD]);
+	                                     static_cast<float>(dailyIncome[EGameResID::GOLD]));
 }
 
 void BuildAnalyzer::reset()
@@ -104,7 +101,7 @@ void BuildAnalyzer::reset()
 
 bool BuildAnalyzer::isBuilt(FactionID alignment, BuildingID bid) const
 {
-	for(auto tdi : developmentInfos)
+	for(const auto & tdi : developmentInfos)
 	{
 		if(tdi.town->getFactionID() == alignment && tdi.town->hasBuilt(bid))
 			return true;
@@ -113,44 +110,28 @@ bool BuildAnalyzer::isBuilt(FactionID alignment, BuildingID bid) const
 	return false;
 }
 
-void TownDevelopmentInfo::addExistingDwelling(const BuildingInfo & existingDwelling)
+void TownDevelopmentInfo::addExistingDwelling(const BuildingInfo & bi)
 {
-	existingDwellings.push_back(existingDwelling);
-
-	armyCost += existingDwelling.armyCost;
-	armyStrength += existingDwelling.armyStrength;
+	armyCost += bi.armyCost;
+	armyStrength += bi.armyStrength;
+	built.push_back(bi);
 }
 
-void TownDevelopmentInfo::addBuildingToBuild(const BuildingInfo & nextToBuild)
+void TownDevelopmentInfo::addBuildingToBuild(const BuildingInfo & bi)
 {
-	townDevelopmentCost += nextToBuild.buildCostWithPrerequisites;
-	townDevelopmentCost += BuildAnalyzer::withoutGold(nextToBuild.armyCost);
+	townDevelopmentCost += bi.buildCostWithPrerequisites;
+	townDevelopmentCost += BuildAnalyzer::withoutGold(bi.armyCost);
 
-	if(nextToBuild.canBuild)
-	{
-		hasSomethingToBuild = true;
-		toBuild.push_back(nextToBuild);
-	}
-	else if(nextToBuild.notEnoughRes)
+	if(!bi.isBuildable && bi.isMissingResources)
 	{
-		requiredResources += nextToBuild.buildCost;
-		hasSomethingToBuild = true;
-		toBuild.push_back(nextToBuild);
+		requiredResources += bi.buildCost;
 	}
-}
 
-BuildingInfo::BuildingInfo()
-{
-	id = BuildingID::NONE;
-	creatureGrows = 0;
-	creatureID = CreatureID::NONE;
-	buildCost = 0;
-	buildCostWithPrerequisites = 0;
-	prerequisitesCount = 0;
-	name.clear();
-	armyStrength = 0;
+	toBuild.push_back(bi);
 }
 
+BuildingInfo::BuildingInfo() {}
+
 BuildingInfo::BuildingInfo(
 	const CBuilding * building,
 	const CCreature * creature,
@@ -162,7 +143,7 @@ BuildingInfo::BuildingInfo(
 	buildCost = building->resources;
 	buildCostWithPrerequisites = building->resources;
 	dailyIncome = building->produce;
-	exists = town->hasBuilt(id);
+	isBuilt = town->hasBuilt(id);
 	prerequisitesCount = 1;
 	name = building->getNameTranslated();
 
@@ -170,11 +151,11 @@ BuildingInfo::BuildingInfo(
 	{
 		creatureGrows = creature->getGrowth();
 		creatureID = creature->getId();
+		baseCreatureID = baseCreature;
 		creatureCost = creature->getFullRecruitCost();
 		creatureLevel = creature->getLevel();
-		baseCreatureID = baseCreature;
 
-		if(exists)
+		if(isBuilt)
 		{
 			creatureGrows = town->creatureGrowth(creatureLevel - 1);
 		}
@@ -198,16 +179,6 @@ BuildingInfo::BuildingInfo(
 		armyStrength = armyManager->evaluateStackPower(creature, creatureGrows);
 		armyCost = creatureCost * creatureGrows;
 	}
-	else
-	{
-		creatureGrows = 0;
-		creatureID = CreatureID::NONE;
-		baseCreatureID = CreatureID::NONE;
-		creatureCost = TResources();
-		armyCost = TResources();
-		creatureLevel = 0;
-		armyStrength = 0;
-	}
 }
 
 std::string BuildingInfo::toString() const
@@ -229,13 +200,13 @@ float BuildAnalyzer::calculateGoldPressure(TResource lockedGold, float armyCostG
 	return pressure;
 }
 
-TResources BuildAnalyzer::calculateDailyIncome(std::vector<const CGObjectInstance *> objects, std::vector<const CGTownInstance *> townInfos)
+TResources BuildAnalyzer::calculateDailyIncome(const std::vector<const CGObjectInstance *> & objects, const std::vector<const CGTownInstance *> & townInfos)
 {
 	auto result = TResources();
 
 	for(const CGObjectInstance * obj : objects)
 	{
-		if(const CGMine * mine = dynamic_cast<const CGMine *>(obj))
+		if(const auto * mine = dynamic_cast<const CGMine *>(obj))
 			result += mine->dailyIncome();
 	}
 
@@ -247,7 +218,7 @@ TResources BuildAnalyzer::calculateDailyIncome(std::vector<const CGObjectInstanc
 	return result;
 }
 
-void BuildAnalyzer::updateTownDwellings(TownDevelopmentInfo & developmentInfo, std::unique_ptr<ArmyManager> & armyManager, std::shared_ptr<CCallback> & cb)
+void BuildAnalyzer::updateCreatureBuildings(TownDevelopmentInfo & developmentInfo, std::unique_ptr<ArmyManager> & armyManager, std::shared_ptr<CCallback> & cb)
 {
 	for(int level = 0; level < developmentInfo.town->getTown()->creatures.size(); level++)
 	{
@@ -278,7 +249,7 @@ void BuildAnalyzer::updateTownDwellings(TownDevelopmentInfo & developmentInfo, s
 				continue;
 
 			const auto & info = getBuildingOrPrerequisite(developmentInfo.town, buildID, armyManager, cb);
-			if (info.canBuild || info.notEnoughRes)
+			if (info.isBuildable || info.isMissingResources)
 				developmentInfo.addBuildingToBuild(info);
 		}
 	}
@@ -295,7 +266,7 @@ void BuildAnalyzer::updateOtherBuildings(TownDevelopmentInfo & developmentInfo,
 		{BuildingID::MAGES_GUILD_3, BuildingID::MAGES_GUILD_5}
 	};
 
-	if(developmentInfo.existingDwellings.size() >= 2 && cb->getDate(Date::DAY_OF_WEEK) > 4)
+	if(developmentInfo.built.size() >= 2 && cb->getDate(Date::DAY_OF_WEEK) > 4)
 	{
 		otherBuildings.push_back({BuildingID::HORDE_1});
 		otherBuildings.push_back({BuildingID::HORDE_2});
@@ -330,7 +301,7 @@ BuildingInfo BuildAnalyzer::getBuildingOrPrerequisite(
 	bool excludeDwellingDependencies)
 {
 	BuildingID building = toBuild;
-	auto townInfo = town->getTown();
+	const auto * townInfo = town->getTown();
 
 	const auto & buildPtr = townInfo->buildings.at(building);
 	const CCreature * creature = nullptr;
@@ -369,9 +340,9 @@ BuildingInfo BuildAnalyzer::getBuildingOrPrerequisite(
 	//logAi->trace("checking %s buildInfo %s", info.name, info.toString());
 
 	int highestFort = 0;
-	for (auto ti : cb->getTownsInfo())
+	for (const auto * ti : cb->getTownsInfo())
 	{
-		highestFort = std::max(highestFort, (int)ti->fortLevel());
+		highestFort = std::max(highestFort, static_cast<int>(ti->fortLevel()));
 	}
 
 	if(!town->hasBuilt(building))
@@ -380,12 +351,12 @@ BuildingInfo BuildAnalyzer::getBuildingOrPrerequisite(
 
 		if(canBuild == EBuildingState::ALLOWED)
 		{
-			info.canBuild = true;
+			info.isBuildable = true;
 		}
 		else if(canBuild == EBuildingState::NO_RESOURCES)
 		{
 			//logAi->trace("cant build. Not enough resources. Need %s", info.buildCost.toString());
-			info.notEnoughRes = true;
+			info.isMissingResources = true;
 		}
 		else if(canBuild == EBuildingState::PREREQUIRES)
 		{
@@ -454,7 +425,7 @@ BuildingInfo BuildAnalyzer::getBuildingOrPrerequisite(
 #if NKAI_TRACE_LEVEL >= 1
 		logAi->trace("Dwelling %d exists", toBuild.getNum());
 #endif
-		info.exists = true;
+		info.isBuilt = true;
 	}
 
 	return info;
@@ -470,6 +441,7 @@ int32_t BuildAnalyzer::approximateInGold(const TResources & res)
 
 TResources BuildAnalyzer::withoutGold(TResources other)
 {
+	// TODO: Mircea: Potential issue modifying the input directly? To inspect
 	other[GameResID::GOLD] = 0;
 	return other;
 }

+ 18 - 28
AI/Nullkiller2/Analyzers/BuildAnalyzer.h

@@ -21,22 +21,22 @@ class Nullkiller;
 class DLL_EXPORT BuildingInfo
 {
 public:
-	BuildingID id;
+	BuildingID id = BuildingID::NONE;
 	TResources buildCost;
 	TResources buildCostWithPrerequisites;
-	int creatureGrows;
-	uint8_t creatureLevel;
+	int creatureGrows = 0;
+	uint8_t creatureLevel = 0;
 	TResources creatureCost;
-	CreatureID creatureID;
-	CreatureID baseCreatureID;
+	CreatureID creatureID = CreatureID::NONE;
+	CreatureID baseCreatureID = CreatureID::NONE;
 	TResources dailyIncome;
-	uint8_t prerequisitesCount;
-	uint64_t armyStrength;
+	uint8_t prerequisitesCount = 0;
+	uint64_t armyStrength = 0;
 	TResources armyCost;
 	std::string name;
-	bool exists = false;
-	bool canBuild = false;
-	bool notEnoughRes = false;
+	bool isBuilt = false;
+	bool isBuildable = false;
+	bool isMissingResources = false;
 
 	BuildingInfo();
 
@@ -55,41 +55,31 @@ class DLL_EXPORT TownDevelopmentInfo
 public:
 	const CGTownInstance* town;
 	std::vector<BuildingInfo> toBuild;
-	std::vector<BuildingInfo> existingDwellings;
+	std::vector<BuildingInfo> built;
 	TResources townDevelopmentCost;
 	TResources requiredResources;
 	TResources armyCost;
-	uint64_t armyStrength;
-	HeroRole townRole;
-	bool hasSomethingToBuild;
-
-	TownDevelopmentInfo(const CGTownInstance * town):
-		town(town),
-		armyStrength(0),
-		townRole(HeroRole::SCOUT),
-		hasSomethingToBuild(false)
-	{
-	}
+	uint64_t armyStrength = 0;
 
+	TownDevelopmentInfo(const CGTownInstance * town) : town(town) {}
 	TownDevelopmentInfo() : TownDevelopmentInfo(nullptr) {}
 
 	void addBuildingToBuild(const BuildingInfo & building);
-	void addExistingDwelling(const BuildingInfo & existingDwelling);
+	void addExistingDwelling(const BuildingInfo & bi);
 };
 
 class DLL_EXPORT BuildAnalyzer
 {
-private:
 	TResources requiredResources;
 	TResources totalDevelopmentCost;
 	std::vector<TownDevelopmentInfo> developmentInfos;
 	TResources armyCost;
 	TResources dailyIncome;
-	float goldPressure;
+	float goldPressure = 0;
 	Nullkiller * aiNk;
 
 public:
-	BuildAnalyzer(Nullkiller * ai) : aiNk(ai) {}
+	explicit BuildAnalyzer(Nullkiller * ai) : aiNk(ai) {}
 	void update();
 
 	TResources getResourcesRequiredNow() const;
@@ -103,8 +93,8 @@ public:
 	void reset();
 
 	static float calculateGoldPressure(TResource lockedGold, float armyCostGold, float economyDevelopmentCost, float freeGold, float dailyIncomeGold);
-	static TResources calculateDailyIncome(std::vector<const CGObjectInstance *> objects, std::vector<const CGTownInstance *> townInfos);
-	static void updateTownDwellings(TownDevelopmentInfo& developmentInfo, std::unique_ptr<ArmyManager>& armyManager, std::shared_ptr<CCallback>& cb);
+	static TResources calculateDailyIncome(const std::vector<const CGObjectInstance *> & objects, const std::vector<const CGTownInstance *> & townInfos);
+	static void updateCreatureBuildings(TownDevelopmentInfo& developmentInfo, std::unique_ptr<ArmyManager>& armyManager, std::shared_ptr<CCallback>& cb);
 	static void updateOtherBuildings(TownDevelopmentInfo& developmentInfo, std::unique_ptr<ArmyManager>& armyManager, std::shared_ptr<CCallback>& cb);
 	static BuildingInfo getBuildingOrPrerequisite(
 		const CGTownInstance* town,

+ 2 - 2
AI/Nullkiller2/Behaviors/BuildingBehavior.cpp

@@ -64,7 +64,7 @@ Goals::TGoalVec BuildingBehavior::decompose(const Nullkiller * aiNk) const
 		{
 			for (auto& buildingInfo : developmentInfo.toBuild)
 			{
-				if ( !buildingInfo.notEnoughRes && (buildingInfo.id == BuildingID::CITADEL || buildingInfo.id == BuildingID::CASTLE))
+				if ( !buildingInfo.isMissingResources && (buildingInfo.id == BuildingID::CITADEL || buildingInfo.id == BuildingID::CASTLE))
 				{
 					tasks.push_back(sptr(BuildThis(buildingInfo, developmentInfo)));
 					emergencyDefense = true;
@@ -78,7 +78,7 @@ Goals::TGoalVec BuildingBehavior::decompose(const Nullkiller * aiNk) const
 			{
 				if (isGoldPressureLow || buildingInfo.dailyIncome[EGameResID::GOLD] > 0)
 				{
-					if (buildingInfo.notEnoughRes)
+					if (buildingInfo.isMissingResources)
 					{
 						if (aiNk->getLockedResources().canAfford(buildingInfo.buildCost))
 							continue;

+ 1 - 1
AI/Nullkiller2/Engine/PriorityEvaluator.cpp

@@ -1256,7 +1256,7 @@ public:
 			evaluationContext.addNonCriticalStrategicalValue(evaluationContext.goldReward * goldPressure / 3500.0f / bi.prerequisitesCount);
 		}
 
-		if(bi.notEnoughRes && bi.prerequisitesCount == 1)
+		if(bi.isMissingResources && bi.prerequisitesCount == 1)
 		{
 			evaluationContext.strategicalValue /= 3;
 			evaluationContext.movementCostByRole[evaluationContext.heroRole] += 5;