define range

This commit is contained in:
cdemeyer-teachx
2025-09-14 15:28:02 +09:00
parent 14aa93ada0
commit 41bdd79f27
6 changed files with 60 additions and 23 deletions

View File

@@ -316,19 +316,17 @@ private:
static bool parseLine(const std::string& line, std::array<uint8_t, 81>& board); static bool parseLine(const std::string& line, std::array<uint8_t, 81>& board);
}; };
using SudokuSolverBuilder = WFC::Builder<Sudoku> using SudokuSolverBuilder = WFC::Builder<Sudoku>
::DefineIDs<1, 2, 3, 4, 5, 6, 7, 8, 9> ::DefineRange<1, 10>
::DefineConstrainer<decltype([](Sudoku&, size_t index, WFC::WorldValue<uint8_t> val, auto& constrainer) { ::DefineConstrainer<decltype([](Sudoku&, size_t index, WFC::WorldValue<uint8_t> val, auto& constrainer) constexpr {
size_t x = index % 9; size_t x = index % 9;
size_t y = index / 9; size_t y = index / 9;
// Add row constraints (same row, different columns) for (size_t i = 0; i < 9; ++i)
for (size_t i = 0; i < 9; ++i) { {
// Add row constraints (same row, different columns)
if (i != x) constrainer.Exclude(val, i + y * 9); if (i != x) constrainer.Exclude(val, i + y * 9);
} // Add column constraints (same column, different rows)
if (i != y) constrainer.Exclude(val, x + i * 9);
// Add column constraints (same column, different rows)
for (size_t i = 0; i < 9; ++i) {
if (i != y) constrainer.Exclude(val,x + i * 9);
} }
// Add box constraints (3x3 box) // Add box constraints (3x3 box)

View File

@@ -308,12 +308,11 @@ private:
static void PropogateInitialValues(SolverState& state, WaveType& wave) static void PropogateInitialValues(SolverState& state, WaveType& wave)
{ {
auto allValues = VariableIDMapT::GetAllValues();
for (size_t i = 0; i < wave.size(); ++i) for (size_t i = 0; i < wave.size(); ++i)
{ {
for (size_t j = 0; j < allValues.size(); ++j) for (size_t j = 0; j < VariableIDMapT::size(); ++j)
{ {
if (state.m_world.getValue(i) == allValues[j]) if (state.m_world.getValue(i) == VariableIDMapT::GetValue(j))
{ {
CollapseCell(state, wave, static_cast<uint16_t>(i), static_cast<uint16_t>(j)); CollapseCell(state, wave, static_cast<uint16_t>(i), static_cast<uint16_t>(j));
state.m_propagationQueue.push(i); state.m_propagationQueue.push(i);

View File

@@ -28,7 +28,13 @@ public:
using ConstrainerType = Constrainer<WaveType, PropagationQueueType>; using ConstrainerType = Constrainer<WaveType, PropagationQueueType>;
template <VarT ... Values> template <VarT ... Values>
using DefineIDs = Builder<WorldT, VarT, typename VariableIDMapT::template Merge<Values...>, ConstrainerFunctionMapT, CallbacksT, RandomSelectorT>; using DefineIDs = Builder<WorldT, VarT, VariableIDMap<VarT, Values...>, ConstrainerFunctionMapT, CallbacksT, RandomSelectorT>;
template <size_t RangeStart, size_t RangeEnd>
using DefineRange = Builder<WorldT, VarT, VariableIDRange<VarT, RangeStart, RangeEnd>, ConstrainerFunctionMapT, CallbacksT, RandomSelectorT>;
template <size_t RangeEnd>
using DefineRange0 = Builder<WorldT, VarT, VariableIDRange<VarT, 0, RangeEnd>, ConstrainerFunctionMapT, CallbacksT, RandomSelectorT>;
template <typename ConstrainerFunctionT, VarT ... CorrespondingValues> template <typename ConstrainerFunctionT, VarT ... CorrespondingValues>
requires ConstrainerFunction<ConstrainerFunctionT, WorldT, VarT, WaveType, PropagationQueueType> requires ConstrainerFunction<ConstrainerFunctionT, WorldT, VarT, WaveType, PropagationQueueType>

View File

@@ -31,7 +31,7 @@ template<std::size_t I,
typename SelectedIDsVariableIDMapT, typename SelectedIDsVariableIDMapT,
typename EmptyFunctionT> typename EmptyFunctionT>
using MergedConstrainerElementSelector = using MergedConstrainerElementSelector =
std::conditional_t<SelectedIDsVariableIDMapT::template HasValue<VariableIDMapT::GetValueConsteval(I)>(), // if the value is in the selected IDs std::conditional_t<SelectedIDsVariableIDMapT::template HasValue<VariableIDMapT::GetValue(I)>(), // if the value is in the selected IDs
NewConstrainerFunctionT, NewConstrainerFunctionT,
std::conditional_t<(I < ConstrainerFunctionMapT::size()), // if the index is within the size of the tuple std::conditional_t<(I < ConstrainerFunctionMapT::size()), // if the index is within the size of the tuple
std::tuple_element_t<std::min(I, ConstrainerFunctionMapT::size() - 1), typename ConstrainerFunctionMapT::TupleType>, std::tuple_element_t<std::min(I, ConstrainerFunctionMapT::size() - 1), typename ConstrainerFunctionMapT::TupleType>,

View File

@@ -101,7 +101,7 @@ public:
std::array<uint16_t, VariableIDMapT::ValuesRegisteredAmount> weights{}; std::array<uint16_t, VariableIDMapT::ValuesRegisteredAmount> weights{};
for (size_t i = 0; i < VariableIDMapT::ValuesRegisteredAmount; ++i) { for (size_t i = 0; i < VariableIDMapT::ValuesRegisteredAmount; ++i) {
weights[i] = GetWeightForValue(VariableIDMapT::GetValueConsteval(i)); weights[i] = GetWeightForValue(VariableIDMapT::GetValue(i));
} }
return weights; return weights;

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include <concepts>
#include "wfc_utils.hpp" #include "wfc_utils.hpp"
namespace WFC { namespace WFC {
@@ -10,6 +11,7 @@ namespace WFC {
* This class is used to map variable values to indices at compile time. * This class is used to map variable values to indices at compile time.
* It is a compile-time map of variable values to indices. * It is a compile-time map of variable values to indices.
*/ */
template <typename VarT, VarT ... Values> template <typename VarT, VarT ... Values>
class VariableIDMap { class VariableIDMap {
public: public:
@@ -55,17 +57,11 @@ public:
return std::span<const VarT>{ allValues, ValuesRegisteredAmount }; return std::span<const VarT>{ allValues, ValuesRegisteredAmount };
} }
static VarT GetValue(size_t index) { static constexpr VarT GetValue(size_t index) {
constexpr_assert(index < ValuesRegisteredAmount); constexpr_assert(index < ValuesRegisteredAmount);
return GetAllValues()[index]; return GetAllValues()[index];
} }
static consteval VarT GetValueConsteval(size_t index)
{
constexpr VarT arr[] = {Values...};
return arr[index];
}
static consteval size_t size() { return ValuesRegisteredAmount; } static consteval size_t size() { return ValuesRegisteredAmount; }
template <VarT ... ValuesSlice> template <VarT ... ValuesSlice>
@@ -75,5 +71,43 @@ public:
} }
}; };
template <typename VarT, size_t Start, size_t End>
class VariableIDRange
{
public:
using Type = VarT;
static_assert(Start < End, "Start must be less than End");
static_assert(std::numeric_limits<VarT>::min() <= Start, "VarT must be able to represent all values in the range");
static_assert(std::numeric_limits<VarT>::max() >= End, "VarT must be able to represent all values in the range");
static constexpr size_t ValuesRegisteredAmount = End - Start;
template <VarT Value>
static consteval bool HasValue()
{
return Value >= Start && Value < End;
}
template <VarT Value>
static consteval size_t GetIndex()
{
return Value - Start;
}
static constexpr VarT GetValue(size_t index)
{
return Start + index;
}
static consteval size_t size() { return End - Start; }
template <VarT ... ValuesSlice>
static constexpr auto ValuesToIndices() -> std::array<size_t, sizeof...(ValuesSlice)> {
std::array<size_t, sizeof...(ValuesSlice)> indices = {GetIndex<ValuesSlice>()...};
return indices;
}
};
} }