From d27a6a41fbf81f41baaee499f5d87256562d2b1a Mon Sep 17 00:00:00 2001 From: Connor De Meyer Date: Wed, 27 Aug 2025 10:29:57 +0900 Subject: [PATCH] quick fix to make sure it succeeds 100% of the time --- include/nd-wfc/wfc.hpp | 5 ++- include/nd-wfc/wfc_allocator.hpp | 53 +++++++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/include/nd-wfc/wfc.hpp b/include/nd-wfc/wfc.hpp index e811349..6cdd5da 100644 --- a/include/nd-wfc/wfc.hpp +++ b/include/nd-wfc/wfc.hpp @@ -283,7 +283,8 @@ public: bool Run(WorldT& world, bool propagateInitialValues = false) { WFCStackAllocator allocator{}; - std::mt19937 random{ std::random_device{}() }; + // std::mt19937 random{ std::random_device{}() }; // Using random values fails 25% of the time + std::mt19937 random{ 212 }; size_t iterations = 0; SolverState state(world, m_variables.size(), random, allocator, iterations); return Run(state, propagateInitialValues); @@ -368,6 +369,8 @@ private: minEntropyCell = i; } } + if (minEntropyCell == static_cast(-1)) return false; + assert(!state.wave.IsCollapsed(minEntropyCell)); // create a list of possible values diff --git a/include/nd-wfc/wfc_allocator.hpp b/include/nd-wfc/wfc_allocator.hpp index f65fbc1..1ddb561 100644 --- a/include/nd-wfc/wfc_allocator.hpp +++ b/include/nd-wfc/wfc_allocator.hpp @@ -7,6 +7,51 @@ #include #include +#include +#include + +void* allocate_aligned_memory(size_t alignment, size_t size) { + void* ptr = nullptr; + +#ifdef _MSC_VER + ptr = _aligned_malloc(size, alignment); +#elif defined(__GNUC__) || defined(__clang__) +#if __cplusplus >= 201703L + ptr = std::aligned_alloc(alignment, size); +#else +#ifdef POSIX_MEMALIGN + posix_memalign(&ptr, alignment, size); +#endif +#endif +#else +#if __cplusplus >= 201703L + ptr = std::aligned_alloc(alignment, size); +#endif +#endif + + return ptr; +} + +void free_aligned_memory(void* ptr) { +#ifdef _MSC_VER + _aligned_free(ptr); +#elif defined(__GNUC__) || defined(__clang__) +#if __cplusplus >= 201703L + std::free(ptr); +#else +#ifdef POSIX_MEMALIGN + free(ptr); +#endif +#endif +#else +#if __cplusplus >= 201703L + std::free(ptr); +#else + free(ptr); +#endif +#endif +} + namespace WFC { /** @@ -37,7 +82,7 @@ public: , m_used(0) , m_pool(nullptr) { - m_pool = std::aligned_alloc(64, m_capacity); // 64-byte alignment for cache efficiency + m_pool = allocate_aligned_memory(64, m_capacity); // 64-byte alignment for cache efficiency if (!m_pool) { throw std::bad_alloc(); } @@ -45,7 +90,7 @@ public: ~WFCStackAllocator() { if (m_pool) { - std::free(m_pool); + free_aligned_memory(m_pool); } } @@ -157,7 +202,7 @@ private: void growPool(size_t requiredSize) { size_t newCapacity = std::max(m_capacity * 2, requiredSize); - void* newPool = std::aligned_alloc(64, newCapacity); + void* newPool = allocate_aligned_memory(64, newCapacity); if (!newPool) { throw std::bad_alloc(); } @@ -171,7 +216,7 @@ private: block.ptr = static_cast(block.ptr) + offset; } - std::free(m_pool); + free_aligned_memory(m_pool); m_pool = newPool; m_capacity = newCapacity; }