// 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();
}
}