Add helper methods for System.Random (#3832)

This might be a maint thing but look, I just want seeded RNG and IRobustRandom doesn't have it so not sure what is easier considering IRobustRandom is also registered as a depdency but constructing it manually is weird aaaa
This commit is contained in:
metalgearsloth
2023-03-10 09:04:23 +11:00
committed by GitHub
parent abecc554f4
commit 2f7a652e22
2 changed files with 69 additions and 44 deletions

View File

@@ -2,53 +2,76 @@ using System;
using System.Collections.Generic;
using Robust.Shared.Maths;
namespace Robust.Shared.Random
namespace Robust.Shared.Random;
public interface IRobustRandom
{
public interface IRobustRandom
/// <summary>
/// Get the underlying System.Random
/// </summary>
/// <returns></returns>
System.Random GetRandom();
float NextFloat();
public float NextFloat(float minValue, float maxValue)
=> NextFloat() * (maxValue - minValue) + minValue;
public float NextFloat(float maxValue) => NextFloat() * maxValue;
int Next();
int Next(int minValue, int maxValue);
TimeSpan Next(TimeSpan minTime, TimeSpan maxTime);
TimeSpan Next(TimeSpan maxTime);
int Next(int maxValue);
double NextDouble();
double NextDouble(double minValue, double maxValue) => NextDouble() * (maxValue - minValue) + minValue;
void NextBytes(byte[] buffer);
public Angle NextAngle() => NextFloat() * MathHelper.Pi * 2;
public Angle NextAngle(Angle minValue, Angle maxValue) => NextFloat() * (maxValue - minValue) + minValue;
public Angle NextAngle(Angle maxValue) => NextFloat() * maxValue;
/// <summary>
/// Random vector, created from a uniform distribution of magnitudes and angles.
/// </summary>
/// <remarks>
/// In general, NextVector2(1) will tend to result in vectors with smaller magnitudes than
/// NextVector2Box(1,1), even if you ignored any vectors with a magnitude larger than one.
/// </remarks>
public Vector2 NextVector2(float minMagnitude, float maxMagnitude) => NextAngle().RotateVec((NextFloat(minMagnitude, maxMagnitude), 0));
public Vector2 NextVector2(float maxMagnitude = 1) => NextVector2(0, maxMagnitude);
/// <summary>
/// Random vector, created from a uniform distribution of x and y coordinates lying inside some box.
/// </summary>
public Vector2 NextVector2Box(float minX, float minY, float maxX, float maxY) => new Vector2(NextFloat(minX, maxX), NextFloat(minY, maxY));
public Vector2 NextVector2Box(float maxAbsX = 1, float maxAbsY = 1) => NextVector2Box(-maxAbsX, -maxAbsY, maxAbsX, maxAbsY);
void Shuffle<T>(IList<T> list)
{
float NextFloat();
public float NextFloat(float minValue, float maxValue)
=> NextFloat() * (maxValue - minValue) + minValue;
public float NextFloat(float maxValue) => NextFloat() * maxValue;
int Next();
int Next(int minValue, int maxValue);
TimeSpan Next(TimeSpan minTime, TimeSpan maxTime);
TimeSpan Next(TimeSpan maxTime);
int Next(int maxValue);
double NextDouble();
double NextDouble(double minValue, double maxValue) => NextDouble() * (maxValue - minValue) + minValue;
void NextBytes(byte[] buffer);
public Angle NextAngle() => NextFloat() * MathHelper.Pi * 2;
public Angle NextAngle(Angle minValue, Angle maxValue) => NextFloat() * (maxValue - minValue) + minValue;
public Angle NextAngle(Angle maxValue) => NextFloat() * maxValue;
/// <summary>
/// Random vector, created from a uniform distribution of magnitudes and angles.
/// </summary>
/// <remarks>
/// In general, NextVector2(1) will tend to result in vectors with smaller magnitudes than
/// NextVector2Box(1,1), even if you ignored any vectors with a magnitude larger than one.
/// </remarks>
public Vector2 NextVector2(float minMagnitude, float maxMagnitude) => NextAngle().RotateVec((NextFloat(minMagnitude, maxMagnitude), 0));
public Vector2 NextVector2(float maxMagnitude = 1) => NextVector2(0, maxMagnitude);
/// <summary>
/// Random vector, created from a uniform distribution of x and y coordinates lying inside some box.
/// </summary>
public Vector2 NextVector2Box(float minX, float minY, float maxX, float maxY) => new Vector2(NextFloat(minX, maxX), NextFloat(minY, maxY));
public Vector2 NextVector2Box(float maxAbsX = 1, float maxAbsY = 1) => NextVector2Box(-maxAbsX, -maxAbsY, maxAbsX, maxAbsY);
void Shuffle<T>(IList<T> list)
var n = list.Count;
while (n > 1)
{
var n = list.Count;
while (n > 1) {
n -= 1;
var k = Next(n + 1);
var value = list[k];
list[k] = list[n];
list[n] = value;
}
n -= 1;
var k = Next(n + 1);
(list[k], list[n]) = (list[n], list[k]);
}
}
}
public static class RandomHelpers
{
public static void Shuffle<T>(this System.Random random, IList<T> list)
{
var n = list.Count;
while (n > 1)
{
n -= 1;
var k = random.Next(n + 1);
(list[k], list[n]) = (list[n], list[k]);
}
}
public static bool Prob(this System.Random random, double chance)
{
return random.NextDouble() < chance;
}
}

View File

@@ -7,6 +7,8 @@ namespace Robust.Shared.Random
{
private readonly System.Random _random = new();
public System.Random GetRandom() => _random;
public float NextFloat()
{
return _random.NextFloat();