rj-action-library/Runtime/Random/LCG.cs

85 lines
2.2 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System;
using Godot;
namespace Rokojori
{
[System.Serializable]
public class LCGSeedState
{
public int modulus;
public int multiplier;
public int increment;
public int state;
}
public class LCG:SeedableRandomEngine
{
private LCGSeedState _seedState = new LCGSeedState();
private float _normalizer;
public LCG()
{
this.setParameters( (int)Mathf.Pow(2,32), 1664525, 1013904223 );
}
public static LCG Randomized()
{
var ms = Time.GetUnixTimeFromSystem() % 1;
var seed = (int) ( ms * 10000 );
var lcg = new LCG();
// RJLog.Log( "Seed", seed, Time.GetUnixTimeFromSystem() );
lcg.SetSeed( seed );
lcg.Next();
return lcg;
}
void setParameters( int modulus, int multiplier, int increment )
{
_seedState.modulus = modulus;
_seedState.multiplier = multiplier;
_seedState.increment = increment;
_seedState.state = 0;
this._normalizer = 1f/(_seedState.modulus);
}
public override object GetSeedState()
{
var seedState = new LCGSeedState();
seedState.modulus = _seedState.modulus;
seedState.multiplier = _seedState.multiplier;
seedState.increment = _seedState.increment;
seedState.state = _seedState.state;
return seedState;
}
public override void SetSeedState( object seedStateObject )
{
var seedState = (LCGSeedState) seedStateObject;
_seedState.modulus = seedState.modulus;
_seedState.multiplier = seedState.multiplier;
_seedState.increment = seedState.increment;
_seedState.state = seedState.state;
this._normalizer = 1 / ( _seedState.modulus );
}
public override float Next()
{
_seedState.state = ( _seedState.state * _seedState.multiplier + _seedState.increment) % _seedState.modulus;
var value = _seedState.state * this._normalizer;
return Mathf.Abs( value );
}
public override void SetSeed( int seed )
{
_seedState.state = seed % _seedState.modulus;
}
}
}