Lazarus
Engine for creating roguelikes in C++
 All Classes Namespaces Functions
Random.h
1 #pragma once
2 
3 #include <stdexcept>
4 #include <random>
5 #include <type_traits>
6 
7 #include <lazarus/common.h>
8 
9 namespace lz
10 {
25 class Random
26 {
27 public:
32  static void seed();
33 
41  static void seed(unsigned seed);
42 
54  template <typename T, typename U,
55  typename std::enable_if_t<
56  (std::is_integral<T>::value || std::is_unsigned<T>::value)
57  && (std::is_integral<U>::value || std::is_unsigned<U>::value)
58  >* = nullptr>
59  static typename std::common_type<T, U>::type range(T a, U b)
60  {
61  typedef typename std::common_type<T, U>::type common_type;
62  auto _a = static_cast<common_type>(a);
63  auto _b = static_cast<common_type>(b);
64  if (_a > _b)
65  std::swap(_a, _b);
66  return std::uniform_int_distribution<common_type>(_a, _b)(generator);
67  }
68 
81  template <typename T, typename U,
82  typename std::enable_if_t<
83  std::is_floating_point<T>::value || std::is_floating_point<U>::value
84  >* = nullptr>
85  static typename std::common_type<T, U>::type range(T a, U b)
86  {
87  typedef typename std::common_type<T, U>::type common_type;
88  auto _a = static_cast<common_type>(a);
89  auto _b = static_cast<common_type>(b);
90  if (_a > _b)
91  std::swap(_a, _b);
92  return std::uniform_real_distribution<common_type>(_a, _b)(generator);
93  }
94 
99  static ulong roll(unsigned sides=6, unsigned times=1);
100 
104  static bool oneIn(unsigned n);
105 
115  static double normal(double mean, double stdev);
116 
124  template <typename C, typename T = typename C::value_type>
125  static T& choice(C& container);
126 
127 private:
128  static std::mt19937 generator;
129 };
130 
131 template <typename C, typename T>
132 T& Random::choice(C& container)
133 {
134  // Use size() instead of empty() to make conditions less restrictive
135  size_t size = container.size();
136  if (size == 0)
137  throw __lz::LazarusException("Container is empty");
138 
139  size_t idx = Random::range(0, size - 1);
140  return container[idx];
141 }
142 
143 } // namespace lz
static ulong roll(unsigned sides=6, unsigned times=1)
Rolls a dice with the specified number of sides a certain number of times and returns the total resul...
Definition: Random.cpp:32
static void seed()
Sets a new seed for the random generator using a hardware random device if available, or a seed using the current time.
Definition: Random.cpp:11
static T & choice(C &container)
Return a reference to a random item from a container.
Definition: Random.h:132
Definition: common.h:21
static std::common_type< T, U >::type range(T a, U b)
Return a random integral between the two given numbers with equal probability.
Definition: Random.h:59
The Random class provides a simple interface for commonly used RNG functionality. ...
Definition: Random.h:25
static double normal(double mean, double stdev)
Return a random number generated from a normal distribution.
Definition: Random.cpp:52
static bool oneIn(unsigned n)
Return true with a 1 in n probability.
Definition: Random.cpp:45