17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-17 05:09:20 +02:00

seed the random engines from the system pool, not std::random_device

This commit is contained in:
maj00r
2026-09-14 17:34:59 +02:00
parent c3007e3237
commit ff3daea78c
5 changed files with 53 additions and 10 deletions

View File

@@ -321,7 +321,7 @@ int eu07_application::init(int Argc, char *Argv[])
} }
if (!Global.random_seed) if (!Global.random_seed)
Global.random_seed = std::random_device{}(); Global.random_seed = clock_seed();
Global.random_engine.seed(Global.random_seed); Global.random_engine.seed(Global.random_seed);
// configure the OS console according to Globals.ShowSystemConsole. // configure the OS console according to Globals.ShowSystemConsole.
@@ -1140,10 +1140,21 @@ int eu07_application::init_settings(int Argc, char *Argv[])
Global.local_start_vehicle = ToLower(Argv[++i]); Global.local_start_vehicle = ToLower(Argv[++i]);
} }
} }
else if (token == "-seed")
{
// a number is the seed; anything else is a word that stands for one. said in the
// log as it was given, because that is what gets passed on to somebody else
if (i + 1 < Argc)
{
Global.random_seed = seed_of(Argv[++i]);
WriteLog("seed given on the command line: " + std::string(Argv[i]) + " -> " + std::to_string(Global.random_seed));
}
}
else else
{ {
std::cout << "usage: " << std::string(Argv[0]) << " [-s sceneryfilepath]" std::cout << "usage: " << std::string(Argv[0]) << " [-s sceneryfilepath]"
<< " [-v vehiclename]" << std::endl; << " [-v vehiclename]"
<< " [-seed number|word]" << std::endl;
return -1; return -1;
} }
} }
@@ -1421,7 +1432,7 @@ int eu07_application::init_data()
int eu07_application::init_modes() int eu07_application::init_modes()
{ {
Global.local_random_engine.seed(std::random_device{}()); Global.local_random_engine.seed(clock_seed());
if ((!Global.network_servers.empty() || Global.network_client) && Global.SceneryFile.empty()) if ((!Global.network_servers.empty() || Global.network_client) && Global.SceneryFile.empty())
{ {

View File

@@ -403,10 +403,9 @@ std::string *brush_object_list::GetRandomObject()
if (Objects.empty()) if (Objects.empty())
return &empty; return &empty;
static std::mt19937 rng{std::random_device{}()};
std::uniform_int_distribution<size_t> dist(0, Objects.size() - 1); std::uniform_int_distribution<size_t> dist(0, Objects.size() - 1);
return &Objects[dist(rng)]; return &Objects[dist(Global.local_random_engine)];
} }
void brush_object_list::render() void brush_object_list::render()

View File

@@ -15,6 +15,8 @@ Copyright (C) 2007-2014 Maciej Cierniak
// //
//#include <sys/types.h> //#include <sys/types.h>
//#include <sys/stat.h> //#include <sys/stat.h>
#include <charconv>
#include <ctime>
#include <ranges> #include <ranges>
//#ifndef WIN32 //#ifndef WIN32
//#include <unistd.h> //#include <unistd.h>
@@ -30,7 +32,6 @@ Copyright (C) 2007-2014 Maciej Cierniak
#include "utilities/U8.h" #include "utilities/U8.h"
//#include "utilities/Logs.h"
// TODO: This shouldn't be in Globals? // TODO: This shouldn't be in Globals?
bool DebugModeFlag = false; bool DebugModeFlag = false;
@@ -137,15 +138,35 @@ int Random(int min, int max)
return dist(Global.random_engine); return dist(Global.random_engine);
} }
std::uint32_t clock_seed()
{
static std::atomic<std::uint32_t> nth{0};
return static_cast<std::uint32_t>(std::time({})) + nth.fetch_add(1, std::memory_order_relaxed);
}
std::uint32_t seed_of(std::string const &Text)
{
std::uint32_t number{};
if (std::from_chars(Text.data(), Text.data() + Text.size(), number).ec == std::errc{})
{
return number;
}
std::uint32_t hash{};
for (auto const character : Text)
{
hash = hash * 31u + static_cast<std::uint32_t>(static_cast<unsigned char>(character));
}
return hash;
}
std::string generate_uuid_v4() std::string generate_uuid_v4()
{ {
std::random_device rd; static thread_local std::mt19937 generator{clock_seed()};
std::mt19937 gen(rd());
std::uniform_int_distribution<int> dist(0, 255); std::uniform_int_distribution<int> dist(0, 255);
std::array<uint8_t, 16> bytes; std::array<uint8_t, 16> bytes;
for (auto &b : bytes) for (auto &b : bytes)
b = static_cast<uint8_t>(dist(gen)); b = static_cast<uint8_t>(dist(generator));
// UUID v4 (RFC 4122) // UUID v4 (RFC 4122)
bytes[6] = bytes[6] & 0x0F | 0x40; bytes[6] = bytes[6] & 0x0F | 0x40;

View File

@@ -62,6 +62,17 @@ inline long Round(double const f)
double Random(double a, double b); double Random(double a, double b);
int Random(int min, int max); int Random(int min, int max);
// Seed for the random engines: the clock, plus a counter so two engines seeded in
// the same second do not come out the same.
std::uint32_t clock_seed();
// The seed a word stands for. A number is taken as it is written; anything else is
// hashed the way Java's String.hashCode does it, so the same word gives the same
// world on every platform and every build - which is the whole point of telling
// somebody a seed.
std::uint32_t seed_of(std::string const &Text);
std::string generate_uuid_v4(); std::string generate_uuid_v4();
double LocalRandom(double a, double b); double LocalRandom(double a, double b);

View File

@@ -6,6 +6,7 @@
#include <string> #include <string>
#include <algorithm> #include <algorithm>
#include <cstdint> #include <cstdint>
#include "utilities/utilities.h"
class UID { class UID {
public: public:
@@ -13,7 +14,7 @@ public:
static UID random() { static UID random() {
static thread_local std::mt19937_64 gen(std::random_device{}()); static thread_local std::mt19937_64 gen{clock_seed()};
UID u; UID u;
uint64_t a = gen(); uint64_t a = gen();
uint64_t b = gen(); uint64_t b = gen();