puzzle setup
This commit is contained in:
112
src/game/Puzzle.cpp
Normal file
112
src/game/Puzzle.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
#include "Puzzle.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace
|
||||
{
|
||||
static constexpr Puzzle::PuzPos Dirs[4]{
|
||||
{-1, 0},
|
||||
{0, -1},
|
||||
{0, 1},
|
||||
{1, 0},
|
||||
};
|
||||
}
|
||||
|
||||
namespace Puzzle
|
||||
{
|
||||
bool PuzzleNode::HasElement(PuzzleElementType search) const
|
||||
{
|
||||
for (int32_t i = 0; i < Config::MaxElementsPerTile; ++i)
|
||||
{
|
||||
if (PlacedTypes[i] == search) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PuzzleNode::IsEmpty() const
|
||||
{
|
||||
for (int32_t i = 0; i < Config::MaxElementsPerTile; ++i)
|
||||
{
|
||||
if (PlacedTypes[i] != PuzzleElementType::None) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t PuzzleCardStack::GetRemainingCount()
|
||||
{
|
||||
assert(MaxAvailableCount >= UsedCount);
|
||||
return MaxAvailableCount - UsedCount;
|
||||
}
|
||||
|
||||
bool PuzzleSolver::IsPuzzleSolved(const PuzzleData& puzzle)
|
||||
{
|
||||
bool IsSolved = true;
|
||||
for (uint32_t i = 0; i < puzzle.GoalPositionCount; ++i)
|
||||
{
|
||||
}
|
||||
return IsSolved;
|
||||
}
|
||||
|
||||
bool PuzzleSolver::IsExitSatisfied(const PuzzleData& puzzle, ElemPos pos)
|
||||
{
|
||||
const PuzzleNode& goalNode = puzzle.GetNodeAt(pos.Position);
|
||||
PuzzleElementType goalType = puzzle.GetElementAt(pos);
|
||||
|
||||
uint32_t currentPositionQueueIdx = 0;
|
||||
uint32_t positionQueueCount = 0;
|
||||
PuzPos positionQueue[Config::MaxTilesInPuzzle];
|
||||
|
||||
positionQueue[0] = pos.Position;
|
||||
positionQueueCount++;
|
||||
while (positionQueueCount > 0)
|
||||
{
|
||||
assert(currentPositionQueueIdx < 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)
|
||||
{
|
||||
if (IsValidSource(e, goalType))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
positionQueue[positionQueueCount] = nextPos;
|
||||
positionQueueCount++;
|
||||
}
|
||||
}
|
||||
currentPositionQueueIdx++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PuzzleSolver::IsValidGoalConnection(const PuzzleData& puzzle,
|
||||
PuzPos flowFrom,
|
||||
PuzPos flowTo,
|
||||
PuzzleElementType goalType)
|
||||
{
|
||||
const PuzzleNode& from = puzzle.GetNodeAt(flowFrom);
|
||||
const PuzzleNode& to = puzzle.GetNodeAt(flowTo);
|
||||
|
||||
if (goalType == PuzzleElementType::WaterGoal)
|
||||
{
|
||||
return from.HasElement(PuzzleElementType::WaterIn) || from.HasElement(PuzzleElementType::WaterChannel) ||
|
||||
from.HasElement(PuzzleElementType::WaterGoal);
|
||||
}
|
||||
else if (goalType == PuzzleElementType::ElectricGoal)
|
||||
{
|
||||
return from.HasElement(PuzzleElementType::ElectricIn) || from.HasElement(PuzzleElementType::ElectricGoal) ||
|
||||
from.IsEmpty();
|
||||
}
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
bool PuzzleSolver::IsValidSource(PuzzleElementType sourceType, PuzzleElementType goalType)
|
||||
{
|
||||
return (sourceType == PuzzleElementType::WaterIn && goalType == PuzzleElementType::WaterGoal) ||
|
||||
(sourceType == PuzzleElementType::ElectricIn && goalType == PuzzleElementType::ElectricGoal);
|
||||
}
|
||||
} // namespace Puzzle
|
||||
Reference in New Issue
Block a user