using System; namespace MLEM.Misc { /// /// The SingleRandom class allows generating single, one-off pseudorandom numbers based on a seed, or a set of seeds. /// The types of numbers that can be generated are and , both of which can be generated with specific minimum and maximum values if desired. /// Methods in this class are tested to be sufficiently "random", that is, to be sufficiently distributed throughout their range, as well as sufficiently different for neighboring seeds. /// public class SingleRandom { /// /// Generates a single, one-off pseudorandom integer between 0 and based on a given . /// This method is guaranteed to return the same result for the same . /// /// The seed to use. /// The generated number. public static int Int(int seed) { return (int) (SingleRandom.Single(seed) * int.MaxValue); } /// /// Generates a single, one-off pseudorandom integer between 0 and based on a given set of . /// This method is guaranteed to return the same result for the same set of . /// /// The seeds to use. /// The generated number. public static int Int(params int[] seeds) { return (int) (SingleRandom.Single(seeds) * int.MaxValue); } /// /// Generates a single, one-off pseudorandom integer between 0 and based on a given . /// This method is guaranteed to return the same result for the same . /// /// The (exclusive) maximum value. /// The seed to use. /// The generated number. public static int Int(int maxValue, int seed) { return (int) (maxValue * SingleRandom.Single(seed)); } /// /// Generates a single, one-off pseudorandom integer between 0 and based on a given set of . /// This method is guaranteed to return the same result for the same set of . /// /// The (exclusive) maximum value. /// The seeds to use. /// The generated number. public static int Int(int maxValue, params int[] seeds) { return (int) (maxValue * SingleRandom.Single(seeds)); } /// /// Generates a single, one-off pseudorandom integer between and based on a given . /// This method is guaranteed to return the same result for the same . /// /// The (inclusive) minimum value. /// The (exclusive) maximum value. /// The seed to use. /// The generated number. public static int Int(int minValue, int maxValue, int seed) { return (int) ((maxValue - minValue) * SingleRandom.Single(seed)) + minValue; } /// /// Generates a single, one-off pseudorandom integer between and based on a given set of . /// This method is guaranteed to return the same result for the same set of . /// /// The (inclusive) minimum value. /// The (exclusive) maximum value. /// The seeds to use. /// The generated number. public static int Int(int minValue, int maxValue, params int[] seeds) { return (int) ((maxValue - minValue) * SingleRandom.Single(seeds)) + minValue; } /// /// Generates a single, one-off pseudorandom floating point number between 0 and 1 based on a given . /// This method is guaranteed to return the same result for the same . /// /// The seed to use. /// The generated number. public static float Single(int seed) { return (SingleRandom.Scramble(seed) / (float) int.MaxValue + 1) / 2; } /// /// Generates a single, one-off pseudorandom floating point number between 0 and 1 based on a given set of . /// This method is guaranteed to return the same result for the same set of . /// /// The seeds to use. /// The generated number. public static float Single(params int[] seeds) { return (SingleRandom.Scramble(seeds) / (float) int.MaxValue + 1) / 2; } /// /// Generates a single, one-off pseudorandom floating point number between 0 and based on a given . /// This method is guaranteed to return the same result for the same . /// /// The (exclusive) maximum value. /// The seed to use. /// The generated number. public static float Single(int maxValue, int seed) { return maxValue * SingleRandom.Single(seed); } /// /// Generates a single, one-off pseudorandom floating point number between 0 and based on a given set of . /// This method is guaranteed to return the same result for the same set of . /// /// The (exclusive) maximum value. /// The seeds to use. /// The generated number. public static float Single(int maxValue, params int[] seeds) { return maxValue * SingleRandom.Single(seeds); } /// /// Generates a single, one-off pseudorandom floating point number between and based on a given . /// This method is guaranteed to return the same result for the same . /// /// The (inclusive) minimum value. /// The (exclusive) maximum value. /// The seed to use. /// The generated number. public static float Single(int minValue, int maxValue, int seed) { return (maxValue - minValue) * SingleRandom.Single(seed) + minValue; } /// /// Generates a single, one-off pseudorandom floating point number between and based on a given set of . /// This method is guaranteed to return the same result for the same set of . /// /// The (inclusive) minimum value. /// The (exclusive) maximum value. /// The seeds to use. /// The generated number. public static float Single(int minValue, int maxValue, params int[] seeds) { return (maxValue - minValue) * SingleRandom.Single(seeds) + minValue; } private static int Scramble(int[] seeds) { if (seeds == null || seeds.Length <= 0) throw new ArgumentOutOfRangeException(nameof(seeds)); var ret = 1; for (var i = 0; i < seeds.Length; i++) ret *= SingleRandom.Scramble(seeds[i]); return ret; } private static int Scramble(int seed) { seed ^= (seed << 7); seed *= 207398809; seed ^= (seed << 17); seed *= 928511849; seed ^= (seed << 12); return seed; } } }