#pragma once #include #include #include #include #include #include #include "BeltSystem.h" #include "SchematicDropEvent.h" #include "BuildingType.h" #include "EntityId.h" #include "FireEvent.h" #include "GameConfig.h" #include "Rotation.h" #include "Tick.h" class BuildingSystem; class CombatSystem; class ShipSystem; class ScrapSystem; class WaveSystem; class Simulation { public: explicit Simulation(GameConfig config, unsigned int seed = 0); ~Simulation(); const GameConfig& config() const; // Reinitializes all simulation state as if constructed fresh. void reset(unsigned int seed = 0); // Reloads config then reinitializes all simulation state. void reset(GameConfig newConfig, unsigned int seed = 0); // Advances the simulation by one tick. Tick order per architecture.md §Tick Order. void tick(); // Returns all fire events accumulated since the last drain, clearing the // internal queue. Call once per rendered frame (REQ-SHP-FIRING-BEAM). std::vector drainFireEvents(); // Returns all schematic drop events since the last drain. std::vector drainSchematicDropEvents(); Tick currentTick() const; int buildingBlocksStock() const; bool isGameOver() const; double threatLevel() const; // Schematic state queries. int schematicLevel(const std::string& shipId) const; bool isSchematicUnlocked(const std::string& shipId) const; // Checks affordability, deducts building blocks, and places the building. // Returns the new entity id, or kInvalidEntityId if blocks are insufficient. EntityId tryPlaceBuilding(BuildingType type, QPoint anchor, Rotation rotation); // Demolishes the building with the given id and refunds building blocks. void demolish(EntityId id); BuildingSystem& buildings(); const BuildingSystem& buildings() const; BeltSystem& belts(); const BeltSystem& belts() const; ShipSystem& ships(); const ShipSystem& ships() const; ScrapSystem& scraps(); const ScrapSystem& scraps() const; private: EntityId allocateId(); // Strictly increasing; never returns kInvalidEntityId. // Populate HQ, player defence stations, and the first enemy station set. void placeInitialStructures(); // Place two enemy defence stations for the given generation level. // Stores their IDs in m_currentEnemyStationIds. void placeEnemyStationSet(int generation); // Tick step 9: remove dead ships and buildings, drop scrap, handle push. void tickDeathsAndLoot(); // Award a random schematic drop (REQ-DEF-SCHEMATIC-DROP) and emit the event. void awardSchematicDrop(); GameConfig m_config; std::mt19937 m_rng; Tick m_currentTick; Tick m_nextDepartureTick; EntityId m_nextId; int m_buildingBlocksStock; bool m_gameOver = false; // Pre-placed structure IDs. EntityId m_hqId; EntityId m_playerStation1Id; EntityId m_playerStation2Id; EntityId m_currentEnemyStationIds[2]; // Schematic unlock state (REQ-DEF-SCHEMATIC-DROP). struct SchematicState { bool unlocked; int level; }; std::map m_schematicLevels; BeltSystem m_beltSystem; std::unique_ptr m_buildingSystem; std::unique_ptr m_shipSystem; std::unique_ptr m_scrapSystem; std::unique_ptr m_waveSystem; std::unique_ptr m_combatSystem; std::vector m_fireEvents; std::vector m_schematicDropEvents; };