diff --git a/demos/random_selector_example.cpp b/demos/random_selector_example.cpp deleted file mode 100644 index 0034481..0000000 --- a/demos/random_selector_example.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/** - * @brief Example demonstrating custom random selectors in WFC - * - * This example shows how to use different random selection strategies - * in the Wave Function Collapse algorithm, including: - * - Default constexpr random selector - * - Advanced random selector with std::mt19937 - * - Custom lambda-based selectors - */ - -#include -#include -#include -#include - -#include "../include/nd-wfc/wfc.hpp" - -// Simple test world for demonstration -struct SimpleWorld { - using ValueType = int; - std::vector data; - size_t grid_size; - - SimpleWorld(size_t size) : data(size * size, 0), grid_size(size) {} - size_t size() const { return data.size(); } - void setValue(size_t id, int value) { data[id] = value; } - int getValue(size_t id) const { return data[id]; } - - void print() const { - for (size_t i = 0; i < grid_size; ++i) { - for (size_t j = 0; j < grid_size; ++j) { - std::cout << data[i * grid_size + j] << " "; - } - std::cout << std::endl; - } - } -}; - -int main() { - std::cout << "=== WFC Random Selector Examples ===\n\n"; - - // Example 1: Using the default constexpr random selector - std::cout << "1. Default Random Selector (constexpr-friendly):\n"; - { - WFC::DefaultRandomSelector selector(0x12345678); - - // Test with some sample values - std::array values = {1, 2, 3, 4}; - std::span span(values.data(), values.size()); - - std::cout << "Possible values: "; - for (int v : values) std::cout << v << " "; - std::cout << "\nSelected indices: "; - - for (int i = 0; i < 8; ++i) { - size_t index = selector(span); - std::cout << index << "(" << values[index] << ") "; - } - std::cout << "\n\n"; - } - - // Example 2: Using the advanced random selector - std::cout << "2. Advanced Random Selector (std::mt19937):\n"; - { - std::mt19937 rng(54321); - WFC::AdvancedRandomSelector selector(rng); - - std::array values = {10, 20, 30, 40, 50}; - std::span span(values.data(), values.size()); - - std::cout << "Possible values: "; - for (int v : values) std::cout << v << " "; - std::cout << "\nSelected values: "; - - for (int i = 0; i < 10; ++i) { - size_t index = selector(span); - std::cout << values[index] << " "; - } - std::cout << "\n\n"; - } - - // Example 3: Custom lambda selector that always picks the first element - std::cout << "3. Custom Lambda Selector (always first):\n"; - { - auto firstSelector = [](std::span values) -> size_t { - return 0; // Always pick first - }; - - std::array values = {100, 200, 300}; - std::span span(values.data(), values.size()); - - std::cout << "Possible values: "; - for (int v : values) std::cout << v << " "; - std::cout << "\nSelected values: "; - - for (int i = 0; i < 5; ++i) { - size_t index = firstSelector(span); - std::cout << values[index] << " "; - } - std::cout << "\n\n"; - } - - // Example 4: Stateful lambda selector with captured variables - std::cout << "4. Stateful Lambda Selector (round-robin):\n"; - { - int callCount = 0; - auto roundRobinSelector = [&callCount](std::span values) mutable -> size_t { - return callCount++ % values.size(); - }; - - std::array values = {1, 2, 3}; - std::span span(values.data(), values.size()); - - std::cout << "Possible values: "; - for (int v : values) std::cout << v << " "; - std::cout << "\nRound-robin selection: "; - - for (int i = 0; i < 9; ++i) { - size_t index = roundRobinSelector(span); - std::cout << values[index] << " "; - } - std::cout << "\n\n"; - } - - // Example 5: Custom selector with probability weighting - std::cout << "5. Weighted Random Selector:\n"; - { - std::mt19937 rng(99999); - auto weightedSelector = [&rng](std::span values) -> size_t { - // Simple weighted selection - favor earlier indices - std::vector weights; - for (size_t i = 0; i < values.size(); ++i) { - weights.push_back(1.0 / (i + 1.0)); // Higher weight for lower indices - } - - std::discrete_distribution dist(weights.begin(), weights.end()); - return dist(rng); - }; - - std::array values = {1, 2, 3, 4}; - std::span span(values.data(), values.size()); - - std::cout << "Possible values: "; - for (int v : values) std::cout << v << " "; - std::cout << "\nWeighted selection ( favors lower values): "; - - for (int i = 0; i < 12; ++i) { - size_t index = weightedSelector(span); - std::cout << values[index] << " "; - } - std::cout << "\n\n"; - } - - // Example 6: Integration with WFC Builder - std::cout << "6. WFC Builder Integration:\n"; - { - // Define a simple WFC setup with custom random selector - using VariableMap = WFC::VariableIDMap; - - // Using default random selector - using DefaultWFC = WFC::Builder - ::SetRandomSelector> - ::Build; - - // Using advanced random selector - using AdvancedWFC = WFC::Builder - ::SetRandomSelector> - ::Build; - - // Note: Lambda types cannot be used directly as template parameters - // Instead, you would create a custom selector class: - // class CustomSelector { - // public: - // size_t operator()(std::span values) const { - // return values.size() > 1 ? 1 : 0; - // } - // }; - // using CustomWFC = WFC::Builder - // ::SetRandomSelector - // ::Build; - - std::cout << "Successfully created WFC types with different random selectors:\n"; - std::cout << "- DefaultWFC with DefaultRandomSelector\n"; - std::cout << "- AdvancedWFC with AdvancedRandomSelector\n"; - std::cout << "- Custom selector classes can be created for lambda-like behavior\n"; - } - - std::cout << "\n=== Examples completed successfully! ===\n"; - - return 0; -} diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 46b5285..bece00e 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -5,122 +5,6 @@ #include "nd-wfc/wfc.hpp" #include "nd-wfc/worlds.hpp" -// Test world for demonstration -struct TestWorld { - using ValueType = int; - std::vector data; - - TestWorld(size_t size) : data(size, 0) {} - size_t size() const { return data.size(); } - void setValue(size_t id, int value) { data[id] = value; } - int getValue(size_t id) const { return data[id]; } -}; - -// Test random selectors -TEST(RandomSelectorTest, DefaultRandomSelector) { - using namespace WFC; - - // Test default random selector with constexpr capabilities - DefaultRandomSelector selector(12345); - - std::array testValues = {1, 2, 3}; - std::span span(testValues.data(), testValues.size()); - - // Test that selector returns valid indices - size_t index1 = selector(span); - size_t index2 = selector(span); - - EXPECT_LT(index1, testValues.size()); - EXPECT_LT(index2, testValues.size()); - EXPECT_GE(index1, 0); - EXPECT_GE(index2, 0); -} - -TEST(RandomSelectorTest, AdvancedRandomSelector) { - using namespace WFC; - - std::mt19937 rng(54321); - AdvancedRandomSelector selector(rng); - - std::array testValues = {10, 20, 30, 40}; - std::span span(testValues.data(), testValues.size()); - - // Test that selector returns valid indices - size_t index = selector(span); - EXPECT_LT(index, testValues.size()); - EXPECT_GE(index, 0); - - // Verify the selected value matches - EXPECT_EQ(testValues[index], span[index]); -} - -TEST(RandomSelectorTest, CustomLambdaSelector) { - using namespace WFC; - - // Custom selector that always picks the first element - auto firstSelector = [](std::span values) -> size_t { - return 0; - }; - - std::array testValues = {100, 200, 300}; - std::span span(testValues.data(), testValues.size()); - - size_t index = firstSelector(span); - EXPECT_EQ(index, 0); - EXPECT_EQ(span[index], 100); -} - -TEST(RandomSelectorTest, StatefulLambdaSelector) { - using namespace WFC; - - // Stateful selector that cycles through options - uint32_t callCount = 0; - auto cyclingSelector = [&callCount](std::span values) mutable -> size_t { - return callCount++ % values.size(); - }; - - std::array testValues = {1, 2, 3}; - std::span span(testValues.data(), testValues.size()); - - // Test multiple calls - EXPECT_EQ(cyclingSelector(span), 0); - EXPECT_EQ(cyclingSelector(span), 1); - EXPECT_EQ(cyclingSelector(span), 2); - EXPECT_EQ(cyclingSelector(span), 0); // Should cycle back -} - -TEST(RandomSelectorTest, WFCIntegration) { - using namespace WFC; - - // Create a simple WFC setup with custom random selector - using VariableMap = VariableIDMap; - using CustomWFC = Builder - ::SetRandomSelector> - ::Build; - - TestWorld world(4); - uint32_t seed = 12345; - - // This should compile and run without errors - // (Note: This is a basic integration test - full WFC solving would require proper constraints) - SUCCEED(); -} - -TEST(RandomSelectorTest, ConstexprDefaultSelector) { - using namespace WFC; - - // Test that default selector can be used in constexpr context - constexpr DefaultRandomSelector selector(0xDEADBEEF); - - constexpr std::array testValues = {42, 84}; - constexpr auto span = std::span(testValues.data(), testValues.size()); - - // This should compile in constexpr context - constexpr size_t index = selector(span); - EXPECT_LT(index, testValues.size()); - EXPECT_GE(index, 0); -} - int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS();