]> git.localhorst.tv Git - blank.git/commitdiff
avoid library rand()
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 28 Aug 2015 09:15:13 +0000 (11:15 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 28 Aug 2015 13:44:48 +0000 (15:44 +0200)
src/ai/RandomWalk.hpp
src/ai/Spawner.cpp
src/ai/Spawner.hpp
src/ai/ai.cpp
src/app/WorldState.cpp
src/rand/GaloisLFSR.hpp
src/rand/noise.cpp

index a25d4db502bedf56ca98affa5997ff89646185cf..4d00f0bbdc53276b06df664fb87d23d6c1856ac0 100644 (file)
@@ -3,6 +3,8 @@
 
 #include "Controller.hpp"
 
+#include "../rand/GaloisLFSR.hpp"
+
 
 namespace blank {
 
@@ -11,12 +13,13 @@ class RandomWalk
 : public Controller {
 
 public:
-       explicit RandomWalk(Entity &) noexcept;
+       RandomWalk(Entity &, std::uint64_t seed) noexcept;
        ~RandomWalk();
 
        void Update(int dt) override;
 
 private:
+       GaloisLFSR random;
        int time_left;
 
 };
index 1120b5b320c5987d415243314d3c58cf7c33ce37..fb2a1eafc46c69906826e98c91f0ed117eb70f97 100644 (file)
 
 namespace blank {
 
-Spawner::Spawner(World &world)
+Spawner::Spawner(World &world, std::uint64_t seed)
 : world(world)
 , controllers()
+, random(seed)
 , timer(64)
 , despawn_range(128 * 128)
 , spawn_distance(16 * 16)
@@ -97,15 +98,15 @@ void Spawner::TrySpawn() {
        if (controllers.size() >= max_entities) return;
 
        glm::ivec3 chunk(
-               (rand() % (chunk_range * 2 + 1)) - chunk_range,
-               (rand() % (chunk_range * 2 + 1)) - chunk_range,
-               (rand() % (chunk_range * 2 + 1)) - chunk_range
+               (random.Next<unsigned char>() % (chunk_range * 2 + 1)) - chunk_range,
+               (random.Next<unsigned char>() % (chunk_range * 2 + 1)) - chunk_range,
+               (random.Next<unsigned char>() % (chunk_range * 2 + 1)) - chunk_range
        );
 
        glm::ivec3 pos(
-               rand() % Chunk::width,
-               rand() % Chunk::height,
-               rand() % Chunk::depth
+               random.Next<unsigned char>() % Chunk::width,
+               random.Next<unsigned char>() % Chunk::height,
+               random.Next<unsigned char>() % Chunk::depth
        );
 
 
@@ -132,20 +133,20 @@ void Spawner::TrySpawn() {
 
 void Spawner::Spawn(const glm::ivec3 &chunk, const glm::vec3 &pos) {
        glm::vec3 rot(0.000001f);
-       rot.x *= (rand() % 1024);
-       rot.y *= (rand() % 1024);
-       rot.z *= (rand() % 1024);
+       rot.x *= (random.Next<unsigned short>() % 1024);
+       rot.y *= (random.Next<unsigned short>() % 1024);
+       rot.z *= (random.Next<unsigned short>() % 1024);
 
        Entity &e = world.AddEntity();
        e.Name("spawned");
        e.Position(chunk, pos);
        e.Bounds({ { -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f } });
        e.WorldCollidable(true);
-       skeletons[rand() % 3].Instantiate(e.GetModel());
+       skeletons[random.Next<unsigned char>() % 3].Instantiate(e.GetModel());
        e.AngularVelocity(rot);
        Controller *ctrl;
-       if (rand() % 2) {
-               ctrl = new RandomWalk(e);
+       if (random()) {
+               ctrl = new RandomWalk(e, random.Next<std::uint64_t>());
        } else {
                ctrl = new Chaser(world, e, world.Player());
        }
index 7b56130f5f090aba00cfe9426637b1aa7d7d4bab..9fb3d368de0dcd2a02156006422526a54a95a53f 100644 (file)
@@ -4,6 +4,7 @@
 #include "../app/IntervalTimer.hpp"
 #include "../model/CompositeModel.hpp"
 #include "../model/EntityModel.hpp"
+#include "../rand/GaloisLFSR.hpp"
 
 #include <vector>
 #include <glm/glm.hpp>
@@ -17,7 +18,7 @@ class World;
 class Spawner {
 
 public:
-       explicit Spawner(World &);
+       Spawner(World &, std::uint64_t seed);
        ~Spawner();
 
        void Update(int dt);
@@ -34,6 +35,8 @@ private:
        EntityModel models[3];
        CompositeModel skeletons[3];
 
+       GaloisLFSR random;
+
        IntervalTimer timer;
        float despawn_range;
        float spawn_distance;
index e0fb9555adc0430d5f32daeeaa137b3771064588..4a2e3102b90d7f6dbdb88ba1bf39d2bd80d171bd 100644 (file)
@@ -61,8 +61,9 @@ Controller::~Controller() {
 }
 
 
-RandomWalk::RandomWalk(Entity &e) noexcept
+RandomWalk::RandomWalk(Entity &e, std::uint64_t seed) noexcept
 : Controller(e)
+, random(seed)
 , time_left(0) {
 
 }
@@ -74,13 +75,13 @@ RandomWalk::~RandomWalk() {
 void RandomWalk::Update(int dt) {
        time_left -= dt;
        if (time_left > 0) return;
-       time_left += 2500 + (rand() % 5000);
+       time_left += 2500 + (random.Next<unsigned short>() % 5000);
 
        constexpr float move_vel = 0.0005f;
 
        glm::vec3 new_vel = Controlled().Velocity();
 
-       switch (rand() % 9) {
+       switch (random.Next<unsigned char>() % 9) {
                case 0:
                        new_vel.x = -move_vel;
                        break;
index ed711bfc8c15e6fde8999f9846b5184b77fed3d5..243b0a1dc519d42ba18d1e6350e60864896480ba 100644 (file)
@@ -18,7 +18,7 @@ WorldState::WorldState(
 , block_types()
 , world(block_types, wc, save)
 , chunk_renderer(world, wc.load.load_dist)
-, spawner(world)
+, spawner(world, wc.gen.seed)
 , interface(ic, env, world)
 , preload(env, world.Loader(), chunk_renderer)
 , unload(env, world.Loader()) {
index 88a1d37e899f1b26e369a727a804d7755ba7d33e..395ff8f0546cc7b75cf111a4b996a7705052f29b 100644 (file)
@@ -11,10 +11,21 @@ class GaloisLFSR {
 
 public:
        // seed should be non-zero
-       explicit GaloisLFSR(std::uint64_t seed) noexcept;
+       explicit GaloisLFSR(std::uint64_t seed) noexcept
+       : state(seed) { }
 
        // get the next bit
-       bool operator ()() noexcept;
+       bool operator ()() noexcept {
+               bool result = state & 1;
+               state >>= 1;
+               if (result) {
+                       state |= 0x8000000000000000;
+                       state ^= mask;
+               } else {
+                       state &= 0x7FFFFFFFFFFFFFFF;
+               }
+               return result;
+       }
 
        template<class T>
        T operator ()(T &out) noexcept {
@@ -27,12 +38,19 @@ public:
                return out = static_cast<T>(state);
        }
 
+       template<class T>
+       T Next() noexcept {
+               T next;
+               return (*this)(next);
+       }
+
 private:
        std::uint64_t state;
        // bits 64, 63, 61, and 60 set to 1 (counting from 1 lo to hi)
        static constexpr std::uint64_t mask = 0xD800000000000000;
 
 };
+
 }
 
 #endif
index de037ef1a7c66aa5d71de9d57a18ff44892e411f..664096dc36c5559bb87ae86021072cf2ee0779ab 100644 (file)
@@ -14,24 +14,6 @@ constexpr float one_sixth = 1.0f/6.0f;
 
 namespace blank {
 
-GaloisLFSR::GaloisLFSR(std::uint64_t seed) noexcept
-: state(seed) {
-
-}
-
-bool GaloisLFSR::operator ()() noexcept {
-       bool result = state & 1;
-       state >>= 1;
-       if (result) {
-               state |= 0x8000000000000000;
-               state ^= mask;
-       } else {
-               state &= 0x7FFFFFFFFFFFFFFF;
-       }
-       return result;
-}
-
-
 SimplexNoise::SimplexNoise(unsigned int seed) noexcept
 : grad({
        {  1.0f,  1.0f,  0.0f },