#include #include #include #include #include #include #include namespace s2ga { template struct always_false: std::false_type { }; class lehmer64 { public: lehmer64(__uint128_t seed = 0) { this->seed(seed); } void seed(__uint128_t z) { if(z == 0) { z = 0xC0FFEE; } s = z; } uint64_t operator()() noexcept { s *= 0xda942042e4dd58b5; return s >> 64; } static constexpr uint64_t min() { return 0; } static constexpr uint64_t max() { return UINT64_MAX; } template T random(T min, T max) { if constexpr(std::is_integral_v) { return std::uniform_int_distribution(min, max)(*this); } else if constexpr(std::is_floating_point_v) { return std::uniform_real_distribution(min, max)(*this); } else { static_assert(always_false::value, "unsupported distribution type"); } } private: __uint128_t s; }; static_assert(std::uniform_random_bit_generator); template requires std::is_enum_v && ((std::is_same_v), ...) std::bitset()> bm(const Args&... v) //aka "bitmask" { constexpr size_t N = magic_enum::enum_count(); std::bitset bitmask; ((bitmask.set(magic_enum::enum_integer(v))), ...); return bitmask; } template requires std::is_enum_v struct action { static constexpr size_t N = magic_enum::enum_count(); std::string name = "ACTION"; float cost = 1.0f; std::bitset positive_effects{}; std::bitset negative_effects{}; std::bitset positive_preconds{}; std::bitset negative_preconds{}; bool preconds_met(const std::bitset& state) const { return ((state & positive_preconds) == positive_preconds) && (state & ~negative_preconds).none(); } std::bitset apply(const std::bitset& state) const { return (state | positive_effects) & ~negative_effects; } void print() { std::cout << std::format("[{}, {}]", name, cost) << std::endl; if(positive_effects.any() || negative_effects.any()) { std::cout << "Effects:" << std::endl; for(size_t i = 0; i < N; ++i) { if(positive_effects.test(i) || negative_effects.test(i)) { auto enum_value = magic_enum::enum_cast(i).value(); auto value_name = magic_enum::enum_name(enum_value); std::cout << std::format(" {}{}", negative_effects.test(i) ? "-" : "+", value_name) << std::endl; } } } if(positive_preconds.any() || negative_preconds.any()) { std::cout << "Preconditions:" << std::endl; for(size_t i = 0; i < N; ++i) { if(positive_preconds.test(i) || negative_preconds.test(i)) { auto enum_value = magic_enum::enum_cast(i).value(); auto value_name = magic_enum::enum_name(enum_value); std::cout << std::format(" {}{}", negative_preconds.test(i) ? "-" : "+", value_name) << std::endl; } } } } }; template requires std::is_enum_v using action_list = std::vector>; }; // namespace s2ga inline void foo() { }