diff --git a/inkcpp/random.h b/inkcpp/random.h new file mode 100644 index 00000000..995b7947 --- /dev/null +++ b/inkcpp/random.h @@ -0,0 +1,29 @@ +#pragma once + +#include "../shared/public/system.h" + +namespace ink::runtime::internal { + /** + * @brief pseudo random number generator based on Linear Congruential Generator. + */ + class prng { + static constexpr uint32_t C = 12345; + static constexpr uint32_t A = 1103515245; + static constexpr uint32_t M = 1<<31; + public: + void srand(int32_t seed) { + _x = seed; + } + uint32_t rand() { + _x = (A*_x+ C) % M; + return _x; + } + int32_t rand(int32_t max) { + uint64_t prod = rand(); + prod *= max; + return static_cast(prod / M); + } + private: + uint32_t _x = 1337; + }; +} diff --git a/inkcpp/runner_impl.cpp b/inkcpp/runner_impl.cpp index 6a8634db..0dc95e7d 100644 --- a/inkcpp/runner_impl.cpp +++ b/inkcpp/runner_impl.cpp @@ -929,13 +929,13 @@ namespace ink::runtime::internal int sequenceLength = _eval.pop(); int index = _eval.pop(); - _eval.push(rand() % sequenceLength); // TODO: platform independance? + _eval.push(_rng.rand(sequenceLength)); } break; case Command::SEED: { // TODO: Platform independance - int seed = _eval.pop(); - srand(seed); + int32_t seed = _eval.pop(); + _rng.srand(seed); // push void (TODO) _eval.push(0); diff --git a/inkcpp/runner_impl.h b/inkcpp/runner_impl.h index c56eb280..3b32dc14 100644 --- a/inkcpp/runner_impl.h +++ b/inkcpp/runner_impl.h @@ -11,6 +11,7 @@ #include "functions.h" #include "string_table.h" #include "array.h" +#include "random.h" #include "runner.h" #include "choice.h" @@ -163,6 +164,8 @@ namespace ink::runtime::internal bool _is_falling = false; bool _saved = false; + + prng _rng{}; }; template<> diff --git a/inkcpp/value.cpp b/inkcpp/value.cpp index 8203ae1d..ba8099ba 100644 --- a/inkcpp/value.cpp +++ b/inkcpp/value.cpp @@ -2,9 +2,6 @@ #include "output.h" #include "string_table.h" -// TODO -#include - namespace ink { namespace runtime