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);
|
||||
};
|
||||
using SudokuSolverBuilder = WFC::Builder<Sudoku>
|
||||
::DefineIDs<1, 2, 3, 4, 5, 6, 7, 8, 9>
|
||||
::DefineConstrainer<decltype([](Sudoku&, size_t index, WFC::WorldValue<uint8_t> val, auto& constrainer) {
|
||||
::DefineRange<1, 10>
|
||||
::DefineConstrainer<decltype([](Sudoku&, size_t index, WFC::WorldValue<uint8_t> val, auto& constrainer) constexpr {
|
||||
size_t x = index % 9;
|
||||
size_t y = index / 9;
|
||||
|
||||
for (size_t i = 0; i < 9; ++i)
|
||||
{
|
||||
// Add row constraints (same row, different columns)
|
||||
for (size_t i = 0; i < 9; ++i) {
|
||||
if (i != x) constrainer.Exclude(val, i + y * 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);
|
||||
if (i != y) constrainer.Exclude(val, x + i * 9);
|
||||
}
|
||||
|
||||
// Add box constraints (3x3 box)
|
||||
|
||||
@@ -308,12 +308,11 @@ private:
|
||||
|
||||
static void PropogateInitialValues(SolverState& state, WaveType& wave)
|
||||
{
|
||||
auto allValues = VariableIDMapT::GetAllValues();
|
||||
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));
|
||||
state.m_propagationQueue.push(i);
|
||||
|
||||
@@ -28,7 +28,13 @@ public:
|
||||
using ConstrainerType = Constrainer<WaveType, PropagationQueueType>;
|
||||
|
||||
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>
|
||||
requires ConstrainerFunction<ConstrainerFunctionT, WorldT, VarT, WaveType, PropagationQueueType>
|
||||
|
||||
@@ -31,7 +31,7 @@ template<std::size_t I,
|
||||
typename SelectedIDsVariableIDMapT,
|
||||
typename EmptyFunctionT>
|
||||
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,
|
||||
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>,
|
||||
|
||||
@@ -101,7 +101,7 @@ public:
|
||||
std::array<uint16_t, VariableIDMapT::ValuesRegisteredAmount> weights{};
|
||||
|
||||
for (size_t i = 0; i < VariableIDMapT::ValuesRegisteredAmount; ++i) {
|
||||
weights[i] = GetWeightForValue(VariableIDMapT::GetValueConsteval(i));
|
||||
weights[i] = GetWeightForValue(VariableIDMapT::GetValue(i));
|
||||
}
|
||||
|
||||
return weights;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <concepts>
|
||||
#include "wfc_utils.hpp"
|
||||
|
||||
namespace WFC {
|
||||
@@ -10,6 +11,7 @@ namespace WFC {
|
||||
* This class is used to map variable values to indices at compile time.
|
||||
* It is a compile-time map of variable values to indices.
|
||||
*/
|
||||
|
||||
template <typename VarT, VarT ... Values>
|
||||
class VariableIDMap {
|
||||
public:
|
||||
@@ -55,17 +57,11 @@ public:
|
||||
return std::span<const VarT>{ allValues, ValuesRegisteredAmount };
|
||||
}
|
||||
|
||||
static VarT GetValue(size_t index) {
|
||||
static constexpr VarT GetValue(size_t index) {
|
||||
constexpr_assert(index < ValuesRegisteredAmount);
|
||||
return GetAllValues()[index];
|
||||
}
|
||||
|
||||
static consteval VarT GetValueConsteval(size_t index)
|
||||
{
|
||||
constexpr VarT arr[] = {Values...};
|
||||
return arr[index];
|
||||
}
|
||||
|
||||
static consteval size_t size() { return ValuesRegisteredAmount; }
|
||||
|
||||
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