CardGame
Rogue-like card videogame
Loading...
Searching...
No Matches
Random.h
Go to the documentation of this file.
1#ifndef RANDOM_MT_H
2#define RANDOM_MT_H
3
4#include <chrono>
5#include <random>
6
7// This header-only Random namespace implements a self-seeding Mersenne Twister.
8// Requires C++17 or newer.
9// It can be #included into as many code files as needed (The inline keyword avoids ODR violations)
10// Freely redistributable, courtesy of learncpp.com (https://www.learncpp.com/cpp-tutorial/global-random-numbers-random-h/)
11namespace Random
12{
13 // Returns a seeded Mersenne Twister
14 // Note: we'd prefer to return a std::seed_seq (to initialize a std::mt19937), but std::seed can't be copied, so it can't be returned by value.
15 // Instead, we'll create a std::mt19937, seed it, and then return the std::mt19937 (which can be copied).
16 inline std::mt19937 generate()
17 {
18 std::random_device rd{};
19
20 // Create seed_seq with clock and 7 random numbers from std::random_device
21 std::seed_seq ss{
22 static_cast<std::seed_seq::result_type>(std::chrono::steady_clock::now().time_since_epoch().count()),
23 rd(), rd(), rd(), rd(), rd(), rd(), rd()};
24
25 return std::mt19937{ss};
26 }
27
28 // Here's our global std::mt19937 object.
29 // The inline keyword means we only have one global instance for our whole program.
30 inline std::mt19937 mt{generate()}; // generates a seeded std::mt19937 and copies it into our global object
31
32 // Generate a random int between [min, max] (inclusive)
33 // * also handles cases where the two arguments have different types but can be converted to int
34 inline int get(int min, int max)
35 {
36 return std::uniform_int_distribution{min, max}(mt);
37 }
38
39 // The following function templates can be used to generate random numbers in other cases
40
41 // See https://www.learncpp.com/cpp-tutorial/function-template-instantiation/
42 // You can ignore these if you don't understand them
43
44 // Generate a random value between [min, max] (inclusive)
45 // * min and max must have the same type
46 // * return value has same type as min and max
47 // * Supported types:
48 // * short, int, long, long long
49 // * unsigned short, unsigned int, unsigned long, or unsigned long long
50 // Sample call: Random::get(1L, 6L); // returns long
51 // Sample call: Random::get(1u, 6u); // returns unsigned int
52 template <typename T>
53 T get(T min, T max)
54 {
55 return std::uniform_int_distribution<T>{min, max}(mt);
56 }
57
58 // Generate a random value between [min, max] (inclusive)
59 // * min and max can have different types
60 // * return type must be explicitly specified as a template argument
61 // * min and max will be converted to the return type
62 // Sample call: Random::get<std::size_t>(0, 6); // returns std::size_t
63 // Sample call: Random::get<std::size_t>(0, 6u); // returns std::size_t
64 // Sample call: Random::get<std::int>(0, 6u); // returns int
65 template <typename R, typename S, typename T>
66 R get(S min, T max)
67 {
68 return get<R>(static_cast<R>(min), static_cast<R>(max));
69 }
70}
71
72#endif
Definition: Random.h:12
std::mt19937 generate()
Definition: Random.h:16
int get(int min, int max)
Definition: Random.h:34
std::mt19937 mt
Definition: Random.h:30