Skip to content

Instantly share code, notes, and snippets.

@corytrese
Created September 21, 2020 16:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save corytrese/2473317a2162cdd9d882c98a31938404 to your computer and use it in GitHub Desktop.
Save corytrese/2473317a2162cdd9d882c98a31938404 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
namespace RPG.Util {
public static class RandomExtensionMethods
{
/// <summary>
/// Returns a random long from min (inclusive) to max (exclusive)
/// </summary>
/// <param name="random">The given random instance</param>
/// <param name="min">The inclusive minimum bound</param>
/// <param name="max">The exclusive maximum bound. Must be greater or equal to min</param>
public static long NextLong(this Random random, long min, long max)
{
if(max < min)
throw new ArgumentOutOfRangeException("max", "max must be >= min!");
//Working with ulong so that modulo works correctly with values > long.MaxValue
ulong uRange = (ulong)(max - min);
//Loop to prevent a modolo bias; see http://stackoverflow.com/a/10984975/238419
//for more information.
//In the worst case, the expected number of calls is 2 (though usually it's
//much closer to 1, depending on min/max) so this loop doesn't really hurt performance at all.
ulong ulongRand;
do
{
byte[] buf = new byte[8];
random.NextBytes(buf);
ulongRand = (ulong)BitConverter.ToInt64(buf, 0);
} while(ulongRand > ulong.MaxValue - ((ulong.MaxValue % uRange) + 1) % uRange);
return (long)(ulongRand % uRange) + min;
}
/// <summary>
/// Returns a random long from 0 (inclusive) to max (exclusive)
/// </summary>
/// <param name="random">The given random instance</param>
/// <param name="max">The exclusive maximum bound. Must be greater or equal to min</param>
public static long NextLong(this Random random, long max)
{
return random.NextLong(0, max);
}
/// <summary>
/// Returns a random long over all possible values of long (except long.MaxValue, similar to
/// random.Next())
/// </summary>
/// <param name="random">The given random instance</param>
public static long NextLong(this Random random)
{
return random.NextLong(long.MinValue, long.MaxValue);
}
// Return a random item from an array.
public static T RandomElement<T>(this T[] items) {
// Return a random item.
return items[UnityEngine.Random.Range(0, items.Length)];
}
// Return a random item from a list.
public static T RandomElement<T>(this List<T> items) {
// Return a random item.
return items[UnityEngine.Random.Range(0, items.Count)];
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment