// MIT License - Copyright (c) 2023 wallstop // Full license text: https://github.com/wallstop/unity-helpers/blob/main/LICENSE namespace WallstopStudios.UnityHelpers.Core.Random { using System; using System.Collections.Generic; using DataStructure.Adapters; using UnityEngine; /// /// Unified random number generator interface implemented by all PRNGs in this package. /// /// /// Serialization guidance: /// - JSON: Works out of the box using runtime type information in the serializer entry points. /// - Protobuf: You can serialize an IRandom instance (the runtime type is used), but when /// deserializing to IRandom you must either register a concrete root via /// Serializer.RegisterProtobufRoot<IRandom, ConcreteRandom>() or declare your model /// field as , which is annotated with [ProtoInclude] for all /// known implementations. /// Alternatively, use the overload Serializer.ProtoDeserialize<T>(byte[], Type) and /// pass the concrete type. /// public interface IRandom { /// /// Gets the internal state of the random number generator for serialization and restoration. /// RandomState InternalState { get; } /// /// Generates a random 32-bit signed integer. /// /// A number within the range [0, int.MaxValue). int Next(); /// /// Generates a random integer within the specified exclusive upper bound. /// /// The exclusive upper bound. /// A number within the range [0, max). int Next(int max); /// /// Generates a random integer within the specified range. /// /// The inclusive lower bound. /// The exclusive upper bound. /// A number within the range [min, max). int Next(int min, int max); /// /// Generates a random 32-bit unsigned integer. /// /// A number within the range [0, uint.MaxValue]. uint NextUint(); /// /// Generates a random unsigned integer within the specified exclusive upper bound. /// /// The exclusive upper bound. /// A number within the range [0, max). uint NextUint(uint max); /// /// Generates a random unsigned integer within the specified range. /// /// The inclusive lower bound. /// The exclusive upper bound. /// A number within the range [min, max). uint NextUint(uint min, uint max); /// /// Generates a random 16-bit signed integer. /// /// A number within the range [0, short.MaxValue). short NextShort(); /// /// Generates a random short within the specified exclusive upper bound. /// /// The exclusive upper bound. /// A number within the range [0, max). short NextShort(short max); /// /// Generates a random short within the specified range. /// /// The inclusive lower bound. /// The exclusive upper bound. /// A number within the range [min, max). short NextShort(short min, short max); /// /// Generates a random 8-bit unsigned integer. /// /// A number within the range [0, byte.MaxValue). byte NextByte(); /// /// Generates a random byte within the specified exclusive upper bound. /// /// The exclusive upper bound. /// A number within the range [0, max). byte NextByte(byte max); /// /// Generates a random byte within the specified range. /// /// The inclusive lower bound. /// The exclusive upper bound. /// A number within the range [min, max). byte NextByte(byte min, byte max); /// /// Generates a random 64-bit signed integer. /// /// A number within the range [0, long.MaxValue). long NextLong(); /// /// Generates a random long within the specified exclusive upper bound. /// /// The exclusive upper bound. /// A number within the range [0, max). long NextLong(long max); /// /// Generates a random long within the specified range. /// /// The inclusive lower bound. /// The exclusive upper bound. /// A number within the range [min, max). long NextLong(long min, long max); /// /// Generates a random 64-bit unsigned integer. /// /// A number within the range [0, ulong.MaxValue]. ulong NextUlong(); /// /// Generates a random ulong within the specified exclusive upper bound. /// /// The exclusive upper bound. /// A number within the range [0, max). ulong NextUlong(ulong max); /// /// Generates a random ulong within the specified range. /// /// The inclusive lower bound. /// The exclusive upper bound. /// A number within the range [min, max). ulong NextUlong(ulong min, ulong max); /// /// Generates a random boolean with equal probability for true and false. /// /// A random boolean value with equal probability for true and false. bool NextBool(); /// /// Fills the specified buffer with random bytes. /// /// The buffer to fill with random bytes. void NextBytes(byte[] buffer); /// /// Generates a random single-precision floating-point number. /// /// A number within the range [0, 1). float NextFloat(); /// /// Generates a random float within the specified exclusive upper bound. /// /// The exclusive upper bound. /// A number within the range [0, max). float NextFloat(float max); /// /// Generates a random float within the specified range. /// /// The inclusive lower bound. /// The exclusive upper bound. /// A number within the range [min, max). float NextFloat(float min, float max); /// /// Generates a random double-precision floating-point number. /// /// A number within the range [0, 1). double NextDouble(); /// /// Generates a random double within the specified exclusive upper bound. /// /// The exclusive upper bound. /// A number within the range [0, max). double NextDouble(double max); /// /// Generates a random double within the specified range. /// /// The inclusive lower bound. /// The exclusive upper bound. /// A number within the range [min, max). double NextDouble(double min, double max); /// /// Generates a random number from a Gaussian (normal) distribution. /// /// The mean of the distribution. /// The standard deviation of the distribution. /// A random number from the specified Gaussian distribution. double NextGaussian(double mean = 0, double stdDev = 1); /// /// Generates a random globally unique identifier (GUID). /// /// A randomly generated GUID. Guid NextGuid(); /// /// Generates a random serializable GUID wrapper. /// /// A randomly generated WGuid. WGuid NextWGuid(); /// /// Selects a random element from the specified enumerable. /// /// The type of elements in the enumerable. /// The enumerable to select from. /// A randomly selected element. /// /// This method automatically dispatches to more efficient overloads when the enumerable /// is actually an or , /// using indexed access to avoid enumerator allocations. For hot paths, prefer passing /// the concrete type (List<T>, T[]) or interface /// (IReadOnlyList<T>) directly to skip the runtime type check. /// T NextOf(IEnumerable enumerable); /// /// Selects a random element from the specified collection. /// /// The type of elements in the collection. /// The collection to select from. /// A randomly selected element. T NextOf(IReadOnlyCollection collection); /// /// Selects a random element from the specified list. /// /// The type of elements in the list. /// The list to select from. /// A randomly selected element. T NextOf(IReadOnlyList list); /// /// Selects a random element from the specified parameters. /// /// The type of elements. /// The elements to select from. /// A randomly selected element. T NextOfParams(params T[] elements); /// /// Selects a random value from the specified enum type. /// /// The enum type. /// A randomly selected enum value. T NextEnum() where T : unmanaged, Enum; /// /// Selects a random value from the specified enum type, excluding the specified value. /// /// The enum type. /// The enum value to exclude. /// A randomly selected enum value that is not the excluded value. T NextEnumExcept(T exception1) where T : unmanaged, Enum; /// /// Selects a random value from the specified enum type, excluding the specified values. /// /// The enum type. /// The first enum value to exclude. /// The second enum value to exclude. /// A randomly selected enum value that is not one of the excluded values. T NextEnumExcept(T exception1, T exception2) where T : unmanaged, Enum; /// /// Selects a random value from the specified enum type, excluding the specified values. /// /// The enum type. /// The first enum value to exclude. /// The second enum value to exclude. /// The third enum value to exclude. /// A randomly selected enum value that is not one of the excluded values. T NextEnumExcept(T exception1, T exception2, T exception3) where T : unmanaged, Enum; /// /// Selects a random value from the specified enum type, excluding the specified values. /// /// The enum type. /// The first enum value to exclude. /// The second enum value to exclude. /// The third enum value to exclude. /// The fourth enum value to exclude. /// A randomly selected enum value that is not one of the excluded values. T NextEnumExcept(T exception1, T exception2, T exception3, T exception4) where T : unmanaged, Enum; /// /// Selects a random value from the specified enum type, excluding the specified values. /// /// The enum type. /// The first enum value to exclude. /// The second enum value to exclude. /// The third enum value to exclude. /// The fourth enum value to exclude. /// Additional enum values to exclude. /// A randomly selected enum value that is not one of the excluded values. T NextEnumExcept( T exception1, T exception2, T exception3, T exception4, params T[] exceptions ) where T : unmanaged, Enum; /// /// Generates a 2D Perlin noise map with the specified parameters. /// /// The array to fill with noise values. /// Optional PerlinNoise instance to use for generation. /// The scale of the noise pattern. /// The number of noise octaves to combine. /// The amplitude multiplier for each successive octave. /// The frequency multiplier for each successive octave. /// The base offset for sampling the noise. /// The range for random octave offsets. /// Whether to normalize the output values to [0, 1]. /// The filled noise map array. float[,] NextNoiseMap( float[,] noiseMap, PerlinNoise noise = null, float scale = 2.5f, int octaves = 8, float persistence = 0.5f, float lacunarity = 2f, Vector2 baseOffset = default, float octaveOffsetRange = 100000f, bool normalize = true ); /// /// Creates a deep copy of this random number generator with the same internal state. /// /// A new IRandom instance with identical state. IRandom Copy(); } }