#pragma once #include #include #include #include #include #include "KPlayer.h" namespace KapitanGame { namespace Utils { template std::string StringFormat(const std::string& format, Args ... args) { const int sizeS = std::snprintf(nullptr, 0, format.c_str(), args ...) + 1; // Extra space for '\0' if (sizeS <= 0) { throw std::runtime_error("Error during formatting."); } const auto size = static_cast(sizeS); const auto buf = std::make_unique(size); std::snprintf(buf.get(), size, format.c_str(), args ...); return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside } template constexpr const T& Clamp(const T& x, const T& min, const T& max) { return std::max(std::min(max, x), min); } template constexpr const T& Clamp01(const T& x) { return Clamp(x, 0.f, 1.f); } template constexpr const T& Lerp(const T& a, const T& b, const float& t) { return a + (b - a) * Clamp01(t); } static std::default_random_engine make_default_random_engine() { // This gets a source of actual, honest-to-god randomness std::random_device source; // Here, we fill an array of random data from the source unsigned int random_data[10]; for (auto& elem : random_data) { elem = source(); } // this creates the random seed sequence out of the random data std::seed_seq seq(random_data + 0, random_data + 10); return std::default_random_engine{ seq }; } inline std::default_random_engine& GetRandomEngine() { // Making rng static ensures that it stays the same // Between different invocations of the function static std::default_random_engine rng(make_default_random_engine()); return rng; } inline double RandomNumber() { const std::uniform_real_distribution dist(0.0, 1.0); return dist(GetRandomEngine()); } template class Iterator { typedef std::underlying_type_t ValT; int Value; public: explicit Iterator(const C& f) : Value(static_cast(f)) {} Iterator() : Value(static_cast(BeginVal)) {} Iterator operator++() { ++Value; return *this; } C operator*() { return static_cast(Value); } Iterator begin() { return *this; } //default ctor is good Iterator end() { static const Iterator END_ITERATE = ++Iterator(EndVal); // cache it return END_ITERATE; } bool operator!=(const Iterator& i) { return Value != i.Value; } }; inline KPlayer GetPlayerFromString(const std::string& str) { static std::unordered_map const TABLE = { {"Player1",KPlayer::Player1},{"Player2",KPlayer::Player2} }; const auto it = TABLE.find(str); if (it != TABLE.end()) { return it->second; } return KPlayer::Player1; } typedef Iterator KPlayerIterator; struct PairHash { template std::size_t operator () (const std::pair& p) const { auto h1 = std::hash{}(p.first); auto h2 = std::hash{}(p.second); return h1 ^ h2; } }; } }