package squidpony.squidmath;
import java.io.Serializable;
import java.util.Random;
/**
* This makes java.util.Random available for testing purposes.
* It is relevant mainly as example code, or if you want to
* compare what your results would have been without using a
* better RNG. Results might not be apparent in some cases,
* although the terrible performance of java.util.Random is
* likely to be the first thing a user notices if this is
* used heavily (i.e. to generate white noise with one call
* to {@link #nextDouble()} per cell).
* @author Ben McLean
*/
public class JavaRNG implements RandomnessSource, Serializable
{
public Random random;
/** Creates a new generator seeded using Math.random. */
public JavaRNG() { this((long) Math.floor(Math.random() * Long.MAX_VALUE)); }
public JavaRNG( final long seed ) { this.random = new Random(seed); }
public JavaRNG( final Random random ) { this.random = random; }
@Override
public int next( int bits ) {
return random.nextInt() >>> (32 - bits);
// return random.next(bits);
}
@Override
public long nextLong() { return random.nextLong(); }
@Override
public RandomnessSource copy() { return new JavaRNG(random); }
public int nextInt() { return random.nextInt(); }
public int nextInt( final int bound ) { return random.nextInt(bound); }
/**
* Inclusive lower, exclusive upper.
* @param lower the lower bound, inclusive, can be positive or negative
* @param upper the upper bound, exclusive, should be positive, must be greater than lower
* @return a random int at least equal to lower and less than upper
*/
public int nextInt( final int lower, final int upper ) {
if ( upper - lower <= 0 ) throw new IllegalArgumentException("Upper bound must be greater than lower bound");
return lower + nextInt(upper - lower);
}
public double nextDouble() { return random.nextDouble(); }
public double nextDouble(final double outer) {
return nextDouble() * outer;
}
/**
* Gets a uniform random float in the range [0.0,1.0)
* @return a random float at least equal to 0.0 and less than 1.0
*/
public float nextFloat() { return random.nextFloat(); }
/**
* Gets a random value, true or false.
* @return a random true or false value.
*/
public boolean nextBoolean() { return ( random.nextBoolean()); }
/**
* Given a byte array as a parameter, this will fill the array with random bytes (modifying it
* in-place).
*/
public void nextBytes( final byte[] bytes ) { random.nextBytes(bytes); }
@Override
public String toString() {
return "JavaRNG wrapping java.util.Random with id " + System.identityHashCode(random);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
JavaRNG javaRNG = (JavaRNG) o;
return random.equals(javaRNG.random);
}
@Override
public int hashCode() {
return random.hashCode() * 31;
}
}