The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
mt_rng.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2016 by Chris Beck <[email protected]>
3  Part of the Battle for Wesnoth Project http://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 "formatter.hpp"
19 #include "log.hpp"
20 #include <sstream>
21 #include <iomanip>
22 static lg::log_domain log_random("random");
23 #define DBG_RND LOG_STREAM(debug, log_random)
24 #define LOG_RND LOG_STREAM(info, log_random)
25 #define WRN_RND LOG_STREAM(warn, log_random)
26 #define ERR_RND LOG_STREAM(err, log_random)
27 
28 
29 namespace rand_rng
30 {
31 
33  random_seed_(seed_rng::next_seed()),
34  mt_(random_seed_),
35  random_calls_(0)
36 {
37 }
38 
39 
41  : random_seed_(seed)
42  , mt_(random_seed_)
43  , random_calls_(0)
44 {
45 }
46 
47 
48 mt_rng::mt_rng(const config& cfg) :
49  random_seed_(42),
50  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.
51  random_calls_(0)
52 {
53  config::attribute_value seed = cfg["random_seed"];
54  seed_random(seed.str(), cfg["random_calls"].to_int(0));
55 }
56 
57 bool mt_rng::operator== (const mt_rng & other) const {
58  return random_seed_ == other.random_seed_
59  && random_calls_ == other.random_calls_
60  && mt_ == other.mt_;
61 }
62 
64 {
65  uint32_t result = mt_();
66  ++random_calls_;
67  DBG_RND << (formatter() << "pulled user random " << result
68  << " for call " << random_calls_
69  << " with seed " << std::hex << random_seed_).str() << std::endl;
70 
71  return result;
72 }
73 
75 {
76  seed_random(mt_(),0);
77 }
78 
79 void mt_rng::seed_random(const uint32_t seed, const unsigned int call_count)
80 {
81  random_seed_ = seed;
82  mt_.seed(random_seed_);
83  discard(call_count); //mt_.discard(call_count);
84  DBG_RND << (formatter() << "Seeded random with " << std::hex << random_seed_ << " with "
85  << random_calls_ << " calls.").str() << 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 
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 void mt_rng::discard(const unsigned int call_count)
109 {
110  for(unsigned int i = 0; i < call_count; ++i) {
111  get_next_random();
112  }
113 }
114 
115 } // ends rand_rng namespace
116 
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:74
std::string str() const
Definition: config.cpp:353
uint32_t random_seed_
Initial seed for the pool.
Definition: mt_rng.hpp:68
boost::uint32_t uint32_t
Definition: xbrz.hpp:45
uint32_t get_next_random()
Get a new random number.
Definition: mt_rng.cpp:63
#define DBG_RND
Definition: mt_rng.cpp:23
void discard(const unsigned int call_count)
On my local version of boost::random, I can use mt_.discard to discard a number of rng results...
Definition: mt_rng.cpp:108
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
Definitions for the interface to Wesnoth Markup Language (WML).
std::string get_random_seed_str() const
Definition: mt_rng.cpp:99
Variant for storing WML attributes.
Definition: config.hpp:223
GLuint GLuint stream
Definition: glew.h:5239
GLuint64EXT * result
Definition: glew.h:10727
bool operator==(const mt_rng &other) const
Definition: mt_rng.cpp:57
std::ostringstream wrapper.
Definition: formatter.hpp:32
size_t i
Definition: function.cpp:1057
static lg::log_domain log_random("random")
unsigned int random_calls_
Number of time a random number is generated.
Definition: mt_rng.hpp:74
uint32_t next_seed()
Definition: seed_rng.cpp:52
Standard logging facilities (interface).
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
GLdouble s
Definition: glew.h:1358
GLsizei const GLcharARB ** string
Definition: glew.h:4503
boost::mt19937 mt_
State for the random pool (boost mersenne twister random generator).
Definition: mt_rng.hpp:71