2dkg/2dkg_zad5/2dgk_zad5/Utils.h
2022-01-20 08:52:14 +01:00

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;
}
};
}
}