110 lines
3.2 KiB
C
110 lines
3.2 KiB
C
|
#pragma once
|
||
|
#include <memory>
|
||
|
#include <string>
|
||
|
#include <stdexcept>
|
||
|
#include <random>
|
||
|
#include <unordered_map>
|
||
|
|
||
|
#include "KPlayer.h"
|
||
|
|
||
|
namespace KapitanGame {
|
||
|
namespace Utils {
|
||
|
|
||
|
template<typename ... Args>
|
||
|
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<size_t>(sizeS);
|
||
|
const auto buf = std::make_unique<char[]>(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 <class T>
|
||
|
constexpr const T& Clamp(const T& x, const T& min, const T& max)
|
||
|
{
|
||
|
return std::max(std::min(max, x), min);
|
||
|
}
|
||
|
template <class T>
|
||
|
constexpr const T& Clamp01(const T& x)
|
||
|
{
|
||
|
return Clamp(x, 0.f, 1.f);
|
||
|
}
|
||
|
template <class T>
|
||
|
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<double> dist(0.0, 1.0);
|
||
|
return dist(GetRandomEngine());
|
||
|
}
|
||
|
|
||
|
template <typename C, C BeginVal, C EndVal>
|
||
|
class Iterator {
|
||
|
typedef std::underlying_type_t<C> ValT;
|
||
|
int Value;
|
||
|
public:
|
||
|
explicit Iterator(const C& f) : Value(static_cast<ValT>(f)) {}
|
||
|
Iterator() : Value(static_cast<ValT>(BeginVal)) {}
|
||
|
Iterator operator++() {
|
||
|
++Value;
|
||
|
return *this;
|
||
|
}
|
||
|
C operator*() { return static_cast<C>(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<std::string, KPlayer> 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<KPlayer, KPlayer::Player1, KPlayer::Player1> KPlayerIterator;
|
||
|
|
||
|
struct PairHash {
|
||
|
template <class T1, class T2>
|
||
|
std::size_t operator () (const std::pair<T1, T2>& p) const {
|
||
|
auto h1 = std::hash<T1>{}(p.first);
|
||
|
auto h2 = std::hash<T2>{}(p.second);
|
||
|
return h1 ^ h2;
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
}
|