diff --git a/src/common/tpt-rand.cpp b/src/common/tpt-rand.cpp index be1f6aaba..7b2ddcbd1 100644 --- a/src/common/tpt-rand.cpp +++ b/src/common/tpt-rand.cpp @@ -1,5 +1,6 @@ #include "tpt-rand.h" #include +#include /* xoroshiro128+ by David Blackman and Sebastiano Vigna */ @@ -8,7 +9,7 @@ static inline uint64_t rotl(const uint64_t x, int k) return (x << k) | (x >> (64 - k)); } -uint64_t RandomGen::next() +uint64_t RNG::next() { const uint64_t s0 = s[0]; uint64_t s1 = s[1]; @@ -21,33 +22,37 @@ uint64_t RandomGen::next() return result; } -unsigned int RandomGen::operator()() +unsigned int RNG::operator()() { return next()&0xFFFFFFFF; } -unsigned int RandomGen::between(unsigned int lower, unsigned int upper) +int RNG::between(int lower, int upper) { - unsigned int r = (*this)(); - - return r % (upper - lower + 1) + lower; + unsigned int r = next(); + return static_cast(r % (upper - lower + 1)) + lower; } -float RandomGen::uniform01() +bool RNG::chance(float chance) { - return static_cast(random_gen())/(float)0xFFFFFFFF; + return uniform01() < chance; } -RandomGen::RandomGen() +float RNG::uniform01() { - s[0] = 1; - s[1] = 2; + return static_cast(next()&0xFFFFFFFF)/(float)0xFFFFFFFF; } -void RandomGen::seed(unsigned int sd) +RNG::RNG() +{ + s[0] = time(NULL); + s[1] = 614; +} + +void RNG::seed(unsigned int sd) { s[0] = sd; s[1] = sd; } -RandomGen random_gen; +RNG random_gen; diff --git a/src/common/tpt-rand.h b/src/common/tpt-rand.h index 274e452cb..198ce45bf 100644 --- a/src/common/tpt-rand.h +++ b/src/common/tpt-rand.h @@ -2,21 +2,23 @@ #define TPT_RAND_ #include +#include "Singleton.h" -class RandomGen +class RNG : public Singleton { private: uint64_t s[2]; uint64_t next(); public: unsigned int operator()(); - unsigned int between(unsigned int lower, unsigned int upper); + int between(int lower, int upper); + bool chance(float chance); float uniform01(); - RandomGen(); + RNG(); void seed(unsigned int sd); }; -extern RandomGen random_gen; +extern RNG random_gen; #endif /* TPT_RAND_ */ diff --git a/src/simulation/elements/ACID.cpp b/src/simulation/elements/ACID.cpp index 9a11bd8d6..c374ea779 100644 --- a/src/simulation/elements/ACID.cpp +++ b/src/simulation/elements/ACID.cpp @@ -69,14 +69,14 @@ int Element_ACID::update(UPDATE_FUNC_ARGS) } else if (rt == PT_WTRV) { - if(!(random_gen()%250)) + if (RNG::Ref().chance(1/250.0f)) { sim->part_change_type(i, x, y, PT_CAUS); - parts[i].life = (random_gen()%50)+25; + parts[i].life = RNG::Ref().between(25, 74); sim->kill_part(ID(r)); } } - else if ((rt != PT_CLNE && rt != PT_PCLN && (unsigned int)sim->elements[rt].Hardness>(random_gen()%1000))&&parts[i].life>=50) + else if (rt != PT_CLNE && rt != PT_PCLN && parts[i].life >= 50 && RNG::Ref().chance(sim->elements[rt].Hardness/1000.0)) { if (sim->parts_avg(i, ID(r),PT_GLAS)!= PT_GLAS)//GLAS protects stuff from acid { @@ -98,8 +98,8 @@ int Element_ACID::update(UPDATE_FUNC_ARGS) } for (trade = 0; trade<2; trade++) { - rx = random_gen()%5-2; - ry = random_gen()%5-2; + rx = RNG::Ref().between(-2, 2); + ry = RNG::Ref().between(-2, 2); if (BOUNDS_CHECK && (rx || ry)) { r = pmap[y+ry][x+rx]; diff --git a/src/simulation/elements/BANG.cpp b/src/simulation/elements/BANG.cpp index ccac93e86..dc51ca625 100644 --- a/src/simulation/elements/BANG.cpp +++ b/src/simulation/elements/BANG.cpp @@ -87,29 +87,29 @@ int Element_BANG::update(UPDATE_FUNC_ARGS) //Explode!! sim->pv[y/CELL][x/CELL] += 0.5f; parts[i].tmp = 0; - if(!(random_gen()%3)) + if (RNG::Ref().chance(1.0/3)) { - if(!(random_gen()%2)) + if (RNG::Ref().chance(1.0/2)) { sim->create_part(i, x, y, PT_FIRE); } else { sim->create_part(i, x, y, PT_SMKE); - parts[i].life = random_gen()%50+500; + parts[i].life = RNG::Ref().between(500, 549); } parts[i].temp = restrict_flt((MAX_TEMP/4)+otemp, MIN_TEMP, MAX_TEMP); } else { - if(!(random_gen()%15)) + if (RNG::Ref().chance(1.0/15)) { sim->create_part(i, x, y, PT_EMBR); parts[i].tmp = 0; parts[i].life = 50; parts[i].temp = restrict_flt((MAX_TEMP/3)+otemp, MIN_TEMP, MAX_TEMP); - parts[i].vx = random_gen()%20-10; - parts[i].vy = random_gen()%20-10; + parts[i].vx = RNG::Ref().between(-10, 10); + parts[i].vy = RNG::Ref().between(-10, 10); } else { diff --git a/src/simulation/elements/BOMB.cpp b/src/simulation/elements/BOMB.cpp index 625b8d54b..7531e1763 100644 --- a/src/simulation/elements/BOMB.cpp +++ b/src/simulation/elements/BOMB.cpp @@ -97,8 +97,8 @@ int Element_BOMB::update(UPDATE_FUNC_ARGS) parts[nb].tmp = 0; parts[nb].life = 50; parts[nb].temp = MAX_TEMP; - parts[nb].vx = random_gen()%40-20; - parts[nb].vy = random_gen()%40-20; + parts[nb].vx = RNG::Ref().between(-20, 20); + parts[nb].vy = RNG::Ref().between(-20, 20); } } sim->kill_part(i); diff --git a/src/simulation/elements/ELEC.cpp b/src/simulation/elements/ELEC.cpp index 87585ef48..7340ad28a 100644 --- a/src/simulation/elements/ELEC.cpp +++ b/src/simulation/elements/ELEC.cpp @@ -69,8 +69,8 @@ int Element_ELEC::update(UPDATE_FUNC_ARGS) parts[nb].tmp = 0; parts[nb].life = 50; parts[nb].temp = parts[i].temp*0.8f; - parts[nb].vx = random_gen()%20-10; - parts[nb].vy = random_gen()%20-10; + parts[nb].vx = RNG::Ref().between(-10, 10); + parts[nb].vy = RNG::Ref().between(-10, 10); } } sim->kill_part(i); diff --git a/src/simulation/elements/IGNT.cpp b/src/simulation/elements/IGNT.cpp index 3972e0eea..384f96681 100644 --- a/src/simulation/elements/IGNT.cpp +++ b/src/simulation/elements/IGNT.cpp @@ -66,20 +66,20 @@ int Element_IGNT::update(UPDATE_FUNC_ARGS) } else if(parts[i].life > 0) { - if(random_gen()%3) + if (RNG::Ref().chance(2.0/3)) { - int nb = sim->create_part(-1, x+random_gen()%3-1, y+random_gen()%3-1, PT_EMBR); + int nb = sim->create_part(-1, x + RNG::Ref().between(-1, 1), y + RNG::Ref().between(-1, 1), PT_EMBR); if (nb!=-1) { parts[nb].tmp = 0; parts[nb].life = 30; - parts[nb].vx = random_gen()%20-10; - parts[nb].vy = random_gen()%20-10; + parts[nb].vx = RNG::Ref().between(-10, 10); + parts[nb].vy = RNG::Ref().between(-10, 10); parts[nb].temp = restrict_flt(parts[i].temp-273.15f+400.0f, MIN_TEMP, MAX_TEMP); } } else { - sim->create_part(-1, x+random_gen()%3-1, y+random_gen()%3-1, PT_FIRE); + sim->create_part(-1, x + RNG::Ref().between(-1, 1), y + RNG::Ref().between(-1, 1), PT_FIRE); } parts[i].life--; } diff --git a/src/simulation/elements/VINE.cpp b/src/simulation/elements/VINE.cpp index 881676cd4..7b62627a5 100644 --- a/src/simulation/elements/VINE.cpp +++ b/src/simulation/elements/VINE.cpp @@ -49,7 +49,7 @@ Element_VINE::Element_VINE() //#TPT-Directive ElementHeader Element_VINE static int update(UPDATE_FUNC_ARGS) int Element_VINE::update(UPDATE_FUNC_ARGS) { - int r, np, rx, ry, rndstore = random_gen(); + int r, np, rx, ry, rndstore = random_gen()&0x7FFFFFFF; rx = (rndstore % 3) - 1; rndstore >>= 2; ry = (rndstore % 3) - 1; diff --git a/src/simulation/elements/YEST.cpp b/src/simulation/elements/YEST.cpp index a43f40a23..6b2cf4369 100644 --- a/src/simulation/elements/YEST.cpp +++ b/src/simulation/elements/YEST.cpp @@ -55,13 +55,13 @@ int Element_YEST::update(UPDATE_FUNC_ARGS) r = pmap[y+ry][x+rx]; if (!r) continue; - if (TYP(r)==PT_DYST && !(random_gen()%6) && !sim->legacy_enable) + if (TYP(r)==PT_DYST && RNG::Ref().chance(1.0/6) && !sim->legacy_enable) { sim->part_change_type(i,x,y,PT_DYST); } } - if (parts[i].temp>303&&parts[i].temp<317) { - sim->create_part(-1, x+random_gen()%3-1, y+random_gen()%3-1, PT_YEST); + if (parts[i].temp > 303 && parts[i].temp < 317) { + sim->create_part(-1, x + RNG::Ref().between(-1, 1), y + RNG::Ref().between(-1, 1), PT_YEST); } return 0; }