diff --git a/CHANGELOG.md b/CHANGELOG.md
index f21f58a..fea90c7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,7 @@ Jump to version:
Additions
- Added GraphicsExtensions.WithRenderTargets, a multi-target version of WithRenderTarget
- Added Zero, One, Linear and Clamp to Easings
+- Added GetRandomEntry and GetRandomWeightedEntry to SingleRandom
Fixes
- Fixed TextInput not working correctly when using surrogate pairs
diff --git a/MLEM/Extensions/RandomExtensions.cs b/MLEM/Extensions/RandomExtensions.cs
index 250e50c..b171c8c 100644
--- a/MLEM/Extensions/RandomExtensions.cs
+++ b/MLEM/Extensions/RandomExtensions.cs
@@ -16,8 +16,7 @@ namespace MLEM.Extensions {
/// The entries' type
/// A random entry
public static T GetRandomEntry(this Random random, ICollection entries) {
- // ElementAt internally optimizes for IList access so we don't have to here
- return entries.ElementAt(random.Next(entries.Count));
+ return RandomExtensions.GetRandomEntry(entries, random.NextSingle());
}
///
@@ -31,28 +30,12 @@ namespace MLEM.Extensions {
/// A random entry, based on the entries' weight
/// If the weight function returns different weights for the same entry
public static T GetRandomWeightedEntry(this Random random, ICollection entries, Func weightFunc) {
- var totalWeight = entries.Sum(weightFunc);
- var goalWeight = random.Next(totalWeight);
- var currWeight = 0;
- foreach (var entry in entries) {
- currWeight += weightFunc(entry);
- if (currWeight > goalWeight)
- return entry;
- }
- throw new IndexOutOfRangeException();
+ return RandomExtensions.GetRandomWeightedEntry(entries, weightFunc, random.NextSingle());
}
///
public static T GetRandomWeightedEntry(this Random random, ICollection entries, Func weightFunc) {
- var totalWeight = entries.Sum(weightFunc);
- var goalWeight = random.NextDouble() * totalWeight;
- var currWeight = 0F;
- foreach (var entry in entries) {
- currWeight += weightFunc(entry);
- if (currWeight > goalWeight)
- return entry;
- }
- throw new IndexOutOfRangeException();
+ return RandomExtensions.GetRandomWeightedEntry(entries, weightFunc, random.NextSingle());
}
///
@@ -87,5 +70,32 @@ namespace MLEM.Extensions {
}
#endif
+ internal static T GetRandomEntry(ICollection entries, float randomValue) {
+ // ElementAt internally optimizes for IList access so we don't have to here
+ return entries.ElementAt((int) (randomValue * entries.Count));
+ }
+
+ internal static T GetRandomWeightedEntry(ICollection entries, Func weightFunc, float randomValue) {
+ var goalWeight = randomValue * entries.Sum(weightFunc);
+ var currWeight = 0;
+ foreach (var entry in entries) {
+ currWeight += weightFunc(entry);
+ if (currWeight > goalWeight)
+ return entry;
+ }
+ throw new IndexOutOfRangeException();
+ }
+
+ internal static T GetRandomWeightedEntry(ICollection entries, Func weightFunc, float randomValue) {
+ var goalWeight = randomValue * entries.Sum(weightFunc);
+ var currWeight = 0F;
+ foreach (var entry in entries) {
+ currWeight += weightFunc(entry);
+ if (currWeight > goalWeight)
+ return entry;
+ }
+ throw new IndexOutOfRangeException();
+ }
+
}
}
diff --git a/MLEM/Misc/SingleRandom.cs b/MLEM/Misc/SingleRandom.cs
index 73f7299..dc3d861 100644
--- a/MLEM/Misc/SingleRandom.cs
+++ b/MLEM/Misc/SingleRandom.cs
@@ -1,4 +1,8 @@
-namespace MLEM.Misc {
+using System;
+using System.Collections.Generic;
+using MLEM.Extensions;
+
+namespace MLEM.Misc {
///
/// The SingleRandom class allows generating single, one-off pseudorandom numbers based on a seed or a .
/// The types of numbers that can be generated are and , both of which can be generated with specific minimum and maximum values if desired.
@@ -138,5 +142,35 @@
return (maxValue - minValue) * SingleRandom.Single(source) + minValue;
}
+ ///
+ /// Gets a random entry from the given collection with uniform chance.
+ ///
+ /// The entries to choose from
+ /// The to use.
+ /// The entries' type
+ /// A random entry
+ public static T GetRandomEntry(ICollection entries, SeedSource source) {
+ return RandomExtensions.GetRandomEntry(entries, SingleRandom.Single(source));
+ }
+
+ ///
+ /// Returns a random entry from the given collection based on the specified weight function.
+ /// A higher weight for an entry increases its likeliness of being picked.
+ ///
+ /// The entries to choose from
+ /// A function that applies weight to each entry
+ /// The to use.
+ /// The entries' type
+ /// A random entry, based on the entries' weight
+ /// If the weight function returns different weights for the same entry
+ public static T GetRandomWeightedEntry(ICollection entries, Func weightFunc, SeedSource source) {
+ return RandomExtensions.GetRandomWeightedEntry(entries, weightFunc, SingleRandom.Single(source));
+ }
+
+ ///
+ public static T GetRandomWeightedEntry(ICollection entries, Func weightFunc, SeedSource source) {
+ return RandomExtensions.GetRandomWeightedEntry(entries, weightFunc, SingleRandom.Single(source));
+ }
+
}
}