diff --git a/include/nd-wfc/wfc.hpp b/include/nd-wfc/wfc.hpp index 4e86edf..7ad1cf0 100644 --- a/include/nd-wfc/wfc.hpp +++ b/include/nd-wfc/wfc.hpp @@ -26,6 +26,9 @@ namespace WFC { +struct EmptyInitialState {}; + + template concept WorldType = requires(T world, typename T::ValueType value) { { world.size() } -> std::integral; @@ -69,7 +72,8 @@ struct SolverState { // Types-only config struct produced by Builder template + typename ConstrainerFunctionMapT, typename CallbacksT, typename RandomSelectorT, + typename InitialStateFunctionT = EmptyInitialState> struct WFCConfig { static_assert(WorldType, "WorldT must satisfy World type requirements"); @@ -79,6 +83,8 @@ struct WFCConfig { using WaveType = Wave; using CallbacksType = CallbacksT; using ConstrainerFunctionMapType = ConstrainerFunctionMapT; + using InitialStateFunctionType = InitialStateFunctionT; + static consteval bool HasInitialState() { return !std::is_same_v; } }; // Forward declarations for mutually recursive functions @@ -289,6 +295,13 @@ bool Run(typename ConfigT::SolverStateType& state) detail::PropogateInitialValues(state, wave); + if constexpr (ConfigT::HasInitialState()) + { + using ConstrainerType = Constrainer; + ConstrainerType constrainer(wave, state.m_propagationQueue); + typename ConfigT::InitialStateFunctionType{}(state.m_world, constrainer, state.m_randomSelector); + } + if (RunLoop(state, wave)) { detail::PopulateWorld(state, wave); return true; diff --git a/include/nd-wfc/wfc_builder.hpp b/include/nd-wfc/wfc_builder.hpp index a4309cc..03688bc 100644 --- a/include/nd-wfc/wfc_builder.hpp +++ b/include/nd-wfc/wfc_builder.hpp @@ -13,13 +13,14 @@ namespace WFC { * @brief Builder class for creating WFC instances */ template< - typename WorldT, - typename VarT = typename WorldT::ValueType, - typename VariableIDMapT = VariableIDMap, - typename ConstrainerFunctionMapT = ConstrainerFunctionMap, - typename CallbacksT = Callbacks, + typename WorldT, + typename VarT = typename WorldT::ValueType, + typename VariableIDMapT = VariableIDMap, + typename ConstrainerFunctionMapT = ConstrainerFunctionMap, + typename CallbacksT = Callbacks, typename RandomSelectorT = DefaultRandomSelector, - typename SelectedValueT = void> + typename SelectedValueT = void, + typename InitialStateFunctionT = EmptyInitialState> class Builder { public: using WorldSizeT = decltype(WorldT{}.size()); @@ -31,22 +32,22 @@ public: template - using DefineIDs = Builder, ConstrainerFunctionMapT, CallbacksT, RandomSelectorT, VariableIDMap>; + using DefineIDs = Builder, ConstrainerFunctionMapT, CallbacksT, RandomSelectorT, VariableIDMap, InitialStateFunctionT>; template - using DefineRange = Builder, ConstrainerFunctionMapT, CallbacksT, RandomSelectorT, VariableIDRange>; + using DefineRange = Builder, ConstrainerFunctionMapT, CallbacksT, RandomSelectorT, VariableIDRange, InitialStateFunctionT>; template - using DefineRange0 = Builder, ConstrainerFunctionMapT, CallbacksT, RandomSelectorT, VariableIDRange>; + using DefineRange0 = Builder, ConstrainerFunctionMapT, CallbacksT, RandomSelectorT, VariableIDRange, InitialStateFunctionT>; template - using Variable = Builder>; + using Variable = Builder, InitialStateFunctionT>; template - using VariableRange = Builder>; + using VariableRange = Builder, InitialStateFunctionT>; + - using EmptyConstrainerFunctionT = EmptyConstrainerFunction; template @@ -58,7 +59,7 @@ public: ConstrainerFunctionT, SelectedValueT, EmptyConstrainerFunctionT - >, CallbacksT, RandomSelectorT, SelectedValueT + >, CallbacksT, RandomSelectorT, SelectedValueT, InitialStateFunctionT >; template @@ -70,22 +71,25 @@ public: ConstrainerFunctionT, VariableIDMapT, EmptyConstrainerFunctionT - >, CallbacksT, RandomSelectorT + >, CallbacksT, RandomSelectorT, SelectedValueT, InitialStateFunctionT >; - + template - using SetCellCollapsedCallback = Builder, RandomSelectorT>; + using SetCellCollapsedCallback = Builder, RandomSelectorT, SelectedValueT, InitialStateFunctionT>; template - using SetContradictionCallback = Builder, RandomSelectorT>; + using SetContradictionCallback = Builder, RandomSelectorT, SelectedValueT, InitialStateFunctionT>; template - using SetBranchCallback = Builder, RandomSelectorT>; + using SetBranchCallback = Builder, RandomSelectorT, SelectedValueT, InitialStateFunctionT>; template - using SetRandomSelector = Builder; + using SetRandomSelector = Builder; - using Build = WFCConfig; + template + using SetInitialState = Builder; + + using Build = WFCConfig; }; -} \ No newline at end of file +}