define range
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>,
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user