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;
}
}
}