#pragma once #include #include namespace PocketDungeon { static constexpr uint8_t DUNGEON_COLS = 9; static constexpr uint8_t DUNGEON_ROWS = 7; static constexpr uint8_t TUTORIAL_ROWS = 2; static constexpr uint8_t MAX_ENTITIES = 8; enum class Tile : uint8_t { Floor, Wall, Stairs, Treasure }; enum class EntityType : uint8_t { Player, Slime, Bat }; enum class MoveResult : uint8_t { None, Moved, Blocked, Attacked, Treasure, Stairs, Dead }; struct Entity { EntityType type = EntityType::Slime; GameKit::GridPos pos {}; int8_t hp = 1; bool alive = false; }; struct DungeonState { Tile tiles[DUNGEON_ROWS][DUNGEON_COLS] {}; Entity entities[MAX_ENTITIES] {}; uint8_t entityCount = 0; GameKit::GridPos playerPos {1, 1}; uint16_t floor = 0; // 0,1 tutorial, 2+ real uint16_t gold = 0; int8_t hp = 5; bool gameOver = false; uint8_t renderRows = DUNGEON_ROWS; }; class DungeonModel { DungeonState state {}; uint32_t seed = 0xC0FFEE; uint16_t bestFloor = 1; uint16_t bestGold = 0; uint32_t nextRandom(); void addEnemy(EntityType type, GameKit::GridPos pos, int8_t hp); int findEnemyAt(GameKit::GridPos pos) const; bool isWalkable(GameKit::GridPos pos) const; void moveMonsters(); void generateTutorialFloor(uint8_t tId); void clearAllTiles(); public: void reset(uint32_t seedValue = 0xC0FFEE, bool tutorials = true); void generateFloor(); MoveResult movePlayer(int dx, int dy); const DungeonState& getState() const { return state; } uint16_t getBestFloor() const { return bestFloor; } uint16_t getBestGold() const { return bestGold; } void setBests(uint16_t floor, uint16_t gold) { bestFloor = floor; bestGold = gold; } bool isTutorial() const { return state.floor < 2; } uint8_t tutorialId() const { return static_cast(state.floor); } uint16_t displayFloor() const { return state.floor < 2 ? 1 : state.floor - 1; } }; } // namespace PocketDungeon