001package squidpony.squidmath; 002 003import java.io.Serializable; 004import java.util.Random; 005 006/** 007 * This makes java.util.Random available for testing purposes. 008 * It is relevant mainly as example code, or if you want to 009 * compare what your results would have been without using a 010 * better RNG. Results might not be apparent in some cases, 011 * although the terrible performance of java.util.Random is 012 * likely to be the first thing a user notices if this is 013 * used heavily (i.e. to generate white noise with one call 014 * to {@link #nextDouble()} per cell). 015 * @author Ben McLean 016 */ 017public class JavaRNG implements RandomnessSource, Serializable 018{ 019 public Random random; 020 021 /** Creates a new generator seeded using Math.random. */ 022 public JavaRNG() { this((long) Math.floor(Math.random() * Long.MAX_VALUE)); } 023 024 public JavaRNG( final long seed ) { this.random = new Random(seed); } 025 026 public JavaRNG( final Random random ) { this.random = random; } 027 028 @Override 029 public int next( int bits ) { 030 return random.nextInt() >>> (32 - bits); 031 // return random.next(bits); 032 } 033 034 @Override 035 public long nextLong() { return random.nextLong(); } 036 037 @Override 038 public JavaRNG copy() { return new JavaRNG(random); } 039 040 public int nextInt() { return random.nextInt(); } 041 042 public int nextInt( final int bound ) { return random.nextInt(bound); } 043 /** 044 * Inclusive lower, exclusive upper. 045 * @param lower the lower bound, inclusive, can be positive or negative 046 * @param upper the upper bound, exclusive, should be positive, must be greater than lower 047 * @return a random int at least equal to lower and less than upper 048 */ 049 public int nextInt( final int lower, final int upper ) { 050 if ( upper - lower <= 0 ) throw new IllegalArgumentException("Upper bound must be greater than lower bound"); 051 return lower + nextInt(upper - lower); 052 } 053 054 public double nextDouble() { return random.nextDouble(); } 055 public double nextDouble(final double outer) { 056 return nextDouble() * outer; 057 } 058 059 /** 060 * Gets a uniform random float in the range [0.0,1.0) 061 * @return a random float at least equal to 0.0 and less than 1.0 062 */ 063 public float nextFloat() { return random.nextFloat(); } 064 /** 065 * Gets a random value, true or false. 066 * @return a random true or false value. 067 */ 068 public boolean nextBoolean() { return ( random.nextBoolean()); } 069 070 /** 071 * Given a byte array as a parameter, this will fill the array with random bytes (modifying it 072 * in-place). 073 */ 074 public void nextBytes( final byte[] bytes ) { random.nextBytes(bytes); } 075 076 @Override 077 public String toString() { 078 return "JavaRNG wrapping java.util.Random with id " + System.identityHashCode(random); 079 } 080 081 @Override 082 public boolean equals(Object o) { 083 if (this == o) return true; 084 if (o == null || getClass() != o.getClass()) return false; 085 086 JavaRNG javaRNG = (JavaRNG) o; 087 088 return random.equals(javaRNG.random); 089 } 090 091 @Override 092 public int hashCode() { 093 return random.hashCode() * 31; 094 } 095}