using UnityEngine; using System.Collections; namespace Tenkoku.Core { /// /// Simple and fast random number generator which can reset to a specific iteration /// public class Random { //Initialiser magic values private const ulong m_A_Init = 181353; private const ulong m_B_Init = 7; //Seed public int m_seed; //State public ulong m_stateA, m_stateB; /// /// Contruct and initialise the RNG /// /// public Random(int seed = 1) { m_seed = seed; if (m_seed == 0) { m_seed = 1; } Reset(); } /// /// Reset it to its initial state with the existing seed /// public void Reset() { m_stateA = m_A_Init * (uint)m_seed; m_stateB = m_B_Init * (uint)m_seed; } /// /// Restet it to a new state with a new seed /// /// New seed public void Reset(int seed) { m_seed = seed; if (m_seed == 0) { m_seed = 1; } Reset(); } /// /// Reset it to the stade defined by the state variables passed in /// public void Reset(ulong stateA, ulong stateB) { Debug.Log("Resetting RNG State " + stateA + " " + stateB); m_stateA = stateA; m_stateB = stateB; } /// /// Return the current state for serialisation /// /// Seed /// State A /// State B public void GetState(out int seed, out ulong stateA, out ulong stateB) { seed = m_seed; stateA = m_stateA; stateB = m_stateB; } //Check here for wrapper functions //https://github.com/tucano/UnityRandom/blob/master/lib/MersenneTwister.cs /// /// Get the next value /// /// A value between zero and one inclusive public float Next() { ulong x = m_stateA; ulong y = m_stateB; m_stateA = y; x ^= x << 23; x ^= x >> 17; x ^= y ^ (y >> 26); m_stateB = x; return (float)(x + y) / (float)ulong.MaxValue; } /// /// Return the next int /// /// public int NextInt() { return (int)(Next() * int.MaxValue); } /// /// Get the next value and scale it between the min and max values supplied inclusive /// /// Minimum value /// Maximum value /// Next value scaled beteen the range supplied public float Next(float min, float max) { //float xx = min + (Next() * (max - min)); //Debug.Log(string.Format("{0:0.0000}", xx)); //return xx; return min + (Next() * (max - min)); } /// /// Get the next value and scale it between the min and max values supplied inclusive /// /// Minimum value /// Maximum value /// Next value scaled beteen the range supplied public int Next(int min, int max) { if (min == max) { return min; } return (int)Next((float)min, (float)max+0.999f); } /// /// Get the next value as a vector /// /// Next value as a vector in ranges 0..1 public Vector3 NextVector() { return new Vector3(Next(), Next(), Next()); } /// /// Get the next value as a vector /// /// Minimum value /// Maximum value /// public Vector3 NextVector(float min, float max) { return new Vector3(Next(min, max), Next(min, max), Next(min, max)); } } }