The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
random.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2014 - 2025
3 by David White <dave@whitevine.net>
4 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY.
12
13 See the COPYING file for more details.
14*/
15
16#pragma once
17
18#include <cstdint>
19#include <iterator> //needed for std::distance
20#include <limits>
21
22namespace randomness
23{
24 /**
25 this class does not give synced random results derived classes might do.
26 */
27 class rng : private std::numeric_limits<uint32_t>
28 {
29 using base = std::numeric_limits<uint32_t>;
30 public:
31 rng();
32 /**
33 * Provides the next random draw. This is raw PRG output.
34 */
35 uint32_t next_random();
36 virtual ~rng();
37 /**
38 * Provides the number of random calls to the rng in this context.
39 * Note that this may be different from the number of random calls to
40 * the underlying rng, and to the random_calls number in save files!
41 */
42 unsigned int get_random_calls() const;
43
44 /**
45 * This helper method provides a random int from the underlying generator,
46 * using results of next_random in a manner guaranteed to be cross platform.
47 * The result will be random in range [min,max] inclusive.
48 * @param min The minimum value produced.
49 * @param max The maximum value produced.
50 */
51 int get_random_int(int min, int max)
52 { return min + get_random_int_in_range_zero_to(max - min); }
53
54 /**
55 * This helper method returns true with the probability supplied as a parameter.
56 * @param probability The probability of returning true, from 0 to 1.
57 */
58 bool get_random_bool(double probability);
59
60 /**
61 * This helper method returns a floating-point number in the range [0,1[.
62 */
63 double get_random_double();
64
65 /**
66 * This helper method selects a random element from a container of floating-point numbers.
67 * Every number has a probability to be selected equal to the number itself
68 * (e.g. a number of 0.1 is selected with a probability of 0.1). The sum of numbers
69 * should be one.
70 * @param first Iterator to the beginning of the container
71 * @param last Iterator to the end of the container
72 * @return The index of the selected number
73 */
74 template <typename T>
75 typename T::difference_type get_random_element(T first, T last);
76
77 // For compatibility with the C++ UniformRandomBitGenerator concept
78 using result_type = uint32_t;
79 using base::min;
80 using base::max;
81 uint32_t operator()() { return next_random(); }
82
83 static rng& default_instance();
84
85 /**
86 * Is this random source networked? If it is it's very important we do actually use
87 * this random source to stay in-sync.
88 */
89 virtual bool is_networked() const { return false; }
90
91 protected:
92 virtual uint32_t next_random_impl() = 0;
93 unsigned int random_calls_;
94
95 private:
96 /** Does the hard work of get_random_int.
97 * The result will be random in range [0,max] inclusive.
98 * @param max The maximum value produced.
99 */
101 };
102
103 /**
104 This generator is automatically synced during synced context.
105 Calling this rng during a synced context automatically makes undoing impossible.
106 Outside a synced context this has the same effect as rand()
107 */
108 extern rng* generator;
109
110 template <typename T>
111 typename T::difference_type rng::get_random_element(T first, T last)
112 {
113 double target = get_random_double();
114 double sum = 0.0;
115 T it = first;
116 sum += *it;
117 while (sum <= target)
118 {
119 ++it;
120 if (it != last)
121 {
122 sum += *it;
123 }
124 else
125 {
126 break;
127 }
128 }
129 return std::distance(first, it);
130 }
131}
this class does not give synced random results derived classes might do.
Definition random.hpp:28
virtual ~rng()
Definition random.cpp:68
unsigned int get_random_calls() const
Provides the number of random calls to the rng in this context.
Definition random.cpp:79
uint32_t next_random()
Provides the next random draw.
Definition random.cpp:84
static rng & default_instance()
Definition random.cpp:73
std::numeric_limits< uint32_t > base
Definition random.hpp:29
T::difference_type get_random_element(T first, T last)
This helper method selects a random element from a container of floating-point numbers.
Definition random.hpp:111
uint32_t result_type
Definition random.hpp:78
virtual uint32_t next_random_impl()=0
unsigned int random_calls_
Definition random.hpp:93
virtual bool is_networked() const
Is this random source networked? If it is it's very important we do actually use this random source t...
Definition random.hpp:89
int get_random_int(int min, int max)
Definition random.hpp:51
bool get_random_bool(double probability)
This helper method returns true with the probability supplied as a parameter.
Definition random.cpp:136
double get_random_double()
This helper method returns a floating-point number in the range [0,1[.
Definition random.cpp:111
int get_random_int_in_range_zero_to(int max)
Does the hard work of get_random_int.
Definition random.cpp:105
uint32_t operator()()
Definition random.hpp:81
rng * generator
This generator is automatically synced during synced context.
Definition random.cpp:60