mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-21 23:00:43 -08:00
Add random number generator
This commit is contained in:
55
00_Common/dotnet/Games.Common/Randomness/IRandom.cs
Normal file
55
00_Common/dotnet/Games.Common/Randomness/IRandom.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
namespace Games.Common.Randomness;
|
||||
|
||||
/// <summary>
|
||||
/// Provides access to a random number generator
|
||||
/// </summary>
|
||||
public interface IRandom
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a random <see cref="float" /> such that 0 <= n < 1.
|
||||
/// </summary>
|
||||
/// <returns>The random number.</returns>
|
||||
float NextFloat();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a random <see cref="float" /> such that 0 <= n < exclusiveMaximum.
|
||||
/// </summary>
|
||||
/// <returns>The random number.</returns>
|
||||
float NextFloat(float exclusiveMaximum);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a random <see cref="float" /> such that inclusiveMinimum <= n < exclusiveMaximum.
|
||||
/// </summary>
|
||||
/// <returns>The random number.</returns>
|
||||
float NextFloat(float inclusiveMinimum, float exclusiveMaximum);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a random <see cref="int" /> such that 0 <= n < exclusiveMaximum.
|
||||
/// </summary>
|
||||
/// <returns>The random number.</returns>
|
||||
int Next(int exclusiveMaximum);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a random <see cref="int" /> such that inclusiveMinimum <= n < exclusiveMaximum.
|
||||
/// </summary>
|
||||
/// <returns>The random number.</returns>
|
||||
int Next(int inclusiveMinimum, int exclusiveMaximum);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the previous random number as a <see cref="float" />.
|
||||
/// </summary>
|
||||
/// <returns>The previous random number.</returns>
|
||||
float PreviousFloat();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the previous random number as an <see cref="int" />.
|
||||
/// </summary>
|
||||
/// <returns>The previous random number.</returns>
|
||||
int Previous();
|
||||
|
||||
/// <summary>
|
||||
/// Reseeds the random number generator.
|
||||
/// </summary>
|
||||
/// <param name="seed">The seed.</param>
|
||||
void Reseed(int seed);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
|
||||
namespace Games.Common.Randomness;
|
||||
|
||||
public class RandomNumberGenerator : IRandom
|
||||
{
|
||||
private Random _random;
|
||||
private float _previous;
|
||||
|
||||
public RandomNumberGenerator()
|
||||
{
|
||||
// The BASIC RNG is seeded based on time with a 1 second resolution
|
||||
_random = new Random((int)(DateTime.UtcNow.Ticks / TimeSpan.TicksPerSecond));
|
||||
}
|
||||
|
||||
public float NextFloat() => NextFloat(1);
|
||||
|
||||
public float NextFloat(float exclusiveMaximum)
|
||||
{
|
||||
if (exclusiveMaximum <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(exclusiveMaximum), "Must be greater than 0.");
|
||||
}
|
||||
|
||||
return NextFloat(0, exclusiveMaximum);
|
||||
}
|
||||
|
||||
public float NextFloat(float inclusiveMinimum, float exclusiveMaximum)
|
||||
{
|
||||
if (exclusiveMaximum <= inclusiveMinimum)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(exclusiveMaximum), "Must be greater than inclusiveMinimum.");
|
||||
}
|
||||
|
||||
var range = exclusiveMaximum - inclusiveMinimum;
|
||||
return _previous = ((float)_random.NextDouble()) * range + inclusiveMinimum;
|
||||
}
|
||||
|
||||
public int Next(int exclusiveMaximum) => ToInt(NextFloat(exclusiveMaximum));
|
||||
|
||||
public int Next(int inclusiveMinimum, int exclusiveMaximum) => ToInt(NextFloat(inclusiveMinimum, exclusiveMaximum));
|
||||
|
||||
public float PreviousFloat() => _previous;
|
||||
|
||||
public int Previous() => ToInt(_previous);
|
||||
|
||||
private static int ToInt(float value) => (int)Math.Floor(value);
|
||||
|
||||
public void Reseed(int seed) => _random = new Random(seed);
|
||||
}
|
||||
Reference in New Issue
Block a user