2025-03-09 23:28:43 +03:00
|
|
|
#include <random>
|
2025-03-12 18:49:28 +03:00
|
|
|
#include <bitset>
|
|
|
|
#include <magic_enum/magic_enum.hpp>
|
|
|
|
#include <type_traits>
|
|
|
|
#include <iostream>
|
|
|
|
#include <format>
|
2025-03-12 21:44:21 +03:00
|
|
|
#include <vector>
|
2025-03-09 23:28:43 +03:00
|
|
|
|
|
|
|
namespace s2ga
|
2025-03-08 20:37:26 +03:00
|
|
|
{
|
2025-03-09 23:28:43 +03:00
|
|
|
template<class... T>
|
|
|
|
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;
|
|
|
|
}
|
2025-03-08 20:37:26 +03:00
|
|
|
|
2025-03-09 23:28:43 +03:00
|
|
|
static constexpr uint64_t max()
|
|
|
|
{
|
|
|
|
return UINT64_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
T random(T min, T max)
|
|
|
|
{
|
|
|
|
if constexpr(std::is_integral_v<T>)
|
|
|
|
{
|
|
|
|
return std::uniform_int_distribution<T>(min, max)(*this);
|
|
|
|
}
|
|
|
|
else if constexpr(std::is_floating_point_v<T>)
|
|
|
|
{
|
|
|
|
return std::uniform_real_distribution<T>(min, max)(*this);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
static_assert(always_false<T>::value,
|
|
|
|
"unsupported distribution type");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
__uint128_t s;
|
|
|
|
};
|
|
|
|
|
|
|
|
static_assert(std::uniform_random_bit_generator<lehmer64>);
|
2025-03-12 18:49:28 +03:00
|
|
|
|
|
|
|
template<typename E, typename... Args>
|
|
|
|
requires std::is_enum_v<E> && ((std::is_same_v<E, Args>), ...)
|
|
|
|
std::bitset<magic_enum::enum_count<E>()> bm(const Args&... v) //aka "bitmask"
|
|
|
|
{
|
|
|
|
constexpr size_t N = magic_enum::enum_count<E>();
|
|
|
|
std::bitset<N> bitmask;
|
|
|
|
|
|
|
|
((bitmask.set(magic_enum::enum_integer(v))), ...);
|
|
|
|
return bitmask;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename E>
|
|
|
|
requires std::is_enum_v<E>
|
|
|
|
struct action
|
|
|
|
{
|
|
|
|
static constexpr size_t N = magic_enum::enum_count<E>();
|
|
|
|
|
|
|
|
std::string name = "ACTION";
|
|
|
|
float cost = 1.0f;
|
|
|
|
|
|
|
|
std::bitset<N> positive_effects{};
|
|
|
|
std::bitset<N> negative_effects{};
|
|
|
|
std::bitset<N> positive_preconds{};
|
|
|
|
std::bitset<N> negative_preconds{};
|
|
|
|
|
|
|
|
bool preconds_met(const std::bitset<N>& state) const
|
|
|
|
{
|
|
|
|
return ((state & positive_preconds) == positive_preconds) &&
|
|
|
|
(state & ~negative_preconds).none();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::bitset<N> apply(const std::bitset<N>& 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<E>(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<E>(i).value();
|
|
|
|
auto value_name = magic_enum::enum_name(enum_value);
|
|
|
|
|
|
|
|
std::cout << std::format(" {}{}",
|
|
|
|
negative_preconds.test(i) ? "-" : "+",
|
|
|
|
value_name) << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2025-03-12 21:44:21 +03:00
|
|
|
|
|
|
|
template<typename E>
|
|
|
|
requires std::is_enum_v<E>
|
|
|
|
using action_list = std::vector<action<E>>;
|
2025-03-09 23:28:43 +03:00
|
|
|
}; // namespace s2ga
|
|
|
|
|
|
|
|
inline void foo()
|
|
|
|
{
|
2025-03-08 20:37:26 +03:00
|
|
|
}
|