/// <summary> /// Selects a random element from a sequence. /// </summary> /// <typeparam name="T">Type of the elements.</typeparam> /// <param name="input">The sequance to choose a random element from.</param> /// <returns>A random element from the input.</returns> public static T RandomElement<T>(this IEnumerable<T> input) { // optimisation for lists var asList = input as IList<T>; if (asList != null) { if (asList.Count == 0) throw new InvalidOperationException("Sequence was empty"); return asList[GlobalRandom.Next(asList.Count)]; } T current = default(T); int count = 0; foreach (T element in input) { count++; if (GlobalRandom.Next(count) == 0) { current = element; } } if (count == 0) { throw new InvalidOperationException("Sequence was empty"); } return current; }
public static void Shuffle<T>(this IList<T> list) { int c = list.Count; for (int i = 0; i < c; i++) { int j = GlobalRandom.Next(c); T temp = list[i]; list[i] = list[j]; list[j] = temp; } }
/// <summary> /// Efficiently (O(n) with n the size of the input) selects a random number of elements from an enumerable. /// Each element has an equal chance to be contained in the result. The order of the output is arbitrary. /// </summary> /// <typeparam name="T">Type of the elements.</typeparam> /// <param name="input">The enumerable that random elements are selected from.</param> /// <param name="count">The number of random elements to return. If this is smaller than the inputs size, the entire input is returned.</param> /// <returns>Random elements from the input.</returns> public static IEnumerable<T> SelectRandom<T>(this IEnumerable<T> input, int count) { if (input == null) throw new ArgumentNullException("input"); if (count <= 0) return Enumerable.Empty<T>(); // optimisation for collections var asCollection = input as ICollection<T>; if (asCollection != null && count >= asCollection.Count) // if we take as much or more than we have, return input return input; // we could use a List<T> as well, but an array should // be slightly faster, for as long as count <= input.Count() var set = new T[count]; int i = 0; foreach (var item in input) { // copy first 'count' elements if (i < count) set[i] = item; else { // add others with decreasing likelyhood int index = GlobalRandom.Next(i + 1); if (index < count) set[index] = item; } i++; } // if the input was smaller than 'count', resize output if (i < count) Array.Resize(ref set, i); return set; }
public static bool NextBool(double probability) { return(GlobalRandom.NextDouble() < probability); }
/// <summary> /// Returns a random boolean value. /// </summary> /// <returns></returns> public static bool NextBool() { return(GlobalRandom.NextBool(0.5)); }
/// <summary> /// Returns random long integer in the interval [0, upper bound[ /// </summary> /// <param name="max">The exclusive upper bound</param> public static long NextLong(long max) { return(GlobalRandom.NextLong(0, max)); }
/// <summary> /// Returns a random angle(number between 0 and 2pi). /// </summary> /// <returns></returns> public static float Angle() { return(GlobalRandom.NextFloat(GameMath.TwoPi)); }