The Battle for Wesnoth  1.15.2+dev
mt_rng.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2018 by Chris Beck <render787@gmail.com>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "mt_rng.hpp"
16 #include "seed_rng.hpp"
17 #include "config.hpp"
18 #include "log.hpp"
19 #include <sstream>
20 #include <iomanip>
21 static lg::log_domain log_random("random");
22 #define DBG_RND LOG_STREAM(debug, log_random)
23 #define LOG_RND LOG_STREAM(info, log_random)
24 #define WRN_RND LOG_STREAM(warn, log_random)
25 #define ERR_RND LOG_STREAM(err, log_random)
26 
27 
28 namespace randomness
29 {
30 
32  random_seed_(seed_rng::next_seed()),
33  mt_(random_seed_),
34  random_calls_(0)
35 {
36 }
37 
38 
39 mt_rng::mt_rng(uint32_t seed)
40  : random_seed_(seed)
41  , mt_(random_seed_)
42  , random_calls_(0)
43 {
44 }
45 
46 
47 mt_rng::mt_rng(const config& cfg) :
48  random_seed_(42),
49  mt_(random_seed_), //we don't have the seed at construction time, we have to seed after construction in this case. Constructing an mt19937 is somewhat expensive, apparently has about 2kb of private memory.
50  random_calls_(0)
51 {
52  config::attribute_value seed = cfg["random_seed"];
53  seed_random(seed.str(), cfg["random_calls"].to_int(0));
54 }
55 
56 bool mt_rng::operator== (const mt_rng & other) const {
57  return random_seed_ == other.random_seed_
58  && random_calls_ == other.random_calls_
59  && mt_ == other.mt_;
60 }
61 
63 {
64  uint32_t result = mt_();
65  ++random_calls_;
66  DBG_RND << "pulled user random " << result
67  << " for call " << random_calls_
68  << " with seed " << std::hex << random_seed_ << std::endl;
69 
70  return result;
71 }
72 
74 {
75  seed_random(mt_(),0);
76 }
77 
78 void mt_rng::seed_random(const uint32_t seed, const unsigned int call_count)
79 {
80  random_seed_ = seed;
81  mt_.seed(random_seed_);
82  mt_.discard(call_count);
83  random_calls_ = call_count;
84  DBG_RND << "Seeded random with " << std::hex << random_seed_ << std::dec << " with "
85  << random_calls_ << " calls." << std::endl;
86 }
87 
88 void mt_rng::seed_random(const std::string & seed_str, const unsigned int call_count)
89 {
90  uint32_t new_seed;
91  std::istringstream s(seed_str);
92  if (!(s >> std::hex >> new_seed)) {
93  new_seed = 42;
94  DBG_RND << "Failed to seed a random number generator using seed string '" << seed_str << "', it could not be parsed to hex. Seeding with 42.\n";
95  }
96  seed_random(new_seed, call_count);
97 }
98 
99 std::string mt_rng::get_random_seed_str() const {
100  std::stringstream stream;
101  stream << std::setfill('0');
102  stream << std::setw(sizeof(uint32_t)*2);
103  stream << std::hex;
104  stream << random_seed_;
105  return stream.str();
106 }
107 
108 } // ends randomness namespace
std::mt19937 mt_
State for the random pool (mersenne twister random generator).
Definition: mt_rng.hpp:67
uint32_t random_seed_
Initial seed for the pool.
Definition: mt_rng.hpp:64
Variant for storing WML attributes.
#define DBG_RND
Definition: mt_rng.cpp:22
uint32_t get_next_random()
Get a new random number.
Definition: mt_rng.cpp:62
unsigned int random_calls_
Number of time a random number is generated.
Definition: mt_rng.hpp:70
bool operator==(const mt_rng &other) const
Definition: mt_rng.cpp:56
Definitions for the interface to Wesnoth Markup Language (WML).
std::string get_random_seed_str() const
Definition: mt_rng.cpp:99
static map_location::DIRECTION s
void rotate_random()
Resets the random to the 0 calls and the seed to the random this way we stay in the same sequence but...
Definition: mt_rng.cpp:73
static lg::log_domain log_random("random")
uint32_t next_seed()
Definition: seed_rng.cpp:45
Standard logging facilities (interface).
void seed_random(const std::string &seed, const unsigned int call_count=0)
Same as uint32_t version, but uses a stringstream to convert given hex string.
Definition: mt_rng.cpp:88
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:68
std::string str(const std::string &fallback="") const