Package squidpony.squidmath
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
This Dr. Dobb's article has more on this type of generator.
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 withnextInt(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 ofseed
and passing that tosetState(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.
-
Field Details
-
Constructor Details
-
BasicRandom32
public BasicRandom32() -
BasicRandom32
-
-
Method Details
-
setState
-
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 interfaceRandomnessSource
- Overrides:
nextLong
in classRandom
- Returns:
- a random long between Long.MIN_VALUE and Long.MAX_VALUE (both inclusive)
-
next
Gets an int with at most the specified amount of bits; don't confuse this withnextInt(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 interfaceRandomnessSource
- Overrides:
next
in classRandom
- Parameters:
bits
- the number of bits to get, from 1 to 32- Returns:
- an int with at most the specified bits
-
nextInt
-
nextInt
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/ -
nextLong
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 asnextLong()
.- 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
Sets the seed using a long, by XORing the upper and lower halves ofseed
and passing that tosetState(int)
. -
swap
Mutates the array arr by switching the contents at pos1 and pos2.- Parameters:
arr
- an array of T; must not be nullpos1
- an index into arr; must be at least 0 and no greater than arr.lengthpos2
- an index into arr; must be at least 0 and no greater than arr.length
-
shuffle
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
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 withrandom.shuffleInPlace(arr.items, arr.size)
. If you don't want the array modified, useshuffle(Object[])
.
Wikipedia has more on this algorithm.- Parameters:
elements
- an array of T; will be modified- Returns:
- elements after shuffling it in-place
-
shuffleInPlace
Shuffles an array in-place using the Fisher-Yates algorithm. If you don't want the array modified, useshuffle(Object[])
.
Wikipedia has more on this algorithm.- Parameters:
elements
- an array of T; will be modified- Returns:
- elements after shuffling it in-place
-
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 interfaceRandomnessSource
- Returns:
- a copy of this RandomnessSource
-