save works!
This commit is contained in:
@@ -9,73 +9,79 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
static constexpr Puzzle::PuzPos Dirs[4]{
|
||||
static constexpr Generated::PuzPos Dirs[4]{
|
||||
{-1, 0},
|
||||
{0, -1},
|
||||
{0, 1},
|
||||
{1, 0},
|
||||
};
|
||||
|
||||
Puzzle::StaticPuzzleData* StaticDataInstance = nullptr;
|
||||
Generated::StaticPuzzleData* StaticDataInstance = nullptr;
|
||||
} // namespace
|
||||
|
||||
namespace Puzzle
|
||||
namespace Generated
|
||||
{
|
||||
void StaticPuzzleData::Setup()
|
||||
void Setup(StaticPuzzleData& data)
|
||||
{
|
||||
StaticDataInstance = this;
|
||||
StaticDataInstance = &data;
|
||||
LOG("Setting up static puzzle data");
|
||||
for (int32_t i = 0; i < BX_COUNTOF(Cards); ++i)
|
||||
for (int32_t i = 0; i < BX_COUNTOF(data.Cards); ++i)
|
||||
{
|
||||
Cards[i].ModelHandle = Game::GameRendering::Get().GetModelHandleFromPath("models/w straight.glb");
|
||||
data.Cards[i].ModelHandle = Game::GameRendering::Get().GetModelHandleFromPath("models/w straight.glb");
|
||||
}
|
||||
}
|
||||
|
||||
StaticPuzzleData& StaticPuzzleData::Get()
|
||||
StaticPuzzleData& GetStaticPuzzleData()
|
||||
{
|
||||
assert(StaticDataInstance != nullptr);
|
||||
return *StaticDataInstance;
|
||||
}
|
||||
const StaticPuzzleCard& StaticPuzzleData::GetCard(StaticPuzzleCardHandle H) const
|
||||
const StaticPuzzleCard& GetCard(const StaticPuzzleData& data, StaticPuzzleCardHandle H)
|
||||
{
|
||||
assert(H.IsValid());
|
||||
return Cards[H.Idx];
|
||||
// assert(IsValid(H));
|
||||
return data.Cards[H.Idx];
|
||||
}
|
||||
|
||||
bool PuzzleNode::HasElement(PuzzleElementType search) const
|
||||
bool HasElement(const PuzzleNode& node, PuzzleElementType::Enum search)
|
||||
{
|
||||
for (int32_t i = 0; i < Config::MaxElementsPerTile; ++i)
|
||||
for (int32_t i = 0; i < Puzzle::Config::MaxElementsPerTile; ++i)
|
||||
{
|
||||
if (PlacedTypes[i] == search) return true;
|
||||
if (node.PlacedTypes[i] == search) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PuzzleNode::IsEmpty() const
|
||||
bool IsEmpty(const PuzzleNode& node)
|
||||
{
|
||||
for (int32_t i = 0; i < Config::MaxElementsPerTile; ++i)
|
||||
for (int32_t i = 0; i < Puzzle::Config::MaxElementsPerTile; ++i)
|
||||
{
|
||||
if (PlacedTypes[i] != PuzzleElementType::None) return false;
|
||||
if (node.PlacedTypes[i] != PuzzleElementType::None) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t PuzzleCardStack::GetRemainingCount()
|
||||
bool IsValid(StaticPuzzleCardHandle h)
|
||||
{
|
||||
assert(MaxAvailableCount >= UsedCount);
|
||||
return MaxAvailableCount - UsedCount;
|
||||
return h.Idx != UINT16_MAX;
|
||||
}
|
||||
|
||||
const PuzzleNode& PuzzleData::GetNodeAt(PuzPos pos) const
|
||||
uint8_t GetRemainingCount(const PuzzleCardStack& stack)
|
||||
{
|
||||
assert(pos.X < Config::MaxPuzzleSizeCards && pos.Y < Config::MaxPuzzleSizeCards && pos.X >= 0 && pos.Y >= 0);
|
||||
return PlacedNodes[pos.Y * Config::MaxPuzzleSizeCards + pos.X];
|
||||
assert(stack.MaxAvailableCount >= stack.UsedCount);
|
||||
return stack.MaxAvailableCount - stack.UsedCount;
|
||||
}
|
||||
|
||||
PuzzleElementType PuzzleData::GetElementAt(ElemPos pos) const
|
||||
const PuzzleNode& GetNodeAt(const PuzzleData& puz, PuzPos pos)
|
||||
{
|
||||
assert(pos.ElemIdx < Config::MaxElementsPerTile);
|
||||
const PuzzleNode& node = GetNodeAt(pos.Position);
|
||||
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];
|
||||
}
|
||||
|
||||
PuzzleElementType::Enum GetElementAt(const PuzzleData& puz, ElemPos pos)
|
||||
{
|
||||
assert(pos.ElemIdx < Puzzle::Config::MaxElementsPerTile);
|
||||
const PuzzleNode& node = GetNodeAt(puz, pos.Position);
|
||||
return node.PlacedTypes[pos.ElemIdx];
|
||||
}
|
||||
|
||||
@@ -95,26 +101,26 @@ namespace Puzzle
|
||||
|
||||
bool PuzzleSolver::IsExitSatisfied(const PuzzleData& puzzle, ElemPos pos)
|
||||
{
|
||||
const PuzzleNode& goalNode = puzzle.GetNodeAt(pos.Position);
|
||||
PuzzleElementType goalType = puzzle.GetElementAt(pos);
|
||||
const PuzzleNode& goalNode = GetNodeAt(puzzle, pos.Position);
|
||||
PuzzleElementType::Enum goalType = GetElementAt(puzzle, pos);
|
||||
|
||||
uint32_t currentPositionQueueIdx = 0;
|
||||
uint32_t positionQueueCount = 0;
|
||||
PuzPos positionQueue[Config::MaxTilesInPuzzle];
|
||||
PuzPos positionQueue[Puzzle::Config::MaxTilesInPuzzle];
|
||||
|
||||
positionQueue[0] = pos.Position;
|
||||
positionQueueCount++;
|
||||
while (positionQueueCount > 0)
|
||||
{
|
||||
assert(currentPositionQueueIdx < Config::MaxTilesInPuzzle);
|
||||
assert(currentPositionQueueIdx < Puzzle::Config::MaxTilesInPuzzle);
|
||||
PuzPos currentPos = positionQueue[currentPositionQueueIdx];
|
||||
for (PuzPos dir : Dirs)
|
||||
{
|
||||
PuzPos nextPos = currentPos + dir;
|
||||
if (IsValidGoalConnection(puzzle, nextPos, currentPos, goalType))
|
||||
{
|
||||
const PuzzleNode& node = puzzle.GetNodeAt(nextPos);
|
||||
for (PuzzleElementType e : node.PlacedTypes)
|
||||
const PuzzleNode& node = GetNodeAt(puzzle, nextPos);
|
||||
for (PuzzleElementType::Enum e : node.PlacedTypes)
|
||||
{
|
||||
if (IsValidSource(e, goalType))
|
||||
{
|
||||
@@ -133,46 +139,50 @@ namespace Puzzle
|
||||
bool PuzzleSolver::IsValidGoalConnection(const PuzzleData& puzzle,
|
||||
PuzPos flowFrom,
|
||||
PuzPos flowTo,
|
||||
PuzzleElementType goalType)
|
||||
PuzzleElementType::Enum goalType)
|
||||
{
|
||||
const PuzzleNode& from = puzzle.GetNodeAt(flowFrom);
|
||||
const PuzzleNode& to = puzzle.GetNodeAt(flowTo);
|
||||
const PuzzleNode& from = GetNodeAt(puzzle, flowFrom);
|
||||
const PuzzleNode& to = GetNodeAt(puzzle, flowTo);
|
||||
|
||||
if (goalType == PuzzleElementType::WaterGoal)
|
||||
{
|
||||
return from.HasElement(PuzzleElementType::WaterIn) || from.HasElement(PuzzleElementType::WaterChannel) ||
|
||||
from.HasElement(PuzzleElementType::WaterGoal);
|
||||
return HasElement(from, PuzzleElementType::WaterIn) || HasElement(from, PuzzleElementType::WaterChannel) ||
|
||||
HasElement(from, PuzzleElementType::WaterGoal);
|
||||
}
|
||||
else if (goalType == PuzzleElementType::ElectricGoal)
|
||||
{
|
||||
return from.HasElement(PuzzleElementType::ElectricIn) || from.HasElement(PuzzleElementType::ElectricGoal) ||
|
||||
from.IsEmpty();
|
||||
return HasElement(from, PuzzleElementType::ElectricIn) ||
|
||||
HasElement(from, PuzzleElementType::ElectricGoal) || IsEmpty(from);
|
||||
}
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
bool PuzzleSolver::IsValidSource(PuzzleElementType sourceType, PuzzleElementType goalType)
|
||||
bool PuzzleSolver::IsValidSource(PuzzleElementType::Enum sourceType, PuzzleElementType::Enum goalType)
|
||||
{
|
||||
return (sourceType == PuzzleElementType::WaterIn && goalType == PuzzleElementType::WaterGoal) ||
|
||||
(sourceType == PuzzleElementType::ElectricIn && goalType == PuzzleElementType::ElectricGoal);
|
||||
}
|
||||
|
||||
bool PuzzleData::RenderDebugUI()
|
||||
} // namespace Generated
|
||||
|
||||
namespace Generated
|
||||
{
|
||||
bool RenderDebugUI(PuzzleData& obj)
|
||||
{
|
||||
bool dataChanged = false;
|
||||
|
||||
bool isVisible = true;
|
||||
if (ImGui::Begin("Puzzle", &isVisible))
|
||||
{
|
||||
ImGui::Text("%s", PuzzleName);
|
||||
ImGui::Text("%s", obj.PuzzleName);
|
||||
|
||||
int32_t W = S.WidthTiles;
|
||||
int32_t H = S.HeightTiles;
|
||||
int32_t W = obj.WidthTiles;
|
||||
int32_t H = obj.HeightTiles;
|
||||
ImGui::PushID("width");
|
||||
ImGui::SetNextItemWidth(40);
|
||||
if (ImGui::DragInt("", &W, 0.3f, 0, Config::MaxPuzzleSizeTiles))
|
||||
if (ImGui::DragInt("", &W, 0.3f, 0, Puzzle::Config::MaxPuzzleSizeTiles))
|
||||
{
|
||||
S.WidthTiles = uint8_t(W);
|
||||
obj.WidthTiles = uint8_t(W);
|
||||
dataChanged = true;
|
||||
}
|
||||
ImGui::PopID();
|
||||
@@ -181,9 +191,9 @@ namespace Puzzle
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(40);
|
||||
ImGui::PushID("height");
|
||||
if (ImGui::DragInt("", &H, 0.3f, 0, Config::MaxPuzzleSizeTiles))
|
||||
if (ImGui::DragInt("", &H, 0.3f, 0, Puzzle::Config::MaxPuzzleSizeTiles))
|
||||
{
|
||||
S.HeightTiles = uint8_t(H);
|
||||
obj.HeightTiles = uint8_t(H);
|
||||
dataChanged = true;
|
||||
}
|
||||
ImGui::PopID();
|
||||
@@ -193,10 +203,32 @@ namespace Puzzle
|
||||
if (dataChanged)
|
||||
{
|
||||
char path[128]{0};
|
||||
bx::snprintf(path, sizeof(path), "game/data/%s.pzl", PuzzleName);
|
||||
SerializeStruct(&S, sizeof(S), path);
|
||||
bx::snprintf(path, sizeof(path), "game/data/%s.pzl", obj.PuzzleName);
|
||||
Serializer ser;
|
||||
ser.Init(path);
|
||||
if (Save(&obj, 1, ser))
|
||||
{
|
||||
LOG("Saved to %s", path);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Failed to save to %s", path);
|
||||
}
|
||||
ser.Finish();
|
||||
}
|
||||
|
||||
return isVisible;
|
||||
}
|
||||
} // namespace Puzzle
|
||||
|
||||
PuzPos operator+=(PuzPos lhs, const PuzPos& rhs)
|
||||
{
|
||||
lhs.X += rhs.X;
|
||||
lhs.Y += rhs.Y;
|
||||
return lhs;
|
||||
}
|
||||
PuzPos operator+(PuzPos lhs, const PuzPos& rhs)
|
||||
{
|
||||
lhs += rhs;
|
||||
return lhs;
|
||||
}
|
||||
} // namespace Generated
|
||||
|
||||
Reference in New Issue
Block a user