#ifndef PLAYER_H #define PLAYER_H #include #include #include #include #include #include #include struct Player { int id; QString name; QColor primaryColor; QColor secondaryColor; // National resources (shared across all cities of this nation) // Note: science represents per-tick science generation rate (no longer stockpiled) int culture; int science; int gold; int faith; // Technology Tree & Research Progression std::set researchedTechs; QMap techProgress; // Tech ID -> accumulated science towards that tech std::vector researchQueue; // Ordered queue of Tech IDs (front is active research) Player() : id(0), name("Unknown"), primaryColor(Qt::blue), secondaryColor(Qt::white), culture(10000), science(0), gold(0), faith(0) {} Player(int pId, const QString &pName, const QColor &primary, const QColor &secondary, int pCulture = 10000, int pScience = 0, int pGold = 0, int pFaith = 0) : id(pId), name(pName), primaryColor(primary), secondaryColor(secondary), culture(pCulture), science(pScience), gold(pGold), faith(pFaith) {} bool hasResearched(const QString &techId) const { if (techId.isEmpty()) return true; return researchedTechs.find(techId) != researchedTechs.end(); } int getTechProgress(const QString &techId) const { return techProgress.value(techId, 0); } bool hasActiveResearch() const { return !researchQueue.empty(); } QString getActiveResearchTech() const { return researchQueue.empty() ? QString() : researchQueue.front(); } bool isTechQueued(const QString &techId) const { return std::find(researchQueue.begin(), researchQueue.end(), techId) != researchQueue.end(); } int getTechQueuePosition(const QString &techId) const { for (size_t i = 0; i < researchQueue.size(); ++i) { if (researchQueue[i] == techId) { return static_cast(i) + 1; } } return 0; } bool arePrerequisitesMet(const QStringList &prerequisites) const { for (const QString &pre : prerequisites) { if (!hasResearched(pre)) return false; } return true; } bool isItemUnlocked(const QString &requiredTech) const { return requiredTech.isEmpty() || hasResearched(requiredTech); } bool isItemObsolete(const QString &obsoleteTech) const { return !obsoleteTech.isEmpty() && hasResearched(obsoleteTech); } bool isItemBuildable(const QString &requiredTech, const QString &obsoleteTech) const { return isItemUnlocked(requiredTech) && !isItemObsolete(obsoleteTech); } }; class PlayerManager { public: PlayerManager(); bool addPlayer(int id, const QString &name, const QColor &primary, const QColor &secondary); const Player* getPlayer(int id) const; Player* getPlayer(int id); const std::vector& getPlayers() const { return m_players; } std::vector& getPlayersMutable() { return m_players; } bool isCombinationUnique(const QColor &primary, const QColor &secondary, int excludeId = -1) const; private: std::vector m_players; }; #endif // PLAYER_H