From d286beadd312c608bcfd6d10e59f039ef66b747e Mon Sep 17 00:00:00 2001 From: Olly Date: Sat, 5 Aug 2023 21:14:33 +0100 Subject: [PATCH] Better Randomize --- .../imports/simba/simba.import_random.pas | 16 ++++++++- Source/simba.init.pas | 7 ++-- Source/simba.random.pas | 34 +++++++++++++++++-- 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/Source/script/imports/simba/simba.import_random.pas b/Source/script/imports/simba/simba.import_random.pas index f434ff2ac..f2c5cfcb6 100644 --- a/Source/script/imports/simba/simba.import_random.pas +++ b/Source/script/imports/simba/simba.import_random.pas @@ -151,7 +151,7 @@ procedure _LapeRandomModeI(const Params: PParamArray; const Result: Pointer); LA (* GaussRand ~~~~~~~~~ -> function GaussRand(Mean, Dev: Double): Double +> function GaussRand(Mean, Dev: Double): Double; Generates a random gaussian/normal number. *) @@ -160,6 +160,18 @@ procedure _LapeGaussRand(const Params: PParamArray; const Result: Pointer); LAPE PDouble(Result)^ := GaussRand(PDouble(Params^[0])^, PDouble(Params^[1])^); end; +(* +Randomize +~~~~~~~~~ +> procedure Randomize; + +Generates a new `RandSeed` +*) +procedure _LapeRandomize(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV +begin + BetterRandomize(); +end; + procedure ImportRandom(Compiler: TSimbaScript_Compiler); begin with Compiler do @@ -168,6 +180,8 @@ procedure ImportRandom(Compiler: TSimbaScript_Compiler); addGlobalVar(ltDouble, @RandCutoff, 'RandCutoff'); + addGlobalFunc('procedure Randomize; override;', @_LapeRandomize); + addGlobalFunc('function RandomCenterTPA(Amount: Integer; Box: TBox): TPointArray', @_LapeRandomCenterTPA); addGlobalFunc('function RandomTPA(Amount: Integer; Box: TBox): TPointArray', @_LapeRandomTPA); diff --git a/Source/simba.init.pas b/Source/simba.init.pas index b2b7eb55f..de3bd2117 100644 --- a/Source/simba.init.pas +++ b/Source/simba.init.pas @@ -19,7 +19,8 @@ interface {$IFDEF UNIX} cthreads, {$ENDIF} - classes, sysutils, lazlogger; + Classes, SysUtils, + simba.random; implementation @@ -61,13 +62,13 @@ initialization LinuxInitialization(); {$ENDIF} - Randomize(); - FormatSettings.ThousandSeparator := ','; FormatSettings.DecimalSeparator := '.'; FormatSettings.DateSeparator := '-'; FormatSettings.TimeSeparator := ':'; + BetterRandomize(); + finalization {$IFDEF DARWIN} DarwinFinalization(); diff --git a/Source/simba.random.pas b/Source/simba.random.pas index d94a3e0f0..2ba608e62 100644 --- a/Source/simba.random.pas +++ b/Source/simba.random.pas @@ -10,7 +10,7 @@ interface uses - classes, sysutils, + Classes, SysUtils, simba.mufasatypes; function RandomCenterTPA(Amount: Integer; Box: TBox): TPointArray; @@ -30,13 +30,16 @@ function RandomMode(Mode, Lo, Hi: Int64): Int64; overload; function GaussRand(Mean, Dev: Double): Double; +procedure BetterRandomize; + var RandCutoff: Double = 5; implementation uses - math; + Math, + simba.process; function nzRandom: Double; begin @@ -139,5 +142,32 @@ function GaussRand(Mean, Dev: Double): Double; Result := Mean + Len * Cos(2 * PI * Random()); end; +{$R-}{$Q-} + +// https://github.com/dajobe/libmtwist/blob/master/seed.c +procedure BetterRandomize; + + procedure Mix(var A, B, C: UInt32); + begin + A -= C; A := A xor ((C shl 4) or (C shr (32-4))); C += B; + B -= A; B := B xor ((A shl 6) or (A shr (32-6))); A += C; + C -= B; C := C xor ((B shl 8) or (B shr (32-8))); B += A; + A -= C; A := A xor ((C shl 16) or (C shr (32-16))); C += B; + B -= A; B := B xor ((A shl 19) or (A shr (32-19))); A += C; + C -= B; C := C xor ((B shl 4) or (B shr (32-4))); B += A; + end; + +var + A, B, C: UInt32; +begin + A := UInt32(GetTickCount64()); + B := UInt32(GetProcessID()); + C := UInt32(SimbaProcess.GetProcessRunnningTime(GetProcessID())); + + Mix(A, B, C); + + RandSeed := C; +end; + end.