From 41bdd79f270a86c4c95902d461c1c5b8b354e398 Mon Sep 17 00:00:00 2001 From: cdemeyer-teachx Date: Sun, 14 Sep 2025 15:28:02 +0900 Subject: [PATCH] define range --- demos/sudoku/sudoku.h | 18 +++++------ include/nd-wfc/wfc.hpp | 5 ++- include/nd-wfc/wfc_builder.hpp | 8 ++++- include/nd-wfc/wfc_constrainer.hpp | 2 +- include/nd-wfc/wfc_random.hpp | 2 +- include/nd-wfc/wfc_variable_map.hpp | 48 ++++++++++++++++++++++++----- 6 files changed, 60 insertions(+), 23 deletions(-) diff --git a/demos/sudoku/sudoku.h b/demos/sudoku/sudoku.h index 8d0ffd2..c1c230c 100644 --- a/demos/sudoku/sudoku.h +++ b/demos/sudoku/sudoku.h @@ -316,19 +316,17 @@ private: static bool parseLine(const std::string& line, std::array& board); }; using SudokuSolverBuilder = WFC::Builder - ::DefineIDs<1, 2, 3, 4, 5, 6, 7, 8, 9> - ::DefineConstrainer val, auto& constrainer) { + ::DefineRange<1, 10> + ::DefineConstrainer val, auto& constrainer) constexpr { size_t x = 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); - } - - // 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 column constraints (same column, different rows) + if (i != y) constrainer.Exclude(val, x + i * 9); } // Add box constraints (3x3 box) diff --git a/include/nd-wfc/wfc.hpp b/include/nd-wfc/wfc.hpp index d31ec67..3f230f8 100644 --- a/include/nd-wfc/wfc.hpp +++ b/include/nd-wfc/wfc.hpp @@ -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(i), static_cast(j)); state.m_propagationQueue.push(i); diff --git a/include/nd-wfc/wfc_builder.hpp b/include/nd-wfc/wfc_builder.hpp index 9d42351..020051f 100644 --- a/include/nd-wfc/wfc_builder.hpp +++ b/include/nd-wfc/wfc_builder.hpp @@ -28,7 +28,13 @@ public: using ConstrainerType = Constrainer; template - using DefineIDs = Builder, ConstrainerFunctionMapT, CallbacksT, RandomSelectorT>; + using DefineIDs = Builder, ConstrainerFunctionMapT, CallbacksT, RandomSelectorT>; + + template + using DefineRange = Builder, ConstrainerFunctionMapT, CallbacksT, RandomSelectorT>; + + template + using DefineRange0 = Builder, ConstrainerFunctionMapT, CallbacksT, RandomSelectorT>; template requires ConstrainerFunction diff --git a/include/nd-wfc/wfc_constrainer.hpp b/include/nd-wfc/wfc_constrainer.hpp index 58fdd6d..e05f4c0 100644 --- a/include/nd-wfc/wfc_constrainer.hpp +++ b/include/nd-wfc/wfc_constrainer.hpp @@ -31,7 +31,7 @@ template using MergedConstrainerElementSelector = - std::conditional_t(), // if the value is in the selected IDs + std::conditional_t(), // 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, diff --git a/include/nd-wfc/wfc_random.hpp b/include/nd-wfc/wfc_random.hpp index fb713ba..2319c19 100644 --- a/include/nd-wfc/wfc_random.hpp +++ b/include/nd-wfc/wfc_random.hpp @@ -101,7 +101,7 @@ public: std::array weights{}; for (size_t i = 0; i < VariableIDMapT::ValuesRegisteredAmount; ++i) { - weights[i] = GetWeightForValue(VariableIDMapT::GetValueConsteval(i)); + weights[i] = GetWeightForValue(VariableIDMapT::GetValue(i)); } return weights; diff --git a/include/nd-wfc/wfc_variable_map.hpp b/include/nd-wfc/wfc_variable_map.hpp index a4d553c..367fa5f 100644 --- a/include/nd-wfc/wfc_variable_map.hpp +++ b/include/nd-wfc/wfc_variable_map.hpp @@ -1,5 +1,6 @@ #pragma once +#include #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 class VariableIDMap { public: @@ -55,17 +57,11 @@ public: return std::span{ 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 @@ -75,5 +71,43 @@ public: } }; +template +class VariableIDRange +{ +public: + using Type = VarT; + + static_assert(Start < End, "Start must be less than End"); + static_assert(std::numeric_limits::min() <= Start, "VarT must be able to represent all values in the range"); + static_assert(std::numeric_limits::max() >= End, "VarT must be able to represent all values in the range"); + + static constexpr size_t ValuesRegisteredAmount = End - Start; + + template + static consteval bool HasValue() + { + return Value >= Start && Value < End; + } + + template + 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 + static constexpr auto ValuesToIndices() -> std::array { + std::array indices = {GetIndex()...}; + return indices; + } +}; + } \ No newline at end of file