Class RNG
- All Implemented Interfaces:
Serializable
,IRNG
,RandomnessSource
- Direct Known Subclasses:
CriticalRNG
,DharmaRNG
,StatefulRNG
public class RNG extends Object implements Serializable, IRNG
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; usesDiverRNG
, 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; usesDiverRNG
, 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 usingCrossHash.hash64(CharSequence)
) as a seed forDiverRNG
, 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.see the version in GreasedRegion,GreasedRegion.approximateBits(RandomnessSource, int)
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 containingwidth * 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 containingMath.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 ofwidth * height
ordest.length
items.int
hashCode()
double
maxDoubleOf(double bound, int trials)
Gets the maximum random double between 0 andbound
generated out oftrials
generated numbers.float
maxFloatOf(float bound, int trials)
Gets the maximum random float between 0 andbound
generated out oftrials
generated numbers.int
maxIntOf(int bound, int trials)
Gets the maximum random int between 0 andbound
generated out oftrials
generated numbers.long
maxLongOf(long bound, int trials)
Gets the maximum random long between 0 andbound
generated out oftrials
generated numbers.double
minDoubleOf(double bound, int trials)
Gets the minimum random double between 0 andbound
generated out oftrials
generated numbers.float
minFloatOf(float bound, int trials)
Gets the minimum random float between 0 andbound
generated out oftrials
generated numbers.int
minIntOf(int bound, int trials)
Gets the minimum random int between 0 andbound
generated out oftrials
generated numbers.long
minLongOf(long bound, int trials)
Gets the minimum random long between 0 andbound
generated out oftrials
generated numbers.int
next(int bits)
Get up to 32 bits (inclusive) of random output; the int this produces will not require more thanbits
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.SeeGreasedRegion.randomInterleave(RandomnessSource)
for where this will be movedint[]
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 aList
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 aCollection
of T using the Fisher-Yates algorithm and returns an ArrayList of T.<T> ArrayList<T>
shuffle(Collection<T> elements, ArrayList<T> buf)
Shuffles aCollection
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 onlyIRNG
's methods can be called.String
toString()
-
Field Details
-
Constructor Details
-
RNG
public RNG()Default constructor; usesDiverRNG
, 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, includingLightRNG
,ThrustAltRNG
,LinnormRNG
, andMersenneTwister
. You can still use one of these by instantiating one of those classes and passing it toRNG(RandomnessSource)
, which may be the best way to ensure the same results across versions. -
RNG
Default constructor; usesDiverRNG
, 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
String-seeded constructor; uses a platform-independent hash of the String (it does not use String.hashCode, instead usingCrossHash.hash64(CharSequence)
) as a seed forDiverRNG
, 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
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 usingRNG()
as the constructor.- Parameters:
random
- the source of pseudo-randomness, such as a LightRNG or LongPeriodRNG object
-
-
Method Details
-
asRandom
- Returns:
- a Random instance that can be used for legacy compatibility
-
between
Returns a value from an even distribution from min (inclusive) to max (exclusive). -
between
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.
Ifmin
andmax
happen to be the same,min
is returned (breaking the exclusive behavior, but it's convenient to do so). -
between
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.
-
betweenWeighted
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
Returns a random element from the provided array and maintains object type.- Specified by:
getRandomElement
in interfaceIRNG
- Type Parameters:
T
- the type of the returned object- Parameters:
array
- the array to get an element from- Returns:
- the randomly selected element
-
getRandomElement
Returns a random element from the provided list. If the list is empty then null is returned.- Specified by:
getRandomElement
in interfaceIRNG
- Type Parameters:
T
- the type of the returned object- Parameters:
list
- the list to get an element from- Returns:
- the randomly selected element
-
getRandomElement
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 interfaceIRNG
- 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
Given aList
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
- AList
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
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 modifylist
while you use the returned reference. And there'll be no ConcurrentModificationException to detect such erroneous uses.- Parameters:
list
- A list with a constant-timeList.get(int)
method (otherwise performance degrades).- Returns:
- An
Iterable
that iterates overlist
but start at a random index. If the chosen index isi
, the iterator will return:list[i]; list[i+1]; ...; list[list.length() - 1]; list[0]; list[i-1]
-
shuffle
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. -
shuffleInPlace
Shuffles an array in-place using the Fisher-Yates algorithm. If you don't want the array modified, useshuffle(Object[], Object[])
.
Wikipedia has more on this algorithm.- Specified by:
shuffleInPlace
in interfaceIRNG
- 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
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 interfaceIRNG
- Type Parameters:
T
- can be any non-primitive type.- Parameters:
elements
- an array of T; will not be modifieddest
- Where to put the shuffle. If it does not have the same length aselements
, this will use the randomPortion method of this class to fill the smaller dest.- Returns:
dest
after modifications
-
shuffle
Shuffles aCollection
of T using the Fisher-Yates algorithm and returns an ArrayList of T.
Wikipedia has more on this algorithm. -
shuffle
Shuffles aCollection
of T using the Fisher-Yates algorithm. The result is allocated ifbuf
is null or ifbuf
isn't empty, otherwiseelements
is poured intobuf
.
Wikipedia has more on this algorithm.- Specified by:
shuffle
in interfaceIRNG
- Type Parameters:
T
- can be any non-primitive type.- Parameters:
elements
- a Collection of T; will not be modifiedbuf
- 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
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, useshuffle(Collection)
, which returns a List as well.
Wikipedia has more on this algorithm.- Specified by:
shuffleInPlace
in interfaceIRNG
- 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
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 interfaceIRNG
- Parameters:
length
- the size of the ordering to produce- Returns:
- a random ordering containing all ints from 0 to length (exclusive)
-
randomOrdering
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 interfaceIRNG
- Parameters:
length
- the size of the ordering to producedest
- the destination array; will be modified- Returns:
- dest, filled with a random ordering containing all ints from 0 to length (exclusive)
-
randomPortion
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
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
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 toRandom.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
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 interfaceIRNG
- Returns:
- a double between 0.0 (inclusive) and 0.9999999999999999 (inclusive)
-
nextDouble
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 interfaceIRNG
- 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
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 . -
nextFloat
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. -
nextBoolean
Get a random bit of state, interpreted as true or false with approximately equal likelihood. This may have better behavior thanrng.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 withrng.next(1)
and very good output withrng.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 interfaceIRNG
- Returns:
- a random boolean.
-
nextLong
Get a random long between Long.MIN_VALUE to Long.MAX_VALUE (both inclusive).- Specified by:
nextLong
in interfaceIRNG
- Specified by:
nextLong
in interfaceRandomnessSource
- Returns:
- a 64-bit random long.
-
nextLong
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 usenextSignedLong(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 asnextLong()
. -
nextSignedLong
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 tonextLong()
, 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 asnextLong()
.- Specified by:
nextSignedLong
in interfaceIRNG
- Parameters:
bound
- the outer exclusive bound; can be positive or negative- Returns:
- a random long between 0 (inclusive) and bound (exclusive)
-
nextSignedInt
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 earliernextIntHasty(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 withnextSignedLong(long)
. This is implemented slightly differently inAbstractRNG
, 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 interfaceIRNG
- Parameters:
bound
- the outer bound (exclusive), can be negative or positive- Returns:
- the found number
-
nextInt
Returns a random non-negative integer below the given bound, or 0 if the bound is 0 or negative. Always makes one call to theRandomnessSource.next(int)
method of the RandomnessSource that would be returned bygetRandomness()
, 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 aSkippingRandomness
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 asLathe32RNG
, and to avoid branching/irregular state advancement/modulus operations. It is now almost identical tonextIntHasty(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). ConsidernextSignedInt(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/ -
nextIntHasty
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" thannextInt(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
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 ofRandom.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
Get a random integer between Integer.MIN_VALUE to Integer.MAX_VALUE (both inclusive). -
next
Get up to 32 bits (inclusive) of random output; the int this produces will not require more thanbits
bits to represent.- Specified by:
next
in interfaceIRNG
- Specified by:
next
in interfaceRandomnessSource
- Parameters:
bits
- an int between 1 and 32, both inclusive- Returns:
- a random number that fits in the specified number of bits
-
getRandomness
-
setRandomness
-
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 interfaceIRNG
- Specified by:
copy
in interfaceRandomnessSource
- Returns:
- a copy of this RNG
-
approximateBits
Deprecated.see the version in GreasedRegion,GreasedRegion.approximateBits(RandomnessSource, int)
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.SeeGreasedRegion.randomInterleave(RandomnessSource)
for where this will be movedGets 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
Gets the minimum random long between 0 andbound
generated out oftrials
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 positivetrials
- 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
Gets the maximum random long between 0 andbound
generated out oftrials
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 positivetrials
- 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
Gets the minimum random int between 0 andbound
generated out oftrials
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 positivetrials
- 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
Gets the maximum random int between 0 andbound
generated out oftrials
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 positivetrials
- 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
Gets the minimum random double between 0 andbound
generated out oftrials
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 boundtrials
- 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
Gets the maximum random double between 0 andbound
generated out oftrials
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 boundtrials
- 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
Gets the minimum random float between 0 andbound
generated out oftrials
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 boundtrials
- 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
Gets the maximum random float between 0 andbound
generated out oftrials
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 boundtrials
- 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
-
equals
-
hashCode
-
randomPortion
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 tonextInt()
, regardless of the data being randomized.
Uses approximately the same code asLowStorageShuffler
, but without any object or array allocations.- Specified by:
randomPortion
in interfaceIRNG
- 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
Gets a random double between 0.0 inclusive and 1.0 inclusive.- Returns:
- a double between 0.0 (inclusive) and 1.0 (inclusive)
-
nextDoubleInclusive
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
Gets a random float between 0.0f inclusive and 1.0f inclusive.- Returns:
- a float between 0f (inclusive) and 1f (inclusive)
-
nextFloatInclusive
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
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 coordinatesheight
- the upper bound (exclusive) for y coordinates- Returns:
- a random Coord between (0,0) inclusive and (width,height) exclusive
-
getRandomCellsIterable
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
Gets an array of unique Coords, from (startX,startY) inclusive to (startX+width,startY+height) exclusive, in a random order, with the array containingwidth * height
items.- Parameters:
startX
- the inclusive starting x positionstartY
- the inclusive starting y positionwidth
- the width of the space to place Coords in, extending from startXheight
- 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
Gets an array of unique Coords, from (startX,startY) inclusive to (startX+width,startY+height) exclusive, in a random order, with the array containingMath.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 positionstartY
- the inclusive starting y positionwidth
- the width of the space to place Coords in, extending from startXheight
- the height of the space to place Coords in, extending from startYsize
- the size of the array to return; only matters if it is smaller thanwidth * height
- Returns:
- an array containing
Math.min(width * height, size)
Coord items in random order, inside the given bounds
-
getRandomUniqueCells
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 ofwidth * height
ordest.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 positionstartY
- the inclusive starting y positionwidth
- the width of the space to place Coords in, extending from startXheight
- the height of the space to place Coords in, extending from startYdest
- 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 onlyIRNG
's methods can be called.- Specified by:
toSerializable
in interfaceIRNG
- Returns:
- a
Serializable
view of this RNG; alwaysthis
-