Class RNG

java.lang.Object
squidpony.squidmath.RNG
All Implemented Interfaces:
Serializable, IRNG, RandomnessSource
Direct Known Subclasses:
CriticalRNG, DharmaRNG, StatefulRNG

public class RNG
extends Object
implements Serializable, IRNG
A wrapper class for working with random number generators in a more friendly way. Implements IRNG, which covers most of the API surface, but RNG implements a decent amount of additional methods. You should consider if your code needs these additional methods, and if not you should use IRNG as the type for when you need some random number generator.

Includes methods for getting values between two numbers and for getting random elements from a collection or array. There are methods to shuffle a collection and to get a random ordering that can be applied as one shuffle across multiple collections, such as via OrderedMap.reorder(int...), ArrayTools.reorder(ArrayList, int...), and so on. You can construct an RNG with all sorts of RandomnessSource implementations, and choosing them is usually not a big concern because the default works very well. If you target GWT, then it is suggested that you use GWTRNG instead of RNG; both implement IRNG, which is enough for most usage across SquidLib, but GWTRNG is optimized heavily for better performance on GWT, even returning long values faster than implementations that natively do their math on longs. It has worse performance on 64-bit PCs and mobile devices, but should also have better performance on 32-bit PCs and mobile devices.
But if you do want advice on what RandomnessSource to use... DiverRNG is the default, and is the fastest generator that passes most tests and can produce all 64-bit values, and though relative to many of the others it has a significantly shorter period (the amount of random numbers it will go through before repeating the sequence), this almost never matters in games, and is primarily relevant for massively-parallel scientific programs. DiverRNG has a period of pow(2, 64) as opposed to XoRoRNG's pow(2, 128) - 1, or LongPeriodRNG's pow(2, 1024) - 1. LightRNG is a solid choice and a former default RandomnessSource; additional features of LightRNG are exposed in MoonwalkRNG and using MoonwalkRNG is recommended if you need unusual features like skipping backwards in a random number sequence, taking a result of a nextLong() call and reversing it to get the state that produced it, or calculating the distance in number of nextLong() calls between two results of nextLong() calls. LightRNG is a StatefulRandomness, which lets it be used in StatefulRNG, and so is DiverRNG, but LightRNG is also a SkippingRandomness, which means you can leap forward or backwards in its sequence very efficiently (DiverRNG is not a SkippingRandomness). ThrustAltRNG provides similar qualities to LightRNG, and is one of the fastest generators here, but can't produce all possible 64-bit values (possibly some 32-bit values as well); it was the default at one point so you may want to keep compatibility with some versions by specifying ThrustAltRNG. The defaults have changed in the past as issues are found in various generators; LightRNG has high quality all-around but is slower than the other defaults, ThrustAltRNG can't produce all results, LinnormRNG passed tests in an earlier version of the PractRand test suite but now fails in the current version, and now the default is DiverRNG, which shares the known issue of LightRNG and LinnormRNG that it can't produce the same result twice from nextLong() until the generator exhausts its period and repeats its output from the beginning. For most cases, you should decide between DiverRNG, ThrustAltRNG, LightRNG, LongPeriodRNG, MiniMover64RNG, and XoshiroStarPhi32RNG based on your priorities. Some tasks are better solved by using a different class, usually GWTRNG, which can always be serialized on GWT to save its state easily and is usually the fastest substitute for RNG on that platform. DiverRNG is the best if you want high speed, very good quality of randomness, and expect to generate a reasonable quantity of numbers for a game (less than 18446744073709551616 numbers) without any single results being impossible. LightRNG is the second-best at the above criteria, but is the best option if you need an RNG that can skip backwards or jump forwards without incurring speed penalties. LongPeriodRNG is best if you for some reason need a massive amount of random numbers (as in, ten quintillion would be far too little) or want to split up such a large generator into unrelated subsequences. XoshiroStarPhi32RNG is best if GWT is a possible target but you either need to generate more than 18446744073709551616 numbers (but less than 340282366920938463463374607431768211455 numbers) or you need to ensure that each 128-bit chunk of output is unique; if GWT is a target but those specific needs don't matter, use GWTRNG. ThrustAltRNG and MiniMover64RNG are both faster than DiverRNG usually (MiniMover64RNG is the fastest), but because they are unable to generate some outputs, that may make them a poor choice for some usage (ThrustAltRNG also has some bias toward specific numbers and produces them more frequently, but not frequently enough to make it fail statistical tests, and ThrustAltRNG can skip around in its output sequence like LightRNG).
There are many more RandomnessSource implementations! You might want significantly less predictable random results, which IsaacRNG can provide, along with a large period. The quality of PermutedRNG is also good, usually, and it has a sound basis in PCG-Random, an involved library with many variants on its RNGs.
There may be reasons why you would want a random number generator that uses 32-bit math instead of the more common 64-bit math, but using a 32-bit int on desktop and Android won't act the same as that same 32-bit int on GWT. Since GWT is stuck with JavaScript's implementation of ints with doubles, overflow (which is needed for an RNG) doesn't work with ints as expected, but does with GWT's implementation of longs. If targeting GWT, you should probably consider GWTRNG or SilkRNG, which would be used in place of this class and have a similar API. You can instead choose a RandomnessSource that is efficient on GWT; Lathe32RNG is significantly faster at producing int values on GWT than any long-based generator, and will produce the same results on GWT as on desktop or Android (not all 32-bit generators do this). Starfish32RNG goes one step further than Lathe32RNG at an even distribution, and has better quality, but is slightly slower; it is also used internally by GWTRNG. While Lathe32RNG can produce all ints over the course of its period, it will produce some pairs of ints, or longs, more often than others and will never produce some longs. Starfish32RNG will produce all longs but one. Oriole32RNG and XoshiroStarPhi32RNG are also GWT-safe, but other generators that were thought to be GWT-friendly are not. PintRNG is a GWT-unsafe generators with other uses, but should not be used on GWT. All other RandomnessSources use longs, and so will be slower than the recommended Starfish32RNG or Lathe32RNG on GWT, but probably are much faster on 64-bit JREs.

Author:
Eben Howard - http://squidpony.com - howard@squidpony.com, Tommy Ettinger, smelC
See Also:
Serialized Form
  • Nested Class Summary

    Nested Classes 
    Modifier and Type Class Description
    static class  RNG.CustomRandom
    A subclass of java.util.Random that uses a RandomnessSource supplied by the user instead of the default.
  • Field Summary

    Fields 
    Modifier and Type Field Description
    protected Random ran  
    protected RandomnessSource random  
  • Constructor Summary

    Constructors 
    Constructor Description
    RNG()
    Default constructor; uses DiverRNG, which is of high quality, but low period (which rarely matters for games), and has excellent speed, tiny state size, and natively generates 64-bit numbers.
    RNG​(long seed)
    Default constructor; uses DiverRNG, which is of high quality, but low period (which rarely matters for games), and has excellent speed, tiny state size, and natively generates 64-bit numbers.
    RNG​(CharSequence seedString)
    String-seeded constructor; uses a platform-independent hash of the String (it does not use String.hashCode, instead using CrossHash.hash64(CharSequence)) as a seed for DiverRNG, which is of high quality, but low period (which rarely matters for games), and has excellent speed, tiny state size, and natively generates 64-bit numbers.
    RNG​(RandomnessSource random)
    Uses the provided source of randomness for all calculations.
  • Method Summary

    Modifier and Type Method Description
    long approximateBits​(int bitCount)
    Deprecated.
    Random asRandom()  
    double between​(double min, double max)
    Returns a value from an even distribution from min (inclusive) to max (exclusive).
    int between​(int min, int max)
    Returns a value between min (inclusive) and max (exclusive).
    long between​(long min, long max)
    Returns a value between min (inclusive) and max (exclusive).
    int betweenWeighted​(int min, int max, int samples)
    Returns the average of a number of randomly selected numbers from the provided range, with min being inclusive and max being exclusive.
    RNG copy()
    Creates a copy of this RNG; it will generate the same random numbers, given the same calls in order, as this RNG at the point copy() is called.
    boolean equals​(Object o)  
    Iterable<Coord> getRandomCellsIterable​(int width, int height, int size)
    Use that to get random cells in a rectangular map.
    <T> T getRandomElement​(Collection<T> coll)
    Returns a random element from the provided Collection, which should have predictable iteration order if you want predictable behavior for identical RNG seeds, though it will get a random element just fine for any Collection (just not predictably in all cases).
    <T> T getRandomElement​(List<T> list)
    Returns a random element from the provided list.
    <T> T getRandomElement​(T[] array)
    Returns a random element from the provided array and maintains object type.
    RandomnessSource getRandomness()  
    <T> Iterable<T> getRandomStartIterable​(List<T> list)
    Get an Iterable that starts at a random location in list and continues on through list in its current order.
    Coord[] getRandomUniqueCells​(int startX, int startY, int width, int height)
    Gets an array of unique Coords, from (startX,startY) inclusive to (startX+width,startY+height) exclusive, in a random order, with the array containing width * height items.
    Coord[] getRandomUniqueCells​(int startX, int startY, int width, int height, int size)
    Gets an array of unique Coords, from (startX,startY) inclusive to (startX+width,startY+height) exclusive, in a random order, with the array containing Math.min(width * height, size) items.
    Coord[] getRandomUniqueCells​(int startX, int startY, int width, int height, Coord[] dest)
    Assigns to dest an array of unique Coords, from (startX,startY) inclusive to (startX+width,startY+height) exclusive, in a random order, with dest after this is called containing the lesser of width * height or dest.length items.
    int hashCode()  
    double maxDoubleOf​(double bound, int trials)
    Gets the maximum random double between 0 and bound generated out of trials generated numbers.
    float maxFloatOf​(float bound, int trials)
    Gets the maximum random float between 0 and bound generated out of trials generated numbers.
    int maxIntOf​(int bound, int trials)
    Gets the maximum random int between 0 and bound generated out of trials generated numbers.
    long maxLongOf​(long bound, int trials)
    Gets the maximum random long between 0 and bound generated out of trials generated numbers.
    double minDoubleOf​(double bound, int trials)
    Gets the minimum random double between 0 and bound generated out of trials generated numbers.
    float minFloatOf​(float bound, int trials)
    Gets the minimum random float between 0 and bound generated out of trials generated numbers.
    int minIntOf​(int bound, int trials)
    Gets the minimum random int between 0 and bound generated out of trials generated numbers.
    long minLongOf​(long bound, int trials)
    Gets the minimum random long between 0 and bound generated out of trials generated numbers.
    int next​(int bits)
    Get up to 32 bits (inclusive) of random output; the int this produces will not require more than bits bits to represent.
    boolean nextBoolean()
    Get a random bit of state, interpreted as true or false with approximately equal likelihood.
    void nextBytes​(byte[] bytes)
    Generates random bytes and places them into the given byte array, modifying it in-place.
    Coord nextCoord​(int width, int height)
    Gets a random Coord that has x between 0 (inclusive) and width (exclusive) and y between 0 (inclusive) and height (exclusive).
    float nextCurvedFloat()
    Generates a random float with a curved distribution that centers on 0 (where it has a bias) and can (rarely) approach -1f and 1f, but not go beyond those bounds.
    double nextDouble()
    Gets a random double between 0.0 inclusive and 1.0 exclusive.
    double nextDouble​(double outer)
    This returns a random double between 0.0 (inclusive) and outer (exclusive).
    double nextDoubleInclusive()
    Gets a random double between 0.0 inclusive and 1.0 inclusive.
    double nextDoubleInclusive​(double outer)
    This returns a random double between 0.0 (inclusive) and outer (inclusive).
    float nextFloat()
    Gets a random float between 0.0f inclusive and 1.0f exclusive.
    float nextFloat​(float outer)
    This returns a random float between 0.0f (inclusive) and outer (exclusive).
    float nextFloatInclusive()
    Gets a random float between 0.0f inclusive and 1.0f inclusive.
    float nextFloatInclusive​(float outer)
    This returns a random float between 0.0f (inclusive) and outer (inclusive).
    int nextInt()
    Get a random integer between Integer.MIN_VALUE to Integer.MAX_VALUE (both inclusive).
    int nextInt​(int bound)
    Returns a random non-negative integer below the given bound, or 0 if the bound is 0 or negative.
    int nextIntHasty​(int bound)
    Returns a random non-negative integer between 0 (inclusive) and the given bound (exclusive), or 0 if the bound is 0.
    long nextLong()
    Get a random long between Long.MIN_VALUE to Long.MAX_VALUE (both inclusive).
    long nextLong​(long bound)
    Gets a pseudo-random long between 0 and bound.
    int nextSignedInt​(int bound)
    Returns a random non-negative integer between 0 (inclusive) and the given bound (exclusive), or 0 if the bound is 0.
    long nextSignedLong​(long bound)
    Exclusive on bound (which may be positive or negative), with an inner bound of 0.
    long randomInterleave()
    Deprecated.
    See GreasedRegion.randomInterleave(RandomnessSource) for where this will be moved
    int[] randomOrdering​(int length)
    Generates a random permutation of the range from 0 (inclusive) to length (exclusive).
    int[] randomOrdering​(int length, int[] dest)
    Generates a random permutation of the range from 0 (inclusive) to length (exclusive) and stores it in the dest parameter, avoiding allocations.
    <T> List<T> randomPortion​(Collection<T> data, int count)
    Gets a random portion of a Collection and returns it as a new List.
    <T> T[] randomPortion​(T[] data, T[] output)
    Gets a random portion of data (an array), assigns that portion to output (an array) so that it fills as much as it can, and then returns output.
    int[] randomRange​(int start, int end, int count)
    Gets a random subrange of the non-negative ints from start (inclusive) to end (exclusive), using count elements.
    <T> List<T> randomRotation​(List<T> l)
    Given a List l, this selects a random element of l to be the first value in the returned list l2.
    void setRandomness​(RandomnessSource random)  
    <T> ArrayList<T> shuffle​(Collection<T> elements)
    Shuffles a Collection of T using the Fisher-Yates algorithm and returns an ArrayList of T.
    <T> ArrayList<T> shuffle​(Collection<T> elements, ArrayList<T> buf)
    Shuffles a Collection of T using the Fisher-Yates algorithm.
    <T> T[] shuffle​(T[] elements)
    Shuffle an array using the Fisher-Yates algorithm and returns a shuffled copy.
    <T> T[] shuffle​(T[] elements, T[] dest)
    Shuffle an array using the Fisher-Yates algorithm.
    <T> List<T> shuffleInPlace​(List<T> elements)
    Shuffles a Collection of T items in-place using the Fisher-Yates algorithm.
    <T> T[] shuffleInPlace​(T[] elements)
    Shuffles an array in-place using the Fisher-Yates algorithm.
    Serializable toSerializable()
    Returns this RNG in a way that can be deserialized even if only IRNG's methods can be called.
    String toString()  

    Methods inherited from class java.lang.Object

    clone, finalize, getClass, notify, notifyAll, wait, wait, wait
  • Field Details

  • Constructor Details

    • RNG

      public RNG()
      Default constructor; uses DiverRNG, which is of high quality, but low period (which rarely matters for games), and has excellent speed, tiny state size, and natively generates 64-bit numbers.
      Previous versions of SquidLib used different implementations, including LightRNG, ThrustAltRNG, LinnormRNG, and MersenneTwister. You can still use one of these by instantiating one of those classes and passing it to RNG(RandomnessSource), which may be the best way to ensure the same results across versions.
    • RNG

      public RNG​(long seed)
      Default constructor; uses DiverRNG, which is of high quality, but low period (which rarely matters for games), and has excellent speed, tiny state size, and natively generates 64-bit numbers. The seed can be any long, including 0.
      Parameters:
      seed - any long
    • RNG

      public RNG​(CharSequence seedString)
      String-seeded constructor; uses a platform-independent hash of the String (it does not use String.hashCode, instead using CrossHash.hash64(CharSequence)) as a seed for DiverRNG, which is of high quality, but low period (which rarely matters for games), and has excellent speed, tiny state size, and natively generates 64-bit numbers.
    • RNG

      public RNG​(RandomnessSource random)
      Uses the provided source of randomness for all calculations. This constructor should be used if an alternate RandomnessSource other than DiverRNG is desirable, such as to keep compatibility with earlier SquidLib versions that defaulted to MersenneTwister, LightRNG, ThrustAltRNG, or LinnormRNG.
      If the parameter is null, this is equivalent to using RNG() as the constructor.
      Parameters:
      random - the source of pseudo-randomness, such as a LightRNG or LongPeriodRNG object
  • Method Details

    • asRandom

      public Random asRandom()
      Returns:
      a Random instance that can be used for legacy compatibility
    • between

      public double between​(double min, double max)
      Returns a value from an even distribution from min (inclusive) to max (exclusive).
      Specified by:
      between in interface IRNG
      Parameters:
      min - the minimum bound on the return value (inclusive)
      max - the maximum bound on the return value (exclusive)
      Returns:
      the found value
    • between

      public int between​(int min, int max)
      Returns a value between min (inclusive) and max (exclusive).
      The inclusive and exclusive behavior is to match the behavior of the similar method that deals with floating point values.
      If min and max happen to be the same, min is returned (breaking the exclusive behavior, but it's convenient to do so).
      Specified by:
      between in interface IRNG
      Parameters:
      min - the minimum bound on the return value (inclusive)
      max - the maximum bound on the return value (exclusive)
      Returns:
      the found value
    • between

      public long between​(long min, long max)
      Returns a value between min (inclusive) and max (exclusive).

      The inclusive and exclusive behavior is to match the behavior of the similar method that deals with floating point values.

      Specified by:
      between in interface IRNG
      Parameters:
      min - the minimum bound on the return value (inclusive)
      max - the maximum bound on the return value (exclusive)
      Returns:
      the found value
    • betweenWeighted

      public int betweenWeighted​(int min, int max, int samples)
      Returns the average of a number of randomly selected numbers from the provided range, with min being inclusive and max being exclusive. It will sample the number of times passed in as the third parameter.

      The inclusive and exclusive behavior is to match the behavior of the similar method that deals with floating point values.

      This can be used to weight RNG calls to the average between min and max.

      Parameters:
      min - the minimum bound on the return value (inclusive)
      max - the maximum bound on the return value (exclusive)
      samples - the number of samples to take
      Returns:
      the found value
    • getRandomElement

      public <T> T getRandomElement​(T[] array)
      Returns a random element from the provided array and maintains object type.
      Specified by:
      getRandomElement in interface IRNG
      Type Parameters:
      T - the type of the returned object
      Parameters:
      array - the array to get an element from
      Returns:
      the randomly selected element
    • getRandomElement

      public <T> T getRandomElement​(List<T> list)
      Returns a random element from the provided list. If the list is empty then null is returned.
      Specified by:
      getRandomElement in interface IRNG
      Type Parameters:
      T - the type of the returned object
      Parameters:
      list - the list to get an element from
      Returns:
      the randomly selected element
    • getRandomElement

      public <T> T getRandomElement​(Collection<T> coll)
      Returns a random element from the provided Collection, which should have predictable iteration order if you want predictable behavior for identical RNG seeds, though it will get a random element just fine for any Collection (just not predictably in all cases). If you give this a Set, it should be a LinkedHashSet or some form of sorted Set like TreeSet if you want predictable results. Any List or Queue should be fine. Map does not implement Collection, thank you very much Java library designers, so you can't actually pass a Map to this, though you can pass the keys or values. If coll is empty, returns null.

      Requires iterating through a random amount of coll's elements, so performance depends on the size of coll but is likely to be decent, as long as iteration isn't unusually slow. This replaces getRandomElement(Queue), since Queue implements Collection and the older Queue-using implementation was probably less efficient.

      Specified by:
      getRandomElement in interface IRNG
      Type Parameters:
      T - the type of the returned object
      Parameters:
      coll - the Collection to get an element from; remember, Map does not implement Collection
      Returns:
      the randomly selected element
    • randomRotation

      public <T> List<T> randomRotation​(List<T> l)
      Given a List l, this selects a random element of l to be the first value in the returned list l2. It retains the order of elements in l after that random element and makes them follow the first element in l2, and loops around to use elements from the start of l after it has placed the last element of l into l2.
      Essentially, it does what it says on the tin. It randomly rotates the List l.
      If you only need to iterate through a collection starting at a random point, the method getRandomStartIterable() should have better performance. This was GWT incompatible before GWT 2.8.0 became the version SquidLib uses; now this method works fine with GWT.
      Type Parameters:
      T - No restrictions on type. Changes to elements of the returned List will be reflected in the parameter.
      Parameters:
      l - A List that will not be modified by this method. All elements of this parameter will be shared with the returned List.
      Returns:
      A shallow copy of l that has been rotated so its first element has been randomly chosen from all possible elements but order is retained. Will "loop around" to contain element 0 of l after the last element of l, then element 1, etc.
    • getRandomStartIterable

      public <T> Iterable<T> getRandomStartIterable​(List<T> list)
      Get an Iterable that starts at a random location in list and continues on through list in its current order. Loops around to the beginning after it gets to the end, stops when it returns to the starting location.
      You should not modify list while you use the returned reference. And there'll be no ConcurrentModificationException to detect such erroneous uses.
      Parameters:
      list - A list with a constant-time List.get(int) method (otherwise performance degrades).
      Returns:
      An Iterable that iterates over list but start at a random index. If the chosen index is i, the iterator will return: list[i]; list[i+1]; ...; list[list.length() - 1]; list[0]; list[i-1]
    • shuffle

      public <T> T[] shuffle​(T[] elements)
      Shuffle an array using the Fisher-Yates algorithm and returns a shuffled copy. GWT-compatible since GWT 2.8.0, which is the default if you use libGDX 1.9.5 or higher.
      Wikipedia has more on this algorithm.
      Specified by:
      shuffle in interface IRNG
      Type Parameters:
      T - can be any non-primitive type.
      Parameters:
      elements - an array of T; will not be modified
      Returns:
      a shuffled copy of elements
    • shuffleInPlace

      public <T> T[] shuffleInPlace​(T[] elements)
      Shuffles an array in-place using the Fisher-Yates algorithm. If you don't want the array modified, use shuffle(Object[], Object[]).
      Wikipedia has more on this algorithm.
      Specified by:
      shuffleInPlace in interface IRNG
      Type Parameters:
      T - can be any non-primitive type.
      Parameters:
      elements - an array of T; will be modified
      Returns:
      elements after shuffling it in-place
    • shuffle

      public <T> T[] shuffle​(T[] elements, T[] dest)
      Shuffle an array using the Fisher-Yates algorithm. If possible, create a new array or reuse an existing array with the same length as elements and pass it in as dest; the dest array will contain the shuffled contents of elements and will also be returned as-is.
      Wikipedia has more on this algorithm.
      Specified by:
      shuffle in interface IRNG
      Type Parameters:
      T - can be any non-primitive type.
      Parameters:
      elements - an array of T; will not be modified
      dest - Where to put the shuffle. If it does not have the same length as elements, this will use the randomPortion method of this class to fill the smaller dest.
      Returns:
      dest after modifications
    • shuffle

      public <T> ArrayList<T> shuffle​(Collection<T> elements)
      Shuffles a Collection of T using the Fisher-Yates algorithm and returns an ArrayList of T.
      Wikipedia has more on this algorithm.
      Specified by:
      shuffle in interface IRNG
      Type Parameters:
      T - can be any non-primitive type.
      Parameters:
      elements - a Collection of T; will not be modified
      Returns:
      a shuffled ArrayList containing the whole of elements in pseudo-random order.
    • shuffle

      public <T> ArrayList<T> shuffle​(Collection<T> elements, ArrayList<T> buf)
      Shuffles a Collection of T using the Fisher-Yates algorithm. The result is allocated if buf is null or if buf isn't empty, otherwise elements is poured into buf.
      Wikipedia has more on this algorithm.
      Specified by:
      shuffle in interface IRNG
      Type Parameters:
      T - can be any non-primitive type.
      Parameters:
      elements - a Collection of T; will not be modified
      buf - a buffer as an ArrayList that will be filled with the shuffled contents of elements; if null or non-empty, a new ArrayList will be allocated and returned
      Returns:
      a shuffled ArrayList containing the whole of elements in pseudo-random order.
    • shuffleInPlace

      public <T> List<T> shuffleInPlace​(List<T> elements)
      Shuffles a Collection of T items in-place using the Fisher-Yates algorithm. This only shuffles List data structures. If you don't want the array modified, use shuffle(Collection), which returns a List as well.
      Wikipedia has more on this algorithm.
      Specified by:
      shuffleInPlace in interface IRNG
      Type Parameters:
      T - can be any non-primitive type.
      Parameters:
      elements - a Collection of T; will be modified
      Returns:
      elements after shuffling it in-place
    • randomOrdering

      public int[] randomOrdering​(int length)
      Generates a random permutation of the range from 0 (inclusive) to length (exclusive). Useful for passing to OrderedMap or OrderedSet's reorder() methods.
      Specified by:
      randomOrdering in interface IRNG
      Parameters:
      length - the size of the ordering to produce
      Returns:
      a random ordering containing all ints from 0 to length (exclusive)
    • randomOrdering

      public int[] randomOrdering​(int length, int[] dest)
      Generates a random permutation of the range from 0 (inclusive) to length (exclusive) and stores it in the dest parameter, avoiding allocations. Useful for passing to OrderedMap or OrderedSet's reorder() methods.
      Specified by:
      randomOrdering in interface IRNG
      Parameters:
      length - the size of the ordering to produce
      dest - the destination array; will be modified
      Returns:
      dest, filled with a random ordering containing all ints from 0 to length (exclusive)
    • randomPortion

      public <T> List<T> randomPortion​(Collection<T> data, int count)
      Gets a random portion of a Collection and returns it as a new List. Will only use a given position in the given Collection at most once; does this by shuffling a copy of the Collection and getting a section of it.
      Type Parameters:
      T - can be any non-primitive type
      Parameters:
      data - a Collection of T; will not be modified.
      count - the non-negative number of elements to randomly take from data
      Returns:
      a List of T that has length equal to the smaller of count or data.length
    • randomRange

      public int[] randomRange​(int start, int end, int count)
      Gets a random subrange of the non-negative ints from start (inclusive) to end (exclusive), using count elements. May return an empty array if the parameters are invalid (end is less than/equal to start, or start is negative).
      Parameters:
      start - the start of the range of numbers to potentially use (inclusive)
      end - the end of the range of numbers to potentially use (exclusive)
      count - the total number of elements to use; will be less if the range is smaller than count
      Returns:
      an int array that contains at most one of each number in the range
    • nextCurvedFloat

      public float nextCurvedFloat()
      Generates a random float with a curved distribution that centers on 0 (where it has a bias) and can (rarely) approach -1f and 1f, but not go beyond those bounds. This is similar to Random.nextGaussian() in that it uses a curved distribution, but it is not the same. The distribution for the values is similar to Irwin-Hall, and is frequently near 0 but not too-rarely near -1f or 1f. It cannot produce values greater than or equal to 1f, or less than -1f, but it can produce -1f.
      Returns:
      a deterministic float between -1f (inclusive) and 1f (exclusive), that is very likely to be close to 0f
    • nextDouble

      public double nextDouble()
      Gets a random double between 0.0 inclusive and 1.0 exclusive. This returns a maximum of 0.9999999999999999 because that is the largest double value that is less than 1.0 .
      Specified by:
      nextDouble in interface IRNG
      Returns:
      a double between 0.0 (inclusive) and 0.9999999999999999 (inclusive)
    • nextDouble

      public double nextDouble​(double outer)
      This returns a random double between 0.0 (inclusive) and outer (exclusive). The value for outer can be positive or negative. Because of how math on doubles works, there are at most 2 to the 53 values this can return for any given outer bound, and very large values for outer will not necessarily produce all numbers you might expect.
      Specified by:
      nextDouble in interface IRNG
      Parameters:
      outer - the outer exclusive bound as a double; can be negative or positive
      Returns:
      a double between 0.0 (inclusive) and outer (exclusive)
    • nextFloat

      public float nextFloat()
      Gets a random float between 0.0f inclusive and 1.0f exclusive. This returns a maximum of 0.99999994 because that is the largest float value that is less than 1.0f .
      Specified by:
      nextFloat in interface IRNG
      Returns:
      a float between 0f (inclusive) and 0.99999994f (inclusive)
    • nextFloat

      public float nextFloat​(float outer)
      This returns a random float between 0.0f (inclusive) and outer (exclusive). The value for outer can be positive or negative. Because of how math on floats works, there are at most 2 to the 24 values this can return for any given outer bound, and very large values for outer will not necessarily produce all numbers you might expect.
      Specified by:
      nextFloat in interface IRNG
      Parameters:
      outer - the outer exclusive bound as a float; can be negative or positive
      Returns:
      a float between 0f (inclusive) and outer (exclusive)
    • nextBoolean

      public boolean nextBoolean()
      Get a random bit of state, interpreted as true or false with approximately equal likelihood. This may have better behavior than rng.next(1), depending on the RandomnessSource implementation; the default DiverRNG will behave fine, as will LightRNG and ThrustAltRNG (these all use similar algorithms), but the normally-high-quality XoRoRNG will produce very predictable output with rng.next(1) and very good output with rng.nextBoolean(). This is a known and considered flaw of Xoroshiro128+, the algorithm used by XoRoRNG, and a large number of generators have lower quality on the least-significant bit than the most- significant bit, where this method only checks the most-significant bit.
      Specified by:
      nextBoolean in interface IRNG
      Returns:
      a random boolean.
    • nextLong

      public long nextLong()
      Get a random long between Long.MIN_VALUE to Long.MAX_VALUE (both inclusive).
      Specified by:
      nextLong in interface IRNG
      Specified by:
      nextLong in interface RandomnessSource
      Returns:
      a 64-bit random long.
    • nextLong

      public long nextLong​(long bound)
      Gets a pseudo-random long between 0 and bound. Exclusive on bound (which must be positive), with an inner bound of 0 If bound is negative or 0, this always returns 0. You can use nextSignedLong(long) to use a negative bound. The technique that
      Credit for this method goes to Rafael Baptista's blog for the original idea, and the JDK10 Math class' usage of Karatsuba multiplication for the current algorithm. This method is drastically faster than the previous implementation when the bound varies often (roughly 4x faster, possibly more). It also always gets exactly one random long, so by default it advances the state as much as nextLong().
      Specified by:
      nextLong in interface IRNG
      Parameters:
      bound - the outer exclusive bound; should be positive, otherwise this always returns 0L
      Returns:
      a random long between 0 (inclusive) and bound (exclusive)
    • nextSignedLong

      public long nextSignedLong​(long bound)
      Exclusive on bound (which may be positive or negative), with an inner bound of 0. If bound is negative this returns a negative long; if bound is positive this returns a positive long. The bound can even be 0, which will cause this to return 0L every time. This uses a biased technique to get numbers from large ranges, but the amount of bias is incredibly small (expected to be under 1/1000 if enough random ranged numbers are requested, which is about the same as an unbiased method that was also considered).It may have noticeable bias if the generator's period is exhausted by only calls to this method. Unlike all unbiased methods, this advances the state by an equivalent to exactly one call to nextLong(), where rejection sampling would sometimes advance by one call, but other times by arbitrarily many more.
      Credit for this method goes to Rafael Baptista's blog for the original idea, and the JDK10 Math class' usage of Hacker's Delight code for the current algorithm. This method is drastically faster than the previous implementation when the bound varies often (roughly 4x faster, possibly more). It also always gets exactly one random long, so by default it advances the state as much as nextLong().
      Specified by:
      nextSignedLong in interface IRNG
      Parameters:
      bound - the outer exclusive bound; can be positive or negative
      Returns:
      a random long between 0 (inclusive) and bound (exclusive)
    • nextSignedInt

      public int nextSignedInt​(int bound)
      Returns a random non-negative integer between 0 (inclusive) and the given bound (exclusive), or 0 if the bound is 0. The bound can be negative, which will produce 0 or a negative result. This is almost identical to the earlier nextIntHasty(int) except that it will perform better when the RandomnessSource this uses natively produces 32-bit output. It was added to the existing nextIntHasty() so existing code using nextIntHasty would produce the same results, but new code matches the API with nextSignedLong(long). This is implemented slightly differently in AbstractRNG, and different results should be expected when using code based on that abstract class.
      Credit goes to Daniel Lemire, http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
      Specified by:
      nextSignedInt in interface IRNG
      Parameters:
      bound - the outer bound (exclusive), can be negative or positive
      Returns:
      the found number
    • nextInt

      public int nextInt​(int bound)
      Returns a random non-negative integer below the given bound, or 0 if the bound is 0 or negative. Always makes one call to the RandomnessSource.next(int) method of the RandomnessSource that would be returned by getRandomness(), even if bound is 0 or negative, to avoid branching and also to ensure consistent advancement rates for the RandomnessSource (this can be important if you use a SkippingRandomness and want to go back before a result was produced).
      This method changed a fair amount on April 5, 2018 to better support RandomnessSource implementations with a slower nextLong() method, such as Lathe32RNG, and to avoid branching/irregular state advancement/modulus operations. It is now almost identical to nextIntHasty(int), but won't return negative results if bound is negative (matching its previous behavior). This may have statistical issues (small ones) if bound is very large (the estimate is still at least a bound of a billion or more before issues are observable). Consider nextSignedInt(int) if the bound should be allowed to be negative; nextIntHasty(int) is here for compatibility with earlier versions, but the two methods are very similar.
      Credit goes to Daniel Lemire, http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
      Specified by:
      nextInt in interface IRNG
      Parameters:
      bound - the upper bound (exclusive)
      Returns:
      the found number
    • nextIntHasty

      public int nextIntHasty​(int bound)
      Returns a random non-negative integer between 0 (inclusive) and the given bound (exclusive), or 0 if the bound is 0. The bound can be negative, which will produce 0 or a negative result. Uses an aggressively optimized technique that has some bias, but mostly for values of bound over 1 billion. This method is no more "hasty" than nextInt(int), but it is a little faster than that method because this avoids special behavior for when bound is negative.
      Credit goes to Daniel Lemire, http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
      Parameters:
      bound - the outer bound (exclusive), can be negative or positive
      Returns:
      the found number
    • nextBytes

      public void nextBytes​(byte[] bytes)
      Generates random bytes and places them into the given byte array, modifying it in-place. The number of random bytes produced is equal to the length of the byte array. Unlike the method in java.util.Random, this generates 8 bytes at a time, which can be more efficient with many RandomnessSource types than the JDK's method that generates 4 bytes at a time.
      Adapted from code in the JavaDocs of Random.nextBytes(byte[]).
      Parameters:
      bytes - the byte array to fill with random bytes; cannot be null, will be modified
      Throws:
      NullPointerException - if the byte array is null
    • nextInt

      public int nextInt()
      Get a random integer between Integer.MIN_VALUE to Integer.MAX_VALUE (both inclusive).
      Specified by:
      nextInt in interface IRNG
      Returns:
      a 32-bit random int.
    • next

      public int next​(int bits)
      Get up to 32 bits (inclusive) of random output; the int this produces will not require more than bits bits to represent.
      Specified by:
      next in interface IRNG
      Specified by:
      next in interface RandomnessSource
      Parameters:
      bits - an int between 1 and 32, both inclusive
      Returns:
      a random number that fits in the specified number of bits
    • getRandomness

    • setRandomness

      public void setRandomness​(RandomnessSource random)
    • copy

      public RNG copy()
      Creates a copy of this RNG; it will generate the same random numbers, given the same calls in order, as this RNG at the point copy() is called. The copy will not share references with this RNG.
      Specified by:
      copy in interface IRNG
      Specified by:
      copy in interface RandomnessSource
      Returns:
      a copy of this RNG
    • approximateBits

      @Deprecated public long approximateBits​(int bitCount)
      Deprecated.
      Generates a random 64-bit long with a number of '1' bits (Hamming weight) equal on average to bitCount. For example, calling this with a parameter of 32 will be equivalent to calling nextLong() on this object's RandomnessSource (it doesn't consider overridden nextLong() methods, where present, on subclasses of RNG). Calling this with a parameter of 16 will have on average 16 of the 64 bits in the returned long set to '1', distributed pseudo-randomly, while a parameter of 47 will have on average 47 bits set. This can be useful for certain code that uses bits to represent data but needs a different ratio of set bits to unset bits than 1:1.
      This method is deprecated because it really only finds usage in GreasedRegion, so it has been moved there and made so it can take any RandomnessSource as a parameter, including any IRNG or RNG.
      Parameters:
      bitCount - an int, only considered if between 0 and 64, that is the average number of bits to set
      Returns:
      a 64-bit long that, on average, should have bitCount bits set to 1, potentially anywhere in the long
    • randomInterleave

      Deprecated.
      See GreasedRegion.randomInterleave(RandomnessSource) for where this will be moved
      Gets a somewhat-random long with exactly 32 bits set; in each pair of bits starting at bit 0 and bit 1, then bit 2 and bit 3, up to bit 62 and bit 3, one bit will be 1 and one bit will be 0 in each pair.
      Not exactly general-use; meant for generating data for GreasedRegion. This is deprecated in favor of the version in GreasedRegion.
      Returns:
      a random long with 32 "1" bits, distributed so exactly one bit is "1" for each pair of bits
    • minLongOf

      public long minLongOf​(long bound, int trials)
      Gets the minimum random long between 0 and bound generated out of trials generated numbers. Useful for when numbers should have a strong bias toward zero, but all possible values are between 0, inclusive, and bound, exclusive.
      Parameters:
      bound - the outer exclusive bound; may be negative or positive
      trials - how many numbers to generate and get the minimum of
      Returns:
      the minimum generated long between 0 and bound out of the specified amount of trials
    • maxLongOf

      public long maxLongOf​(long bound, int trials)
      Gets the maximum random long between 0 and bound generated out of trials generated numbers. Useful for when numbers should have a strong bias away from zero, but all possible values are between 0, inclusive, and bound, exclusive.
      Parameters:
      bound - the outer exclusive bound; may be negative or positive
      trials - how many numbers to generate and get the maximum of
      Returns:
      the maximum generated long between 0 and bound out of the specified amount of trials
    • minIntOf

      public int minIntOf​(int bound, int trials)
      Gets the minimum random int between 0 and bound generated out of trials generated numbers. Useful for when numbers should have a strong bias toward zero, but all possible values are between 0, inclusive, and bound, exclusive.
      Parameters:
      bound - the outer exclusive bound; may be negative or positive
      trials - how many numbers to generate and get the minimum of
      Returns:
      the minimum generated int between 0 and bound out of the specified amount of trials
    • maxIntOf

      public int maxIntOf​(int bound, int trials)
      Gets the maximum random int between 0 and bound generated out of trials generated numbers. Useful for when numbers should have a strong bias away from zero, but all possible values are between 0, inclusive, and bound, exclusive.
      Parameters:
      bound - the outer exclusive bound; may be negative or positive
      trials - how many numbers to generate and get the maximum of
      Returns:
      the maximum generated int between 0 and bound out of the specified amount of trials
    • minDoubleOf

      public double minDoubleOf​(double bound, int trials)
      Gets the minimum random double between 0 and bound generated out of trials generated numbers. Useful for when numbers should have a strong bias toward zero, but all possible values are between 0, inclusive, and bound, exclusive.
      Parameters:
      bound - the outer exclusive bound
      trials - how many numbers to generate and get the minimum of
      Returns:
      the minimum generated double between 0 and bound out of the specified amount of trials
    • maxDoubleOf

      public double maxDoubleOf​(double bound, int trials)
      Gets the maximum random double between 0 and bound generated out of trials generated numbers. Useful for when numbers should have a strong bias away from zero, but all possible values are between 0, inclusive, and bound, exclusive.
      Parameters:
      bound - the outer exclusive bound
      trials - how many numbers to generate and get the maximum of
      Returns:
      the maximum generated double between 0 and bound out of the specified amount of trials
    • minFloatOf

      public float minFloatOf​(float bound, int trials)
      Gets the minimum random float between 0 and bound generated out of trials generated numbers. Useful for when numbers should have a strong bias toward zero, but all possible values are between 0, inclusive, and bound, exclusive.
      Parameters:
      bound - the outer exclusive bound
      trials - how many numbers to generate and get the minimum of
      Returns:
      the minimum generated float between 0 and bound out of the specified amount of trials
    • maxFloatOf

      public float maxFloatOf​(float bound, int trials)
      Gets the maximum random float between 0 and bound generated out of trials generated numbers. Useful for when numbers should have a strong bias away from zero, but all possible values are between 0, inclusive, and bound, exclusive.
      Parameters:
      bound - the outer exclusive bound
      trials - how many numbers to generate and get the maximum of
      Returns:
      the maximum generated float between 0 and bound out of the specified amount of trials
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • equals

      public boolean equals​(Object o)
      Overrides:
      equals in class Object
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object
    • randomPortion

      public <T> T[] randomPortion​(T[] data, T[] output)
      Gets a random portion of data (an array), assigns that portion to output (an array) so that it fills as much as it can, and then returns output. Will only use a given position in the given data at most once; uses a Feistel Network to accomplish this without allocations. Internally, makes 2 calls to nextInt(), regardless of the data being randomized.
      Uses approximately the same code as LowStorageShuffler, but without any object or array allocations.
      Specified by:
      randomPortion in interface IRNG
      Type Parameters:
      T - can be any non-primitive type.
      Parameters:
      data - an array of T; will not be modified.
      output - an array of T that will be overwritten; should always be instantiated with the portion length
      Returns:
      output, after Math.min(output.length, data.length) unique items have been put into it from data
    • nextDoubleInclusive

      public double nextDoubleInclusive()
      Gets a random double between 0.0 inclusive and 1.0 inclusive.
      Returns:
      a double between 0.0 (inclusive) and 1.0 (inclusive)
    • nextDoubleInclusive

      public double nextDoubleInclusive​(double outer)
      This returns a random double between 0.0 (inclusive) and outer (inclusive). The value for outer can be positive or negative. Because of how math on doubles works, there are at most 2 to the 53 values this can return for any given outer bound, and very large values for outer will not necessarily produce all numbers you might expect.
      Parameters:
      outer - the outer inclusive bound as a double; can be negative or positive
      Returns:
      a double between 0.0 (inclusive) and outer (inclusive)
    • nextFloatInclusive

      public float nextFloatInclusive()
      Gets a random float between 0.0f inclusive and 1.0f inclusive.
      Returns:
      a float between 0f (inclusive) and 1f (inclusive)
    • nextFloatInclusive

      public float nextFloatInclusive​(float outer)
      This returns a random float between 0.0f (inclusive) and outer (inclusive). The value for outer can be positive or negative. Because of how math on floats works, there are at most 2 to the 24 values this can return for any given outer bound, and very large values for outer will not necessarily produce all numbers you might expect.
      Parameters:
      outer - the outer inclusive bound as a float; can be negative or positive
      Returns:
      a float between 0f (inclusive) and outer (inclusive)
    • nextCoord

      public Coord nextCoord​(int width, int height)
      Gets a random Coord that has x between 0 (inclusive) and width (exclusive) and y between 0 (inclusive) and height (exclusive). This makes one call to randomLong to generate (more than) 31 random bits for each axis, and should be very fast. Remember that Coord values are cached in a pool that starts able to hold up to 255 x and 255 y for positive values, and the pool should be grown with the static method Coord.expandPool() in order to efficiently use larger Coord values. If width and height are very large, greater than 100,000 for either, this particular method may show bias toward certain positions due to the "hasty" technique used to reduce the random numbers to the given size, but because most maps in tile-based games are relatively small, this technique should be fine.
      Credit goes to Daniel Lemire, http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
      Parameters:
      width - the upper bound (exclusive) for x coordinates
      height - the upper bound (exclusive) for y coordinates
      Returns:
      a random Coord between (0,0) inclusive and (width,height) exclusive
    • getRandomCellsIterable

      public Iterable<Coord> getRandomCellsIterable​(int width, int height, int size)
      Use that to get random cells in a rectangular map.
      Parameters:
      width - The map's width (bounds the x-coordinate in returned coords).
      height - The map's height (bounds the y-coordinate in returned coords).
      size - The number of elements in the returned iterable or anything negative for no bound (in which case the iterator is infinite, it's up to you to bound your iteration).
      Returns:
      An iterable that returns random cells in the rectangle (0,0) (inclusive) .. (width, height) (exclusive).
    • getRandomUniqueCells

      public Coord[] getRandomUniqueCells​(int startX, int startY, int width, int height)
      Gets an array of unique Coords, from (startX,startY) inclusive to (startX+width,startY+height) exclusive, in a random order, with the array containing width * height items.
      Parameters:
      startX - the inclusive starting x position
      startY - the inclusive starting y position
      width - the width of the space to place Coords in, extending from startX
      height - the height of the space to place Coords in, extending from startY
      Returns:
      an array containing width * height Coord items in random order, inside the given bounds
    • getRandomUniqueCells

      public Coord[] getRandomUniqueCells​(int startX, int startY, int width, int height, int size)
      Gets an array of unique Coords, from (startX,startY) inclusive to (startX+width,startY+height) exclusive, in a random order, with the array containing Math.min(width * height, size) items. If size is less than width times height, then not all Coords in the space will be used.
      Parameters:
      startX - the inclusive starting x position
      startY - the inclusive starting y position
      width - the width of the space to place Coords in, extending from startX
      height - the height of the space to place Coords in, extending from startY
      size - the size of the array to return; only matters if it is smaller than width * height
      Returns:
      an array containing Math.min(width * height, size) Coord items in random order, inside the given bounds
    • getRandomUniqueCells

      public Coord[] getRandomUniqueCells​(int startX, int startY, int width, int height, Coord[] dest)
      Assigns to dest an array of unique Coords, from (startX,startY) inclusive to (startX+width,startY+height) exclusive, in a random order, with dest after this is called containing the lesser of width * height or dest.length items. This will not allocate a new array for dest, but will create a temporary int array for handling the shuffle.
      Parameters:
      startX - the inclusive starting x position
      startY - the inclusive starting y position
      width - the width of the space to place Coords in, extending from startX
      height - the height of the space to place Coords in, extending from startY
      dest - a Coord array that will be modified to contain randomly-ordered Coords, but will not be resized
      Returns:
      dest, now with up to its first width * height items assigned to random Coords inside the given bounds
    • toSerializable

      Returns this RNG in a way that can be deserialized even if only IRNG's methods can be called.
      Specified by:
      toSerializable in interface IRNG
      Returns:
      a Serializable view of this RNG; always this