#pragma once #include "Serial.h" #include #include "../../gen/Generated.h" namespace Puzzle { struct Config { static constexpr uint32_t CardSize = 2; static constexpr uint32_t NodesPerCard = CardSize * CardSize; static constexpr uint32_t MaxElementsPerTile = 4; static constexpr uint32_t MaxPuzzleSizeCards = 16; static constexpr uint32_t MaxCardsInPuzzle = MaxPuzzleSizeCards * MaxPuzzleSizeCards; static constexpr uint32_t MaxPuzzleSizeTiles = 16 * CardSize; static constexpr uint32_t MaxTilesInPuzzle = MaxPuzzleSizeTiles * MaxPuzzleSizeTiles; static constexpr uint32_t MaxAvailableStacks = 16; static constexpr uint32_t MaxGoalPositions = 16; }; // struct PuzPos // { // int8_t X = 0; // int8_t Y = 0; // PuzPos& operator+=(const PuzPos& rhs) // { // X += rhs.X; // Y += rhs.Y; // return *this; // } // friend PuzPos operator+(PuzPos lhs, const PuzPos& rhs) // { // lhs += rhs; // return lhs; // } // }; // struct ElemPos // { // PuzPos Position; // uint8_t ElemIdx = 0; // }; // enum class PuzzleElementType : uint8_t // { // None, // WaterIn, // WaterGoal, // WaterChannel, // ElectricIn, // ElectricGoal, // Blocked, // Bridge, // }; // struct PuzzleNode // { // PuzzleElementType PlacedTypes[Config::MaxElementsPerTile]{PuzzleElementType::None}; // bool HasElement(PuzzleElementType search) const; // bool IsEmpty() const; // }; // struct StaticPuzzleCard // { // PuzzleNode Nodes[Config::NodesPerCard]; // uint16_t ModelHandle = 0; // }; // struct StaticPuzzleCardHandle // { // uint16_t Idx = UINT16_MAX; // bool IsValid() // { // return Idx != UINT16_MAX; // } // }; // struct StaticPuzzleData // { // StaticPuzzleCard Cards[64]; // void Setup(); // static StaticPuzzleData& Get(); // const StaticPuzzleCard& GetCard(StaticPuzzleCardHandle H) const; // }; // struct PlacedPuzzleCard // { // StaticPuzzleCardHandle RefCard; // PuzPos Position; // uint8_t Rotation = 0; // bool IsLocked = false; // }; // struct PuzzleCardStack // { // StaticPuzzleCardHandle RefCard; // uint8_t MaxAvailableCount = 0; // uint8_t UsedCount = 0; // uint8_t GetRemainingCount(); // }; // struct PuzzleData // { // uint32_t AvailableCardCount = 0; // PuzzleCardStack AvailableCards[Config::MaxAvailableStacks]; // uint32_t PlacedCardCount = 0; // PlacedPuzzleCard PlacedCards[Config::MaxCardsInPuzzle]; // // Indexed by board position // PuzzleNode PlacedNodes[Config::MaxTilesInPuzzle]; // uint32_t GoalPositionCount = 0; // ElemPos GoalPositions[Config::MaxGoalPositions]; // const PuzzleNode& GetNodeAt(PuzPos pos) const; // PuzzleElementType GetElementAt(ElemPos pos) const; // char PuzzleName[32]{"Unnamed"}; // bool RenderDebugUI(); // }; } // namespace Puzzle namespace Generated { PuzPos operator+=(PuzPos lhs, const PuzPos& rhs); PuzPos operator+(PuzPos lhs, const PuzPos& rhs); void Setup(StaticPuzzleData& data); StaticPuzzleData& GetStaticPuzzleData(); const StaticPuzzleCard& GetCard(const StaticPuzzleData& data, StaticPuzzleCardHandle H); bool HasElement(const PuzzleNode& node, PuzzleElementType::Enum search); bool IsEmpty(const PuzzleNode& node); bool IsValid(StaticPuzzleCardHandle h); uint8_t GetRemainingCount(const PuzzleCardStack& stack); const PuzzleNode& GetNodeAt(const PuzzleData& puz, PuzPos pos); PuzzleElementType::Enum GetElementAt(const PuzzleData& puz, ElemPos pos); struct PuzzleSolver { bool IsPuzzleSolved(const Generated::PuzzleData& puzzle); bool IsExitSatisfied(const Generated::PuzzleData& puzzle, ElemPos pos); // This assumes flowFrom is already verified to be connected. bool IsValidGoalConnection(const Generated::PuzzleData& puzzle, PuzPos flowFrom, PuzPos flowTo, PuzzleElementType::Enum goalType); bool IsValidSource(PuzzleElementType::Enum sourceType, PuzzleElementType::Enum goalType); }; bool RenderDebugUI(PuzzleData& obj); } // namespace Generated