From de88190c4748799337212aee6bf7e498bc69a33f Mon Sep 17 00:00:00 2001 From: Asuro Date: Fri, 14 Mar 2025 01:33:38 +0100 Subject: [PATCH] simplify puzzle data and auto run codegen --- src/CMakeLists.txt | 9 ++- src/game/Puzzle.cpp | 93 +++++++++++++++---------------- src/game/Puzzle.h | 9 ++- src/game/data/puzzles/0.pzl | 4 +- src/game/data/static/puzzle.dat | Bin 4236 -> 1164 bytes src/game/mini.def | 19 ++----- src/game/rendering/Rendering.cpp | 12 ++-- src/gen/Generated.cpp | 50 ++--------------- src/gen/Generated.h | 29 +++------- 9 files changed, 82 insertions(+), 143 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ce61a52..1d63755 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -28,7 +28,14 @@ set_property(TARGET PuzGameEngine PROPERTY CXX_STANDARD 17) target_include_directories(PuzGameEngine PUBLIC) # Game -file(GLOB_RECURSE sources_game game/*.cpp game/*.h gen/*.cpp gen/*.h) +add_custom_command( + COMMAND "${CMAKE_BINARY_DIR}/minidef.exe" "${CMAKE_SOURCE_DIR}/game/mini.def" "${CMAKE_SOURCE_DIR}/gen/" + DEPENDS "${CMAKE_SOURCE_DIR}/game/mini.def" + OUTPUT "${CMAKE_SOURCE_DIR}/gen/Generated.h" "${CMAKE_SOURCE_DIR}/gen/Generated.cpp" + COMMENT "Genrating from minidef" +) + +file(GLOB_RECURSE sources_game game/*.cpp game/*.h gen/Generated.cpp gen/Generated.h gen/Def.h gen/Def.cpp) file(GLOB source_singleheader dependency/tinygltf/stb_image.h dependency/tinygltf/stb_image_write.h dependency/tinygltf/json.hpp dependency/tinygltf/tiny_gltf.h) add_library(PuzGame SHARED ${sources_game} ${source_singleheader} ${imgui_sources} ${imgui_backend_sdl}) set_property(TARGET PuzGame PROPERTY CXX_STANDARD 17) diff --git a/src/game/Puzzle.cpp b/src/game/Puzzle.cpp index 06e3e7d..b6b3164 100644 --- a/src/game/Puzzle.cpp +++ b/src/game/Puzzle.cpp @@ -60,24 +60,6 @@ namespace Generated return data.Cards[H.Idx]; } - bool HasElement(const PuzzleNode& node, PuzzleElementType::Enum search) - { - for (int32_t i = 0; i < Puzzle::Config::MaxElementsPerTile; ++i) - { - if (node.PlacedTypes[i] == search) return true; - } - return false; - } - - bool IsEmpty(const PuzzleNode& node) - { - for (int32_t i = 0; i < Puzzle::Config::MaxElementsPerTile; ++i) - { - if (node.PlacedTypes[i] != PuzzleElementType::None) return false; - } - return true; - } - bool IsValid(StaticPuzzleCardHandle h) { return h.Idx != UINT16_MAX; @@ -89,18 +71,43 @@ namespace Generated return stack.MaxAvailableCount - stack.UsedCount; } - const PuzzleNode& GetNodeAt(const PuzzleData& puz, PuzPos pos) + PuzzleElementType::Enum GetNodeAt(const PuzzleData& puz, PuzPos pos) { assert(pos.X < Puzzle::Config::MaxPuzzleSizeCards && pos.Y < Puzzle::Config::MaxPuzzleSizeCards && pos.X >= 0 && pos.Y >= 0); - return puz.PlacedNodes[pos.Y * Puzzle::Config::MaxPuzzleSizeCards + pos.X]; + // TODO: this is horrible + for (int32_t i = 0; i < puz.PlacedCardCount; ++i) + { + auto& card = puz.PlacedCards[i]; + int8_t offsetX = pos.X - card.Position.X; + int8_t offsetY = pos.Y - card.Position.Y; + if (offsetX >= 0 && offsetX < Puzzle::Config::CardSize && offsetY >= 0 && + offsetY < Puzzle::Config::CardSize) + { + PuzzleElementType::Enum cardVal = + GetCardNodeAt(GetCard(GetStaticPuzzleData(), card.RefCard), offsetX, offsetY); + if (cardVal != PuzzleElementType::None) return cardVal; + } + } + return puz.BackgroundTiles[pos.Y * Puzzle::Config::MaxPuzzleSizeCards + pos.X]; } - PuzzleElementType::Enum GetElementAt(const PuzzleData& puz, ElemPos pos) + PuzzleElementType::Enum GetCardNodeAt(const StaticPuzzleCard& card, int8_t x, int8_t y) { - assert(pos.ElemIdx < Puzzle::Config::MaxElementsPerTile); - const PuzzleNode& node = GetNodeAt(puz, pos.Position); - return node.PlacedTypes[pos.ElemIdx]; + assert(x >= 0 && x < Puzzle::Config::CardSize); + assert(y >= 0 && y < Puzzle::Config::CardSize); + + // TODO: account for card rotation + return card.Elements[y * Puzzle::Config::CardSize + x]; + } + + PuzzleElementType::Enum& EditCardNodeAt(StaticPuzzleCard& card, int8_t x, int8_t y) + { + assert(x >= 0 && x < Puzzle::Config::CardSize); + assert(y >= 0 && y < Puzzle::Config::CardSize); + + // TODO: account for card rotation + return card.Elements[y * Puzzle::Config::CardSize + x]; } bool PuzzleSolver::IsPuzzleSolved(const PuzzleData& puzzle) @@ -117,16 +124,15 @@ namespace Generated return IsSolved; } - bool PuzzleSolver::IsExitSatisfied(const PuzzleData& puzzle, ElemPos pos) + bool PuzzleSolver::IsExitSatisfied(const PuzzleData& puzzle, PuzPos pos) { - const PuzzleNode& goalNode = GetNodeAt(puzzle, pos.Position); - PuzzleElementType::Enum goalType = GetElementAt(puzzle, pos); + PuzzleElementType::Enum goalType = GetNodeAt(puzzle, pos); uint32_t currentPositionQueueIdx = 0; uint32_t positionQueueCount = 0; PuzPos positionQueue[Puzzle::Config::MaxTilesInPuzzle]; - positionQueue[0] = pos.Position; + positionQueue[0] = pos; positionQueueCount++; while (positionQueueCount > 0) { @@ -137,13 +143,9 @@ namespace Generated PuzPos nextPos = currentPos + dir; if (IsValidGoalConnection(puzzle, nextPos, currentPos, goalType)) { - const PuzzleNode& node = GetNodeAt(puzzle, nextPos); - for (PuzzleElementType::Enum e : node.PlacedTypes) + if (IsValidSource(GetNodeAt(puzzle, nextPos), goalType)) { - if (IsValidSource(e, goalType)) - { - return true; - } + return true; } positionQueue[positionQueueCount] = nextPos; positionQueueCount++; @@ -159,18 +161,18 @@ namespace Generated PuzPos flowTo, PuzzleElementType::Enum goalType) { - const PuzzleNode& from = GetNodeAt(puzzle, flowFrom); - const PuzzleNode& to = GetNodeAt(puzzle, flowTo); + auto from = GetNodeAt(puzzle, flowFrom); + auto to = GetNodeAt(puzzle, flowTo); if (goalType == PuzzleElementType::WaterGoal) { - return HasElement(from, PuzzleElementType::WaterIn) || HasElement(from, PuzzleElementType::WaterChannel) || - HasElement(from, PuzzleElementType::WaterGoal); + return from == PuzzleElementType::WaterIn || from == PuzzleElementType::WaterChannel || + from == PuzzleElementType::WaterGoal; } else if (goalType == PuzzleElementType::ElectricGoal) { - return HasElement(from, PuzzleElementType::ElectricIn) || - HasElement(from, PuzzleElementType::ElectricGoal) || IsEmpty(from); + return from == PuzzleElementType::ElectricIn || from == PuzzleElementType::ElectricGoal || + from == PuzzleElementType::None; } assert(false); return false; @@ -192,14 +194,9 @@ namespace Generated bx::snprintf(buf, bufSize, "%s/%u.pzl", Puzzle::PuzzleFileDir, puzID); } - const char* GetShortNodeName(const PuzzleNode& node) + const char* GetShortNodeName(const PuzzleElementType::Enum node) { - PuzzleElementType::Enum elemMax = PuzzleElementType::None; - for (int32_t i = 0; i < BX_COUNTOF(node.PlacedTypes); ++i) - { - if (node.PlacedTypes[i] > elemMax) elemMax = node.PlacedTypes[i]; - } - return PuzzleElementType::ShortName[elemMax]; + return PuzzleElementType::ShortName[node]; } bool RenderDebugUI(PuzzleData& obj) @@ -257,7 +254,7 @@ namespace Generated for (int32_t x = 0; x < obj.WidthTiles; ++x) { ImGui::PushID(x); - PuzzleNode& node = obj.PlacedNodes[Puzzle::Config::MaxPuzzleSizeTiles * y + x]; + auto node = GetNodeAt(obj, {int8_t(x), int8_t(y)}); ImVec2 pos = ImVec2{puzCursorStart.x + x * UIPuzBoxSize + 5, puzCursorStart.y + y * UIPuzBoxSize}; ImGui::SetCursorScreenPos(pos); ImGui::Text("%s", GetShortNodeName(node)); diff --git a/src/game/Puzzle.h b/src/game/Puzzle.h index cc18dcf..cb9fac7 100644 --- a/src/game/Puzzle.h +++ b/src/game/Puzzle.h @@ -31,17 +31,16 @@ namespace Generated void LoadStaticPuzzleData(); void SaveStaticPuzzleData(); 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); + PuzzleElementType::Enum GetNodeAt(const PuzzleData& puz, PuzPos pos); + PuzzleElementType::Enum GetCardNodeAt(const StaticPuzzleCard& card, int8_t x, int8_t y); + PuzzleElementType::Enum& EditCardNodeAt(StaticPuzzleCard& card, int8_t x, int8_t y); struct PuzzleSolver { bool IsPuzzleSolved(const Generated::PuzzleData& puzzle); - bool IsExitSatisfied(const Generated::PuzzleData& puzzle, ElemPos pos); + bool IsExitSatisfied(const Generated::PuzzleData& puzzle, PuzPos pos); // This assumes flowFrom is already verified to be connected. bool IsValidGoalConnection(const Generated::PuzzleData& puzzle, diff --git a/src/game/data/puzzles/0.pzl b/src/game/data/puzzles/0.pzl index 03dc239..289083a 100644 --- a/src/game/data/puzzles/0.pzl +++ b/src/game/data/puzzles/0.pzl @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:46b544848f139d2a7f3dd20643596e338f0aaab45394c96ba67e8f058915c8d9 -size 18124 +oid sha256:017e1fab623e2bce8a32933f1945242335279d895b43204802630fa47e653386 +size 5820 diff --git a/src/game/data/static/puzzle.dat b/src/game/data/static/puzzle.dat index 3a28f6b362848bd7a584681e62c89c41161fee76..d555fea32fd81f9b56abf517e6b5819500e42fa8 100644 GIT binary patch literal 1164 pcmWFz2#vDxNZ!xD%76hF8JMABFq#9(AEib^U^E0qLx8#=0078e0}B8E literal 4236 zcmWFz2#tEHpjp5m$Ure*WMC#>1|fM4f+i5KfPo#u1av#m`RFFHp$m}A=O9@Jx`t5` zAR#gu4x`}!2>}Q>njS{O0TKcbax^`Rh65x7AmnIz7!3zV2tdfu^e`F@kPv{7qv>HZ P93UY8AxG20U 0) ImGui::SameLine(); ImGui::PushID(x); - auto& node = card.Nodes[y * Puzzle::Config::CardSize + x]; - if (ImGui::Button(Generated::PuzzleElementType::ShortName[node.PlacedTypes[0]], {26, 24})) + auto& node = Generated::EditCardNodeAt(card, x, y); + if (ImGui::Button(Generated::PuzzleElementType::ShortName[node], {26, 24})) { - int32_t newVal = int32_t(node.PlacedTypes[0]) + 1; + int32_t newVal = int32_t(node) + 1; if (newVal >= Generated::PuzzleElementType::EntryCount) { newVal = 0; } - node.PlacedTypes[0] = Generated::PuzzleElementType::Enum(newVal); + node = Generated::PuzzleElementType::Enum(newVal); } ImGui::PopID(); } diff --git a/src/gen/Generated.cpp b/src/gen/Generated.cpp index 2feba1b..085952a 100644 --- a/src/gen/Generated.cpp +++ b/src/gen/Generated.cpp @@ -144,50 +144,12 @@ namespace Generated } return isOk; } - bool Save(const ElemPos* obj, uint32_t count, Serializer& serializer) - { - bool isOk = true; - for (uint32_t i = 0; i < count; ++i) - { - isOk = Save(&obj[i].Position, 1, serializer) && isOk; - isOk = Save(&obj[i].ElemIdx, 1, serializer) && isOk; - } - return isOk; - } - bool Load(ElemPos* obj, uint32_t count, Deserializer& serializer) - { - bool isOk = true; - for (uint32_t i = 0; i < count; ++i) - { - isOk = Load(&obj[i].Position, 1, serializer) && isOk; - isOk = Load(&obj[i].ElemIdx, 1, serializer) && isOk; - } - return isOk; - } - bool Save(const PuzzleNode* obj, uint32_t count, Serializer& serializer) - { - bool isOk = true; - for (uint32_t i = 0; i < count; ++i) - { - isOk = Save(obj[i].PlacedTypes, 4, serializer) && isOk; - } - return isOk; - } - bool Load(PuzzleNode* obj, uint32_t count, Deserializer& serializer) - { - bool isOk = true; - for (uint32_t i = 0; i < count; ++i) - { - isOk = Load(obj[i].PlacedTypes, 4, serializer) && isOk; - } - return isOk; - } bool Save(const StaticPuzzleCard* obj, uint32_t count, Serializer& serializer) { bool isOk = true; for (uint32_t i = 0; i < count; ++i) { - isOk = Save(obj[i].Nodes, 4, serializer) && isOk; + isOk = Save(obj[i].Elements, 4, serializer) && isOk; isOk = Save(&obj[i].ModelHandle, 1, serializer) && isOk; } return isOk; @@ -197,7 +159,7 @@ namespace Generated bool isOk = true; for (uint32_t i = 0; i < count; ++i) { - isOk = Load(obj[i].Nodes, 4, serializer) && isOk; + isOk = Load(obj[i].Elements, 4, serializer) && isOk; isOk = Load(&obj[i].ModelHandle, 1, serializer) && isOk; } return isOk; @@ -290,16 +252,16 @@ namespace Generated for (uint32_t i = 0; i < count; ++i) { isOk = Save(&obj[i].ID, 1, serializer) && isOk; + isOk = Save(obj[i].PuzzleName, 64, serializer) && isOk; isOk = Save(&obj[i].WidthTiles, 1, serializer) && isOk; isOk = Save(&obj[i].HeightTiles, 1, serializer) && isOk; isOk = Save(&obj[i].AvailableCardCount, 1, serializer) && isOk; isOk = Save(obj[i].AvailableCards, 16, serializer) && isOk; isOk = Save(&obj[i].PlacedCardCount, 1, serializer) && isOk; isOk = Save(obj[i].PlacedCards, 256, serializer) && isOk; - isOk = Save(obj[i].PlacedNodes, 1024, serializer) && isOk; + isOk = Save(obj[i].BackgroundTiles, 1024, serializer) && isOk; isOk = Save(&obj[i].GoalPositionCount, 1, serializer) && isOk; isOk = Save(obj[i].GoalPositions, 16, serializer) && isOk; - isOk = Save(obj[i].PuzzleName, 64, serializer) && isOk; } return isOk; } @@ -309,16 +271,16 @@ namespace Generated for (uint32_t i = 0; i < count; ++i) { isOk = Load(&obj[i].ID, 1, serializer) && isOk; + isOk = Load(obj[i].PuzzleName, 64, serializer) && isOk; isOk = Load(&obj[i].WidthTiles, 1, serializer) && isOk; isOk = Load(&obj[i].HeightTiles, 1, serializer) && isOk; isOk = Load(&obj[i].AvailableCardCount, 1, serializer) && isOk; isOk = Load(obj[i].AvailableCards, 16, serializer) && isOk; isOk = Load(&obj[i].PlacedCardCount, 1, serializer) && isOk; isOk = Load(obj[i].PlacedCards, 256, serializer) && isOk; - isOk = Load(obj[i].PlacedNodes, 1024, serializer) && isOk; + isOk = Load(obj[i].BackgroundTiles, 1024, serializer) && isOk; isOk = Load(&obj[i].GoalPositionCount, 1, serializer) && isOk; isOk = Load(obj[i].GoalPositions, 16, serializer) && isOk; - isOk = Load(obj[i].PuzzleName, 64, serializer) && isOk; } return isOk; } diff --git a/src/gen/Generated.h b/src/gen/Generated.h index 2994819..099dcc8 100644 --- a/src/gen/Generated.h +++ b/src/gen/Generated.h @@ -98,21 +98,10 @@ namespace Generated int8_t X = {}; int8_t Y = {}; }; - struct ElemPos - { - static constexpr uint32_t Hash = 3966109730; - PuzPos Position = {}; - uint8_t ElemIdx = {}; - }; - struct PuzzleNode - { - static constexpr uint32_t Hash = 1417779061; - PuzzleElementType::Enum PlacedTypes[4] = {}; - }; struct StaticPuzzleCard { - static constexpr uint32_t Hash = 110653106; - PuzzleNode Nodes[4] = {}; + static constexpr uint32_t Hash = 2507139249; + PuzzleElementType::Enum Elements[4] = {}; uint16_t ModelHandle = {}; }; struct StaticPuzzleCardHandle @@ -122,7 +111,7 @@ namespace Generated }; struct StaticPuzzleData { - static constexpr uint32_t Hash = 1881743597; + static constexpr uint32_t Hash = 3210954810; StaticPuzzleCard Cards[64] = {}; }; struct PuzzleCardStack @@ -142,18 +131,18 @@ namespace Generated }; struct PuzzleData { - static constexpr uint32_t Hash = 255994202; + static constexpr uint32_t Hash = 2775382112; uint16_t ID = {}; + char PuzzleName[64] = {}; uint8_t WidthTiles = {}; uint8_t HeightTiles = {}; uint32_t AvailableCardCount = {}; PuzzleCardStack AvailableCards[16] = {}; uint32_t PlacedCardCount = {}; PlacedPuzzleCard PlacedCards[256] = {}; - PuzzleNode PlacedNodes[1024] = {}; + PuzzleElementType::Enum BackgroundTiles[1024] = {}; uint32_t GoalPositionCount = {}; - ElemPos GoalPositions[16] = {}; - char PuzzleName[64] = {}; + PuzPos GoalPositions[16] = {}; }; bool Save(const PuzzleElementType::Enum* obj, uint32_t count, Serializer& serializer); bool Load(PuzzleElementType::Enum* obj, uint32_t count, Deserializer& serializer); @@ -169,10 +158,6 @@ namespace Generated bool Load(Mat4* obj, uint32_t count, Deserializer& serializer); bool Save(const PuzPos* obj, uint32_t count, Serializer& serializer); bool Load(PuzPos* obj, uint32_t count, Deserializer& serializer); - bool Save(const ElemPos* obj, uint32_t count, Serializer& serializer); - bool Load(ElemPos* obj, uint32_t count, Deserializer& serializer); - bool Save(const PuzzleNode* obj, uint32_t count, Serializer& serializer); - bool Load(PuzzleNode* obj, uint32_t count, Deserializer& serializer); bool Save(const StaticPuzzleCard* obj, uint32_t count, Serializer& serializer); bool Load(StaticPuzzleCard* obj, uint32_t count, Deserializer& serializer); bool Save(const StaticPuzzleCardHandle* obj, uint32_t count, Serializer& serializer);