diff --git a/lib/std/math/math.random.c3 b/lib/std/math/math.random.c3 index a2aa6bd28..fe58f6bdb 100644 --- a/lib/std/math/math.random.c3 +++ b/lib/std/math/math.random.c3 @@ -21,6 +21,11 @@ macro void seed(random, seed) random.set_seed(@as_char_view(seed)); } +macro void seed_entropy(random) +{ + random.set_seed(&&entropy()); +} + /** * @require is_random(random) **/ @@ -29,6 +34,17 @@ macro int next(random, int max) return (int)(next_double(random) * max); } +fn int rand(int max) @builtin +{ + tlocal Sfc64Random default_random; + tlocal bool initialized = false; + if (!initialized) + { + seed_entropy(&default_random); + initialized = true; + } + return next(&default_random, max); +} /** * @require is_random(random) **/ diff --git a/lib/std/math/random/math.seeder.c3 b/lib/std/math/random/math.seeder.c3 index 8786f5daa..ba5b0a1ce 100644 --- a/lib/std/math/random/math.seeder.c3 +++ b/lib/std/math/random/math.seeder.c3 @@ -1,4 +1,5 @@ module std::math::random; +import std::hash::fnv32a; const ODD_PHI64 @local = 0x9e3779b97f4a7c15; const MUL_MCG64 @local = 0xf1357aea2e62a9c5; @@ -65,3 +66,27 @@ fn void seeder(char[] input, char[] out_buffer) out_buffer[..] = ((char*)words.ptr)[:out_chars]; }; } + +macro uint hash(value) @local +{ + return fnv32a::encode(&&bitcast(value, char[$typeof(value).sizeof])); +} + +fn char[8 * 4] entropy() +{ + void* addr = malloc(1); + free(addr); + static uint random_int; + random_int += 0xedf19156; + uint[8] entropy_data = { + hash($$TIME), + hash(addr), + hash(&addr), + hash(&entropy), + random_int, + hash(clock::now()), + hash(&DString.init), + hash(mem::heap()) + }; + return bitcast(entropy_data, char[8 * 4]); +} \ No newline at end of file diff --git a/resources/examples/contextfree/guess_number.c3 b/resources/examples/contextfree/guess_number.c3 index 770e622be..fb77eed39 100644 --- a/resources/examples/contextfree/guess_number.c3 +++ b/resources/examples/contextfree/guess_number.c3 @@ -69,10 +69,8 @@ fn void Game.update(Game *game, int guess) fn void! main() { - Lcg128Random rand; - random::seed(&rand, clock::now()); int high = 100; - int answer = random::next(&rand, high) + 1; + int answer = rand(high) + 1; Game game = { .answer = answer, .high = high }; (void)game.play(); io::printfn("Finished in %d guesses.", game.guesses); diff --git a/src/version.h b/src/version.h index 2d3b6f362..4364c0a92 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.4.692" +#define COMPILER_VERSION "0.4.693"