Class BasicRandom32

java.lang.Object
java.util.Random
squidpony.squidmath.BasicRandom32
All Implemented Interfaces:
Serializable, RandomnessSource

public class BasicRandom32
extends Random
implements RandomnessSource, Serializable
A low-quality but very fast RNG that has no apparent visual artifacts here; uses Mark Overton's CMR subcycle generator type, but modified to be especially GWT-friendly. Even though it has no visual issues when rendered as pixels, it still fails PractRand testing almost immediately. This is meant to be an answer to when people ask for a bare-minimum generator that's still "good enough" for games. It has a period of 0xFFF43787 or 4294195079, which can be exhausted in seconds if you only generate numbers in that time, but some seeds will be in a different cycle with a much lower period. The likelihood of choosing one of these seeds is low, less than a fiftieth of one percent, but it can happen. It cannot produce all possible ints in its longest cycle, and it can't produce even a fraction of all possible ints in its smallest cycle. It implements RandomnessSource, but if you just want to copy this class with no dependencies, then the class declaration can easily be changed to public class BasicRandom32 extends Random implements Serializable without any other changes. Note, it does extend java.util.Random for additional ease of integration, but doesn't use the slow synchronized keyword that Random's implementations do.
This Dr. Dobb's article has more on this type of generator.
Author:
Mark Overton, Tommy Ettinger
See Also:
Serialized Form
  • Field Summary

    Fields 
    Modifier and Type Field Description
    int state  
  • Constructor Summary

    Constructors 
    Constructor Description
    BasicRandom32()  
    BasicRandom32​(int seed)  
  • Method Summary

    Modifier and Type Method Description
    BasicRandom32 copy()
    Produces a copy of this RandomnessSource that, if next() and/or nextLong() are called on this object and the copy, both will generate the same sequence of random numbers from the point copy() was called.
    int next​(int bits)
    Gets an int with at most the specified amount of bits; don't confuse this with nextInt(int), which gets a number between 0 and its int argument, where this draws from a different (larger) range of random results.
    int nextInt()  
    int nextInt​(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()
    Using this method, any algorithm that needs to efficiently generate more than 32 bits of random data can interface with this randomness source.
    long nextLong​(long bound)
    Exclusive on bound (which must be positive), with an inner bound of 0.
    void setSeed​(long seed)
    Sets the seed using a long, by XORing the upper and lower halves of seed and passing that to setState(int).
    void setState​(int seed)  
    <T> T[] shuffle​(T[] elements)
    Shuffle an array using the Fisher-Yates algorithm and returns a shuffled copy, freshly-allocated, without modifying elements.
    <T> T[] shuffleInPlace​(T[] elements)
    Shuffles an array in-place using the Fisher-Yates algorithm.
    <T> T[] shuffleInPlace​(T[] elements, int length)
    Shuffles an array in-place using the Fisher-Yates algorithm, affecting indices from 0 (inclusive) to length (exclusive).
    protected static <T> void swap​(T[] arr, int pos1, int pos2)
    Mutates the array arr by switching the contents at pos1 and pos2.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

  • Constructor Details

  • Method Details

    • setState

      public void setState​(int seed)
    • nextLong

      public final long nextLong()
      Description copied from interface: RandomnessSource
      Using this method, any algorithm that needs to efficiently generate more than 32 bits of random data can interface with this randomness source. Get a random long between Long.MIN_VALUE and Long.MAX_VALUE (both inclusive).
      Specified by:
      nextLong in interface RandomnessSource
      Overrides:
      nextLong in class Random
      Returns:
      a random long between Long.MIN_VALUE and Long.MAX_VALUE (both inclusive)
    • next

      public final int next​(int bits)
      Gets an int with at most the specified amount of bits; don't confuse this with nextInt(int), which gets a number between 0 and its int argument, where this draws from a different (larger) range of random results. For example, next(2) can return any 2-bit int, which is limited to 0, 1, 2, or 3. Note that if you request 0 bits, this can give you any int (32 bits).
      Specified by:
      next in interface RandomnessSource
      Overrides:
      next in class Random
      Parameters:
      bits - the number of bits to get, from 1 to 32
      Returns:
      an int with at most the specified bits
    • nextInt

      public final int nextInt()
      Overrides:
      nextInt in class Random
    • nextInt

      public int nextInt​(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.
      Credit goes to Daniel Lemire, http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
      Overrides:
      nextInt in class Random
      Parameters:
      bound - the outer bound (exclusive), can be negative or positive
      Returns:
      the found number
    • nextLong

      public long nextLong​(long bound)
      Exclusive on bound (which must be positive), with an inner bound of 0. If bound is negative or 0 this always returns 0.
      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 two random ints, so by default it advances the state as much as nextLong().
      Parameters:
      bound - the outer exclusive bound; should be positive, otherwise this always returns 0L
      Returns:
      a random long between 0 (inclusive) and bound (exclusive)
    • setSeed

      public void setSeed​(long seed)
      Sets the seed using a long, by XORing the upper and lower halves of seed and passing that to setState(int).
      Overrides:
      setSeed in class Random
      Parameters:
      seed - the initial seed
    • swap

      protected static <T> void swap​(T[] arr, int pos1, int pos2)
      Mutates the array arr by switching the contents at pos1 and pos2.
      Parameters:
      arr - an array of T; must not be null
      pos1 - an index into arr; must be at least 0 and no greater than arr.length
      pos2 - an index into arr; must be at least 0 and no greater than arr.length
    • shuffle

      public <T> T[] shuffle​(T[] elements)
      Shuffle an array using the Fisher-Yates algorithm and returns a shuffled copy, freshly-allocated, without modifying elements.
      Wikipedia has more on this algorithm.
      Parameters:
      elements - an array of T; will not be modified
      Returns:
      a shuffled copy of elements
    • shuffleInPlace

      public <T> T[] shuffleInPlace​(T[] elements, int length)
      Shuffles an array in-place using the Fisher-Yates algorithm, affecting indices from 0 (inclusive) to length (exclusive). May be useful with libGDX Array instances, which can be shuffled with random.shuffleInPlace(arr.items, arr.size). If you don't want the array modified, use shuffle(Object[]).
      Wikipedia has more on this algorithm.
      Parameters:
      elements - an array of T; will be modified
      Returns:
      elements after shuffling it in-place
    • 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[]).
      Wikipedia has more on this algorithm.
      Parameters:
      elements - an array of T; will be modified
      Returns:
      elements after shuffling it in-place
    • copy

      public BasicRandom32 copy()
      Description copied from interface: RandomnessSource
      Produces a copy of this RandomnessSource that, if next() and/or nextLong() are called on this object and the copy, both will generate the same sequence of random numbers from the point copy() was called. This just needs to copy the state so it isn't shared, usually, and produce a new value with the same exact state.
      Specified by:
      copy in interface RandomnessSource
      Returns:
      a copy of this RandomnessSource