diff --git a/Core/Utils/RandomUtil.cs b/Core/Utils/RandomUtil.cs index 5a99eddc..5da25cd3 100644 --- a/Core/Utils/RandomUtil.cs +++ b/Core/Utils/RandomUtil.cs @@ -209,7 +209,7 @@ public class RandomUtil /// The lower bound of the range (inclusive). /// The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. /// A random integer within the specified range. - public int RandInt(int low, int? high) + public int RandInt(int low, int? high = null) { // Return a random integer from 0 to low if high is not provided if (high is null) @@ -277,6 +277,83 @@ public class RandomUtil return Math.Round(result * factor) / factor; } + + /// + /// Draws a specified number of random elements from a given list. + /// + /// The list to draw elements from. + /// The number of elements to draw. Defaults to 1. + /// Whether to draw with replacement. Defaults to true. + /// The type of elements in the list. + /// A List containing the drawn elements. + public List DrawRandomFromList(List originalList, int count = 1, bool replacement = true) + { + throw new NotImplementedException("ICloneable needs implemented on types before this can be written"); + } + + /// + /// Draws a specified number of random keys from a given dictionary. + /// + /// The dictionary from which to draw keys. + /// The number of keys to draw. Defaults to 1. + /// Whether to draw with replacement. Defaults to true. + /// The type of elements in keys + /// The type of elements in values + /// A list of randomly drawn keys from the dictionary. + public List DrawRandomFromDict(Dictionary dict, int count = 1, bool replacement = true) where TKey : notnull + { + throw new NotImplementedException("ICloneable needs implemented on types before this can be written"); + } + + /// + /// Generates a biased random number within a specified range. + /// + /// The minimum value of the range (inclusive). + /// The maximum value of the range (inclusive). + /// The bias shift to apply to the random number generation. + /// The number of iterations to use for generating a Gaussian random number. + /// A biased random number within the specified range. + public double GetBiasedRandomNumber(double min, double max, double shift, double n) + { + /*** + * This function generates a random number based on a gaussian distribution with an option to add a bias via shifting. + * + * Here's an example graph of how the probabilities can be distributed: + * https://www.boost.org/doc/libs/1_49_0/libs/math/doc/sf_and_dist/graphs/normal_pdf.png + * + * Our parameter 'n' is sort of like σ (sigma) in the example graph. + * + * An 'n' of 1 means all values are equally likely. Increasing 'n' causes numbers near the edge to become less likely. + * By setting 'shift' to whatever 'max' is, we can make values near 'min' very likely, while values near 'max' become extremely unlikely. + * + * Here's a place where you can play around with the 'n' and 'shift' values to see how the distribution changes: + * http://jsfiddle.net/e08cumyx/ + */ + + throw new NotImplementedException("This honestly went over my head..."); + } + + /// + /// Shuffles a list in place using the Fisher-Yates algorithm. + /// + /// The list to shuffle. + /// The type of elements in the list. + /// The shuffled list. + public List Shuffle(List originalList) + { + var currentIndex = originalList.Count; + + while (currentIndex != 0) + { + var randomIndex = GetInt(0, currentIndex); + currentIndex--; + + // Swap it with the current element. + (originalList[currentIndex], originalList[randomIndex]) = (originalList[randomIndex], originalList[currentIndex]); + } + + return originalList; + } /// /// Generates a secure random number between 0 (inclusive) and 1 (exclusive). diff --git a/UnitTests/Tests/Utils/RandomUtilTests.cs b/UnitTests/Tests/Utils/RandomUtilTests.cs index be9b3041..23a6d95d 100644 --- a/UnitTests/Tests/Utils/RandomUtilTests.cs +++ b/UnitTests/Tests/Utils/RandomUtilTests.cs @@ -121,7 +121,7 @@ public sealed class RandomUtilTests for (var i = 0; i < 100; i++) { - var result = _randomUtil.RandInt(10, null); + var result = _randomUtil.RandInt(10); if (result < 0 || result > 9) { @@ -163,4 +163,21 @@ public sealed class RandomUtilTests } } } + + [TestMethod] + public void ShuffleTest() + { + var testList = new List() + { + 1,2,3,4,5,6,7,8,9,10 + }; + + var orig = new List(testList); + + var result = _randomUtil.Shuffle(testList); + + Assert.IsFalse( + result.SequenceEqual(orig), + $"Shuffle test failed. Expected: {string.Join(", ", orig)}, but got {string.Join(", ", result)}"); + } } \ No newline at end of file