using System; namespace Games.Common.Randomness; /// /// Provides extension methods to providing random numbers in a given range. /// /// public static class IRandomExtensions { /// /// Gets a random such that 0 <= n < exclusiveMaximum. /// /// The random number. public static float NextFloat(this IRandom random, float exclusiveMaximum) => Scale(random.NextFloat(), exclusiveMaximum); /// /// Gets a random such that inclusiveMinimum <= n < exclusiveMaximum. /// /// The random number. public static float NextFloat(this IRandom random, float inclusiveMinimum, float exclusiveMaximum) => Scale(random.NextFloat(), inclusiveMinimum, exclusiveMaximum); /// /// Gets a random such that 0 <= n < exclusiveMaximum. /// /// The random number. public static int Next(this IRandom random, int exclusiveMaximum) => ToInt(random.NextFloat(exclusiveMaximum)); /// /// Gets a random such that inclusiveMinimum <= n < exclusiveMaximum. /// /// The random number. public static int Next(this IRandom random, int inclusiveMinimum, int exclusiveMaximum) => ToInt(random.NextFloat(inclusiveMinimum, exclusiveMaximum)); /// /// Gets the previous unscaled (between 0 and 1) scaled to a new range: /// 0 <= x < . /// /// The random number. public static float PreviousFloat(this IRandom random, float exclusiveMaximum) => Scale(random.PreviousFloat(), exclusiveMaximum); /// /// Gets the previous unscaled (between 0 and 1) scaled to a new range: /// <= n < . /// /// The random number. public static float PreviousFloat(this IRandom random, float inclusiveMinimum, float exclusiveMaximum) => Scale(random.PreviousFloat(), inclusiveMinimum, exclusiveMaximum); /// /// Gets the previous unscaled (between 0 and 1) scaled to an in a new /// range: 0 <= n < . /// /// The random number. public static int Previous(this IRandom random, int exclusiveMaximum) => ToInt(random.PreviousFloat(exclusiveMaximum)); /// /// Gets the previous unscaled (between 0 and 1) scaled to an in a new /// range: <= n < . /// The random number. public static int Previous(this IRandom random, int inclusiveMinimum, int exclusiveMaximum) => ToInt(random.PreviousFloat(inclusiveMinimum, exclusiveMaximum)); private static float Scale(float zeroToOne, float exclusiveMaximum) { if (exclusiveMaximum <= 0) { throw new ArgumentOutOfRangeException(nameof(exclusiveMaximum), "Must be greater than 0."); } return Scale(zeroToOne, 0, exclusiveMaximum); } private static float Scale(float zeroToOne, float inclusiveMinimum, float exclusiveMaximum) { if (exclusiveMaximum <= inclusiveMinimum) { throw new ArgumentOutOfRangeException(nameof(exclusiveMaximum), "Must be greater than inclusiveMinimum."); } var range = exclusiveMaximum - inclusiveMinimum; return zeroToOne * range + inclusiveMinimum; } private static int ToInt(float value) => (int)Math.Floor(value); }