浏览代码

refactoring + values added

Laserlicht 1 年之前
父节点
当前提交
86477c7b04
共有 3 个文件被更改,包括 96 次插入37 次删除
  1. 1 9
      lib/gameState/CGameState.cpp
  2. 82 26
      lib/gameState/GameStatistics.cpp
  3. 13 2
      lib/gameState/GameStatistics.h

+ 1 - 9
lib/gameState/CGameState.cpp

@@ -1600,15 +1600,7 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
 	}
 	}
 	if(level >= 3) //obelisks found
 	if(level >= 3) //obelisks found
 	{
 	{
-		auto getObeliskVisited = [&](const TeamID & t)
-		{
-			if(map->obelisksVisited.count(t))
-				return map->obelisksVisited[t];
-			else
-				return ui8(0);
-		};
-
-		FILL_FIELD(obelisks, getObeliskVisited(gs->getPlayerTeam(g->second.color)->id))
+		FILL_FIELD(obelisks, Statistic::getObeliskVisited(gs, gs->getPlayerTeam(g->second.color)->id))
 	}
 	}
 	if(level >= 4) //artifacts
 	if(level >= 4) //artifacts
 	{
 	{

+ 82 - 26
lib/gameState/GameStatistics.cpp

@@ -13,6 +13,7 @@
 #include "../constants/StringConstants.h"
 #include "../constants/StringConstants.h"
 #include "CGameState.h"
 #include "CGameState.h"
 #include "TerrainHandler.h"
 #include "TerrainHandler.h"
+#include "CHeroHandler.h"
 #include "StartInfo.h"
 #include "StartInfo.h"
 #include "../mapObjects/CGHeroInstance.h"
 #include "../mapObjects/CGHeroInstance.h"
 #include "../mapObjects/CGTownInstance.h"
 #include "../mapObjects/CGTownInstance.h"
@@ -40,9 +41,12 @@ StatisticDataSetEntry StatisticDataSet::createEntry(const PlayerState * ps, cons
 	data.numberHeroes = ps->heroes.size();
 	data.numberHeroes = ps->heroes.size();
 	data.numberTowns = ps->towns.size();
 	data.numberTowns = ps->towns.size();
 	data.numberArtifacts = Statistic::getNumberOfArts(ps);
 	data.numberArtifacts = Statistic::getNumberOfArts(ps);
-	data.armyStrength = Statistic::getArmyStrength(ps);
+	data.armyStrength = Statistic::getArmyStrength(ps, true);
 	data.income = Statistic::getIncome(gs, ps);
 	data.income = Statistic::getIncome(gs, ps);
 	data.mapVisitedRatio = Statistic::getMapVisitedRatio(gs, ps->color);
 	data.mapVisitedRatio = Statistic::getMapVisitedRatio(gs, ps->color);
+	data.obeliskVisited = Statistic::getObeliskVisited(gs, ps->team);
+	data.mightMagicRatio = Statistic::getMightMagicRatio(ps);
+	data.numMines = Statistic::getNumMines(gs, ps);
 
 
 	return data;
 	return data;
 }
 }
@@ -63,9 +67,13 @@ std::string StatisticDataSet::toCsv()
 	ss << "NumberArtifacts" << ";";
 	ss << "NumberArtifacts" << ";";
 	ss << "ArmyStrength" << ";";
 	ss << "ArmyStrength" << ";";
 	ss << "Income" << ";";
 	ss << "Income" << ";";
-	ss << "MapVisitedRatio";
+	ss << "MapVisitedRatio" << ";";
+	ss << "ObeliskVisited" << ";";
+	ss << "MightMagicRatio";
 	for(auto & resource : resources)
 	for(auto & resource : resources)
 		ss << ";" << GameConstants::RESOURCE_NAMES[resource];
 		ss << ";" << GameConstants::RESOURCE_NAMES[resource];
+	for(auto & resource : resources)
+		ss << ";" << GameConstants::RESOURCE_NAMES[resource] + "Mines";
 	ss << "\r\n";
 	ss << "\r\n";
 
 
 	for(auto & entry : data)
 	for(auto & entry : data)
@@ -80,15 +88,49 @@ std::string StatisticDataSet::toCsv()
 		ss << entry.numberArtifacts << ";";
 		ss << entry.numberArtifacts << ";";
 		ss << entry.armyStrength << ";";
 		ss << entry.armyStrength << ";";
 		ss << entry.income << ";";
 		ss << entry.income << ";";
-		ss << entry.mapVisitedRatio;
+		ss << entry.mapVisitedRatio << ";";
+		ss << entry.obeliskVisited << ";";
+		ss << entry.mightMagicRatio;
 		for(auto & resource : resources)
 		for(auto & resource : resources)
 			ss << ";" << entry.resources[resource];
 			ss << ";" << entry.resources[resource];
+		for(auto & resource : resources)
+			ss << ";" << entry.numMines[resource];
 		ss << "\r\n";
 		ss << "\r\n";
 	}
 	}
 
 
 	return ss.str();
 	return ss.str();
 }
 }
 
 
+std::vector<const CGMine *> Statistic::getMines(const CGameState * gs, const PlayerState * ps)
+{
+	std::vector<const CGMine *> tmp;
+
+	/// FIXME: Dirty dirty hack
+	/// Stats helper need some access to gamestate.
+	std::vector<const CGObjectInstance *> ownedObjects;
+	for(const CGObjectInstance * obj : gs->map->objects)
+	{
+		if(obj && obj->tempOwner == ps->color)
+			ownedObjects.push_back(obj);
+	}
+	/// This is code from CPlayerSpecificInfoCallback::getMyObjects
+	/// I'm really need to find out about callback interface design...
+
+	for(const auto * object : ownedObjects)
+	{
+		//Mines
+		if ( object->ID == Obj::MINE )
+		{
+			const auto * mine = dynamic_cast<const CGMine *>(object);
+			assert(mine);
+
+			tmp.push_back(mine);
+		}
+	}
+
+	return tmp;
+}
+
 //calculates total number of artifacts that belong to given player
 //calculates total number of artifacts that belong to given player
 int Statistic::getNumberOfArts(const PlayerState * ps)
 int Statistic::getNumberOfArts(const PlayerState * ps)
 {
 {
@@ -101,13 +143,13 @@ int Statistic::getNumberOfArts(const PlayerState * ps)
 }
 }
 
 
 // get total strength of player army
 // get total strength of player army
-si64 Statistic::getArmyStrength(const PlayerState * ps)
+si64 Statistic::getArmyStrength(const PlayerState * ps, bool withTownGarrison)
 {
 {
 	si64 str = 0;
 	si64 str = 0;
 
 
 	for(auto h : ps->heroes)
 	for(auto h : ps->heroes)
 	{
 	{
-		if(!h->inTownGarrison)		//original h3 behavior
+		if(!h->inTownGarrison || withTownGarrison)		//original h3 behavior
 			str += h->getArmyStrength();
 			str += h->getArmyStrength();
 	}
 	}
 	return str;
 	return str;
@@ -138,28 +180,10 @@ int Statistic::getIncome(const CGameState * gs, const PlayerState * ps)
 			heroOrTown = t;
 			heroOrTown = t;
 	}
 	}
 
 
-	/// FIXME: Dirty dirty hack
-	/// Stats helper need some access to gamestate.
-	std::vector<const CGObjectInstance *> ownedObjects;
-	for(const CGObjectInstance * obj : heroOrTown->cb->gameState()->map->objects)
-	{
-		if(obj && obj->tempOwner == ps->color)
-			ownedObjects.push_back(obj);
-	}
-	/// This is code from CPlayerSpecificInfoCallback::getMyObjects
-	/// I'm really need to find out about callback interface design...
-
-	for(const auto * object : ownedObjects)
+	for(const CGMine * mine : getMines(gs, ps))
 	{
 	{
-		//Mines
-		if ( object->ID == Obj::MINE )
-		{
-			const auto * mine = dynamic_cast<const CGMine *>(object);
-			assert(mine);
-
-			if (mine->producedResource == EGameResID::GOLD)
-				totalIncome += mine->getProducedQuantity();
-		}
+		if (mine->producedResource == EGameResID::GOLD)
+			totalIncome += mine->getProducedQuantity();
 	}
 	}
 
 
 	return totalIncome;
 	return totalIncome;
@@ -233,4 +257,36 @@ std::vector<std::vector<PlayerColor>> Statistic::getRank(std::vector<TStat> stat
 	return ret;
 	return ret;
 }
 }
 
 
+int Statistic::getObeliskVisited(const CGameState * gs, const TeamID & t)
+{
+	if(gs->map->obelisksVisited.count(t))
+		return gs->map->obelisksVisited.at(t);
+	else
+		return 0;
+}
+
+double Statistic::getMightMagicRatio(const PlayerState * ps)
+{
+	double numMight = 0;
+
+	for(auto h : ps->heroes)
+		if(h->type->heroClass->affinity == CHeroClass::EClassAffinity::MIGHT)
+			numMight++;
+
+	return numMight / ps->heroes.size();
+}
+
+std::map<EGameResID, int> Statistic::getNumMines(const CGameState * gs, const PlayerState * ps)
+{
+	std::map<EGameResID, int> tmp;
+
+	for(auto & res : EGameResID::ALL_RESOURCES())
+		tmp[res] = 0;
+
+	for(const CGMine * mine : getMines(gs, ps))
+		tmp[mine->producedResource]++;
+	
+	return tmp;
+}
+
 VCMI_LIB_NAMESPACE_END
 VCMI_LIB_NAMESPACE_END

+ 13 - 2
lib/gameState/GameStatistics.h

@@ -17,6 +17,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 struct PlayerState;
 struct PlayerState;
 class CGameState;
 class CGameState;
 class CGHeroInstance;
 class CGHeroInstance;
+class CGMine;
 
 
 struct DLL_LINKAGE StatisticDataSetEntry
 struct DLL_LINKAGE StatisticDataSetEntry
 {
 {
@@ -32,6 +33,9 @@ struct DLL_LINKAGE StatisticDataSetEntry
 	si64 armyStrength;
 	si64 armyStrength;
 	int income;
 	int income;
 	double mapVisitedRatio;
 	double mapVisitedRatio;
+	int obeliskVisited;
+	double mightMagicRatio;
+	std::map<EGameResID, int> numMines;
 
 
 	template <typename Handler> void serialize(Handler &h)
 	template <typename Handler> void serialize(Handler &h)
 	{
 	{
@@ -47,6 +51,9 @@ struct DLL_LINKAGE StatisticDataSetEntry
 		h & armyStrength;
 		h & armyStrength;
 		h & income;
 		h & income;
 		h & mapVisitedRatio;
 		h & mapVisitedRatio;
+		h & obeliskVisited;
+		h & mightMagicRatio;
+		h & numMines;
 	}
 	}
 };
 };
 
 
@@ -67,15 +74,19 @@ public:
 
 
 class DLL_LINKAGE Statistic
 class DLL_LINKAGE Statistic
 {
 {
+	static std::vector<const CGMine *> getMines(const CGameState * gs, const PlayerState * ps);
 public:
 public:
 	using TStat = std::pair<PlayerColor, si64>;
 	using TStat = std::pair<PlayerColor, si64>;
 
 
-    static int getNumberOfArts(const PlayerState * ps);
-	static si64 getArmyStrength(const PlayerState * ps);
+	static int getNumberOfArts(const PlayerState * ps);
+	static si64 getArmyStrength(const PlayerState * ps, bool withTownGarrison = false);
 	static int getIncome(const CGameState * gs, const PlayerState * ps);
 	static int getIncome(const CGameState * gs, const PlayerState * ps);
 	static double getMapVisitedRatio(const CGameState * gs, PlayerColor player);
 	static double getMapVisitedRatio(const CGameState * gs, PlayerColor player);
 	static const CGHeroInstance * findBestHero(CGameState * gs, const PlayerColor & color);
 	static const CGHeroInstance * findBestHero(CGameState * gs, const PlayerColor & color);
 	static std::vector<std::vector<PlayerColor>> getRank(std::vector<TStat> stats);
 	static std::vector<std::vector<PlayerColor>> getRank(std::vector<TStat> stats);
+	static int getObeliskVisited(const CGameState * gs, const TeamID & t);
+	static double getMightMagicRatio(const PlayerState * ps);
+	static std::map<EGameResID, int> getNumMines(const CGameState * gs, const PlayerState * ps);
 };
 };
 
 
 VCMI_LIB_NAMESPACE_END
 VCMI_LIB_NAMESPACE_END