Created
January 24, 2020 06:43
-
-
Save MightyPrinny/342ca512ad8926a98e03c04020b22448 to your computer and use it in GitHub Desktop.
Chooses values from an array using a probabilities array
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
///Returns a random object from the array with probabilities | |
///</summary> | |
/// <param name="prob">the probability of being chosen for each value in the array, their sum must be <= 1</param> | |
public static T ChooseWithProbabilities<T>(float[] prob,params T[] array) | |
{ | |
float rn = RNG.Randf(); | |
int len = array.Length; | |
float[][] intervals = new float[len][]; | |
if (len != prob.Length || len == 0) | |
{ | |
return default; | |
} | |
float total = 0; | |
float intervalStart = 0; | |
for (int i = prob.Length - 1; i >= 0; --i) | |
{ | |
intervals[i] = new float[2]; | |
intervals[i][0] = intervalStart; | |
intervals[i][1] = intervalStart + prob[i]; | |
total += prob[i]; | |
intervalStart += intervals[i][1]; | |
} | |
if (total > 1 && (Mathf.Abs(total - 1) > 0.01f)) | |
{ | |
GD.PrintErr("Bad probabilities array"); | |
return default; | |
} | |
for (int i = intervals.Length - 1; i >= 0; --i) | |
{ | |
if (rn >= intervals[i][0] && rn <= intervals[i][1]) | |
{ | |
return array[i]; | |
} | |
} | |
return default; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Not unit tested, used in godot engine, the intervals could be stored in a struct to play nicer with the GC, but I wasn't calling it every frame so I just used arrays.