using System; using System.Collections.Generic; using System.Linq; using UnityEngine; using Random = UnityEngine.Random; namespace VOID.Generic.Util { public static class RandomUtil { /// /// Reinit random with given seed. /// public static void InitState(int seed) { Random.InitState(seed); } /// /// Returns random integer between min and max. /// public static int RandomInteger(int min = 0, int max = 100) { return Mathf.RoundToInt(Random.value * (max-min)) + min; } /// /// Returns random float between min and max. /// public static float RandomFloat(float min = 0, float max = 1) { return Random.value * (max-min) + min; } /// /// Returns random element from given collection. /// public static T RandomElement(IEnumerable enumerable) { return RandomElements(enumerable, 1)[0]; } /// /// Returns random element from given collection. /// public static List RandomElements(IEnumerable enumerable, int count, bool repeatable = false) { var list = enumerable.ToList(); // Not repeatable - we can take each value only once - sort by random and get needed amount if (!repeatable) return list.OrderBy(_ => RandomFloat()).Take(count).ToList(); // Repeatable - randomize each time and get value from list return new T[count].Select(_ => list[RandomInteger(0, list.Count - 1)]).ToList(); } /// /// Returns random element from given collection by function that determine weight. /// public static T RandomElementByWeight(IEnumerable enumerable, Func getWeight) { var list = enumerable.ToList(); var maxWeight = list.Sum(getWeight.Invoke); var randomWeight = RandomFloat(0, maxWeight); return list.FirstOrDefault(element => (randomWeight -= getWeight.Invoke(element)) <= 0f); } } }