-
Notifications
You must be signed in to change notification settings - Fork 0
/
Random.cpp
102 lines (83 loc) · 3.17 KB
/
Random.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
///---------------------------------------------------------------------------------------------------------------------
/// Random.cpp
///
/// Authors: Tutors
///---------------------------------------------------------------------------------------------------------------------
#include "Random.hpp"
#include <stdexcept>
#include <iostream>
#include <cstdlib>
#include <sstream>
#include <string>
using Oop::Random;
///---------------------------------------------------------------------------------------------------------------------
std::string const Random::CARD_SEED{"RAND_SEED"};
std::string const Random::ORIENTATION_SEED{"RAND_SEED"};
size_t const Random::ORIENTATION_MIN{0};
size_t const Random::ORIENTATION_MAX{3};
///---------------------------------------------------------------------------------------------------------------------
Random::Random() :
card_mersenne_twister_{getSeed(CARD_SEED)},
orientation_mersenne_twister_{getSeed(ORIENTATION_SEED)},
orientations_{ORIENTATION_MIN, ORIENTATION_MAX}
{
}
///---------------------------------------------------------------------------------------------------------------------
Random& Random::getInstance()
{
static Random instance{};
return instance;
}
///---------------------------------------------------------------------------------------------------------------------
size_t Random::getRandomCard(size_t const number_of_cards_left)
{
std::uniform_int_distribution<size_t> normal_distribution{1, number_of_cards_left};
return normal_distribution(card_mersenne_twister_);
}
///---------------------------------------------------------------------------------------------------------------------
size_t Random::getRandomOrientation()
{
return orientations_(orientation_mersenne_twister_);
}
///---------------------------------------------------------------------------------------------------------------------
size_t Random::getSeed(std::string const environment_variable)
{
size_t seed{};
try
{
seed = getEnvironmentSeed(environment_variable);
}
catch (std::runtime_error& exception)
{
seed = getHardwareSeed();
}
return seed;
}
///---------------------------------------------------------------------------------------------------------------------
size_t Random::getEnvironmentSeed(std::string const environment_variable)
{
char* environment_seed{getenv(environment_variable.c_str())};
if (environment_seed)
{
return parseSeed(environment_seed);
}
throw std::runtime_error{"Environment variable \"" + environment_variable + "\" does not exist."};
}
///---------------------------------------------------------------------------------------------------------------------
size_t Random::getHardwareSeed()
{
std::random_device seed_from_hardware{};
return seed_from_hardware();
}
///---------------------------------------------------------------------------------------------------------------------
size_t Random::parseSeed(std::string const seed)
{
std::stringstream seed_stream{seed};
size_t seed_value{};
seed_stream >> seed_value;
if (seed_stream.eof() && !seed_stream.bad())
{
return seed_value;
}
throw std::runtime_error{"Could not parse the seed \"" + seed + "\"."};
}