001package squidpony.squidmath; 002 003import java.io.Serializable; 004import java.util.ArrayList; 005import java.util.Collection; 006import java.util.List; 007 008/** 009 * Interface for full-featured random number generators to implement (it does more than, and includes all of, 010 * {@link RandomnessSource}). It's a stripped down version of the original {@link RNG}. It's an interface instead of a 011 * class, to be able to implement using random number generators that don't implement RandomnessSource, like libGDX's 012 * RandomXS128, or to hard-code the RandomnessSource to avoid overhead or use some methods differently (like preferring 013 * 32-bit math or optimizing for GWT, as {@link GWTRNG} does). You can use any IRNG as a RandomnessSource, but that only 014 * allows its {@link #next(int)}, {@link #nextLong()}, and {@link #copy()} methods to be called, so most usage that can 015 * benefit from methods like {@link #nextDouble()} or {@link #between(int, int)} should prefer IRNG for parameter types. 016 * 017 * @author Eben Howard - http://squidpony.com - howard@squidpony.com 018 * @author Tommy Ettinger 019 * @author smelC 020 */ 021public interface IRNG extends RandomnessSource { 022 023 /** 024 * Get up to 32 bits (inclusive) of random output; the int this produces 025 * will not require more than {@code bits} bits to represent. 026 * 027 * @param bits an int between 1 and 32, both inclusive 028 * @return a random number that fits in the specified number of bits 029 */ 030 int next(int bits); 031 032 /** 033 * Get a random integer between Integer.MIN_VALUE to Integer.MAX_VALUE (both inclusive). 034 * 035 * @return a 32-bit random int. 036 */ 037 int nextInt(); 038 039 /** 040 * Returns a random non-negative integer below the given bound, or 0 if the bound is 0 or 041 * negative. 042 * 043 * @param bound the upper bound (exclusive) 044 * @return the found number 045 */ 046 int nextInt(final int bound); 047 048 /** 049 * Get a random long between Long.MIN_VALUE to Long.MAX_VALUE (both inclusive). 050 * 051 * @return a 64-bit random long. 052 */ 053 long nextLong(); 054 055 /** 056 * Returns a random long below the given bound, or 0 if the bound is 0 or 057 * negative. 058 * 059 * @param bound the upper bound (exclusive) 060 * @return the found number 061 */ 062 long nextLong(final long bound); 063 064 /** 065 * Get a random bit of state, interpreted as true or false with approximately equal likelihood. 066 * @return a random boolean. 067 */ 068 boolean nextBoolean(); 069 070 /** 071 * Gets a random double between 0.0 inclusive and 1.0 exclusive. 072 * This returns a maximum of 0.9999999999999999 because that is the largest double value that is less than 1.0 . 073 * 074 * @return a double between 0.0 (inclusive) and 0.9999999999999999 (inclusive) 075 */ 076 double nextDouble(); 077 /** 078 * This returns a random double between 0.0 (inclusive) and outer (exclusive). The value for outer can be positive 079 * or negative. Because of how math on doubles works, there are at most 2 to the 53 values this can return for any 080 * given outer bound, and very large values for outer will not necessarily produce all numbers you might expect. 081 * 082 * @param outer the outer exclusive bound as a double; can be negative or positive 083 * @return a double between 0.0 (inclusive) and outer (exclusive) 084 */ 085 double nextDouble(final double outer); 086 087 /** 088 * Gets a random float between 0.0f inclusive and 1.0f exclusive. 089 * This returns a maximum of 0.99999994 because that is the largest float value that is less than 1.0f . 090 * 091 * @return a float between 0f (inclusive) and 0.99999994f (inclusive) 092 */ 093 float nextFloat(); 094 /** 095 * This returns a random float between 0.0f (inclusive) and outer (exclusive). The value for outer can be positive 096 * or negative. Because of how math on floats works, there are at most 2 to the 24 values this can return for any 097 * given outer bound, and very large values for outer will not necessarily produce all numbers you might expect. 098 * 099 * @param outer the outer exclusive bound as a float; can be negative or positive 100 * @return a float between 0f (inclusive) and outer (exclusive) 101 */ 102 float nextFloat(final float outer); 103 /** 104 * Exclusive on bound (which may be positive or negative), with an inner bound of 0. 105 * If bound is negative this returns a negative long; if bound is positive this returns a positive long. The bound 106 * can even be 0, which will cause this to return 0L every time. This uses a biased technique to get numbers from 107 * large ranges, but the amount of bias is incredibly small (expected to be under 1/1000 if enough random ranged 108 * numbers are requested, which is about the same as an unbiased method that was also considered). It may have 109 * noticeable bias if the generator's period is exhausted by only calls to this method. Unlike all unbiased methods, 110 * this advances the state by an equivalent to exactly one call to {@link #nextLong()}, where rejection sampling 111 * would sometimes advance by one call, but other times by arbitrarily many more. 112 * @param bound the outer exclusive bound; can be positive or negative 113 * @return a random long between 0 (inclusive) and bound (exclusive) 114 */ 115 long nextSignedLong(long bound); 116 117 /** 118 * Returns a random non-negative integer between 0 (inclusive) and the given bound (exclusive), 119 * or 0 if the bound is 0. The bound can be negative, which will produce 0 or a negative result. 120 * <br> 121 * Credit goes to Daniel Lemire, http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/ 122 * 123 * @param bound the outer bound (exclusive), can be negative or positive 124 * @return the found number 125 */ 126 int nextSignedInt(final int bound); 127 /** 128 * Returns a value between min (inclusive) and max (exclusive) as ints. 129 * <br> 130 * The inclusive and exclusive behavior is to match the behavior of the similar 131 * method that deals with floating point values. 132 * <br> 133 * If {@code min} and {@code max} happen to be the same, {@code min} is returned 134 * (breaking the exclusive behavior, but it's convenient to do so). 135 * 136 * @param min 137 * the minimum bound on the return value (inclusive) 138 * @param max 139 * the maximum bound on the return value (exclusive) 140 * @return the found value 141 */ 142 int between(int min, int max); 143 144 /** 145 * Returns a value between min (inclusive) and max (exclusive) as longs. 146 * <br> 147 * The inclusive and exclusive behavior is to match the behavior of the similar 148 * method that deals with floating point values. 149 * <br> 150 * If {@code min} and {@code max} happen to be the same, {@code min} is returned 151 * (breaking the exclusive behavior, but it's convenient to do so). 152 * 153 * @param min 154 * the minimum bound on the return value (inclusive) 155 * @param max 156 * the maximum bound on the return value (exclusive) 157 * @return the found value 158 */ 159 long between(long min, long max); 160 161 /** 162 * Returns a value from a uniform distribution from min (inclusive) to max 163 * (exclusive). 164 * 165 * @param min the minimum bound on the return value (inclusive) 166 * @param max the maximum bound on the return value (exclusive) 167 * @return the found value 168 */ 169 double between(double min, double max); 170 171 /** 172 * Returns a random element from the provided array and maintains object 173 * type. 174 * 175 * @param <T> the type of the returned object 176 * @param array the array to get an element from 177 * @return the randomly selected element 178 */ 179 <T> T getRandomElement(T[] array); 180 /** 181 * Returns a random element from the provided list. If the list is empty 182 * then null is returned. 183 * 184 * @param <T> the type of the returned object 185 * @param list the list to get an element from 186 * @return the randomly selected element 187 */ 188 <T> T getRandomElement(List<T> list); 189 190 /** 191 * Returns a random element from the provided Collection, which should have predictable iteration order if you want 192 * predictable behavior for identical RNG seeds, though it will get a random element just fine for any Collection 193 * (just not predictably in all cases). If you give this a Set, it should be a LinkedHashSet or some form of sorted 194 * Set like TreeSet if you want predictable results. Any List or Queue should be fine. Map does not implement 195 * Collection, thank you very much Java library designers, so you can't actually pass a Map to this, though you can 196 * pass the keys or values. If coll is empty, returns null. 197 * <br> 198 * Requires iterating through a random amount of coll's elements, so performance depends on the size of coll but is 199 * likely to be decent, as long as iteration isn't unusually slow. This replaces {@code getRandomElement(Queue)}, 200 * since Queue implements Collection and the older Queue-using implementation was probably less efficient. 201 * <br> 202 * You should generally prefer {@link #getRandomElement(List)} whenever possible, or in some cases you can use 203 * methods that get a random value on the Collection (or Map, in the case of OrderedMap) itself. 204 * @param <T> the type of the returned object 205 * @param coll the Collection to get an element from; remember, Map does not implement Collection 206 * @return the randomly selected element 207 */ 208 <T> T getRandomElement(Collection<T> coll); 209 /** 210 * Shuffle an array using the Fisher-Yates algorithm and returns a shuffled copy, freshly-allocated, without 211 * modifying elements. 212 * <br> 213 * <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Wikipedia has more on this algorithm</a>. 214 * 215 * @param elements an array of T; will not be modified 216 * @param <T> can be any non-primitive type. 217 * @return a shuffled copy of elements 218 */ 219 <T> T[] shuffle(final T[] elements); 220 /** 221 * Shuffles an array in-place using the Fisher-Yates algorithm. 222 * If you don't want the array modified, use {@link #shuffle(Object[], Object[])}. 223 * <br> 224 * <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Wikipedia has more on this algorithm</a>. 225 * 226 * @param elements an array of T; <b>will</b> be modified 227 * @param <T> can be any non-primitive type. 228 * @return elements after shuffling it in-place 229 */ 230 <T> T[] shuffleInPlace(T[] elements); 231 /** 232 * Shuffle an array using the Fisher-Yates algorithm. DO NOT give the same array for both elements and 233 * dest, since the prior contents of dest are rearranged before elements is used, and if they refer to the same 234 * array, then you can end up with bizarre bugs where one previously-unique item shows up dozens of times. If 235 * possible, create a new array with the same length as elements and pass it in as dest; the returned value can be 236 * assigned to whatever you want and will have the same items as the newly-formed array. 237 * <br> 238 * <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Wikipedia has more on this algorithm</a>. 239 * 240 * @param elements an array of T; will not be modified 241 * @param <T> can be any non-primitive type. 242 * @param dest Where to put the shuffle. If it does not have the same length as {@code elements}, this will use the 243 * randomPortion method of this class to fill the smaller dest. MUST NOT be the same array as elements! 244 * @return {@code dest} after modifications 245 */ 246 <T> T[] shuffle(T[] elements, T[] dest); 247 /** 248 * Shuffles a {@link Collection} of T using the Fisher-Yates algorithm and returns an ArrayList of T. 249 * <br> 250 * <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Wikipedia has more on this algorithm</a>. 251 * @param elements a Collection of T; will not be modified 252 * @param <T> can be any non-primitive type. 253 * @return a shuffled ArrayList containing the whole of elements in pseudo-random order. 254 */ 255 <T> ArrayList<T> shuffle(Collection<T> elements); 256 257 /** 258 * Shuffles a {@link Collection} of T using the Fisher-Yates algorithm and puts it in a buffer. 259 * The result is allocated if {@code buf} is null or if {@code buf} isn't empty, 260 * otherwise {@code elements} is poured into {@code buf}. 261 * <br> 262 * <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Wikipedia has more on this algorithm</a>. 263 * @param elements a Collection of T; will not be modified 264 * @param buf a buffer as an ArrayList that will be filled with the shuffled contents of elements; 265 * if null or non-empty, a new ArrayList will be allocated and returned 266 * @param <T> can be any non-primitive type. 267 * @return a shuffled ArrayList containing the whole of elements in pseudo-random order, which may be {@code buf} 268 */ 269 <T> ArrayList<T> shuffle(Collection<T> elements, /*@Nullable*/ ArrayList<T> buf); 270 /** 271 * Shuffles a Collection of T items in-place using the Fisher-Yates algorithm. 272 * This only shuffles List data structures. 273 * If you don't want the array modified, use {@link #shuffle(Collection)}, which returns a List as well. 274 * <br> 275 * <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Wikipedia has more on this algorithm</a>. 276 * 277 * @param elements a Collection of T; <b>will</b> be modified 278 * @param <T> can be any non-primitive type. 279 * @return elements after shuffling it in-place 280 */ 281 <T> List<T> shuffleInPlace(List<T> elements); 282 /** 283 * Generates a random permutation of the range from 0 (inclusive) to length (exclusive). 284 * Useful for passing to OrderedMap or OrderedSet's reorder() methods. 285 * 286 * @param length the size of the ordering to produce 287 * @return a random ordering containing all ints from 0 to length (exclusive) 288 */ 289 int[] randomOrdering(int length); 290 291 /** 292 * Generates a random permutation of the range from 0 (inclusive) to length (exclusive) and stores it in 293 * the dest parameter, avoiding allocations. 294 * Useful for passing to OrderedMap or OrderedSet's reorder() methods. 295 * 296 * @param length the size of the ordering to produce 297 * @param dest the destination array; will be modified 298 * @return dest, filled with a random ordering containing all ints from 0 to length (exclusive) 299 */ 300 int[] randomOrdering(int length, int[] dest); 301 /** 302 * Gets a random portion of data (an array), assigns that portion to output (an array) so that it fills as much as 303 * it can, and then returns output. Will only use a given position in the given data at most once. 304 * 305 * @param data an array of T; will not be modified. 306 * @param output an array of T that will be overwritten; should always be instantiated with the portion length 307 * @param <T> can be any non-primitive type. 308 * @return output, after {@code Math.min(output.length, data.length)} unique items have been put into it from data 309 */ 310 <T> T[] randomPortion(T[] data, T[] output); 311 /** 312 * Creates a copy of this IRNG; it will generate the same random numbers, given the same calls in order, as this 313 * IRNG at the point copy() is called. The copy will not share references with this IRNG. If this IRNG does not 314 * permit copying itself, it is suggested to either throw an {@link UnsupportedOperationException} or return a new 315 * IRNG of the same type but with a random seed, with the latter meant as a partial defense against cheating. 316 * 317 * @return a copy of this IRNG 318 */ 319 IRNG copy(); 320 321 /** 322 * Gets a view of this IRNG in a way that implements {@link Serializable}, which may simply be this IRNG if it 323 * implements Serializable as well as IRNG. 324 * <br> 325 * For implementors: It is suggested to return an {@link RNG} initialized by calling 326 * {@link RNG#RNG(long)} with {@link #nextLong()} if you are unable to save the current state of this IRNG and the 327 * caller still needs something saved. This won't preserve the current state or the choice of IRNG implementation, 328 * however, so it is simply a last resort in case you don't want to throw an exception. 329 * @return a {@link Serializable} view of this IRNG or a similar one; may be {@code this} 330 */ 331 Serializable toSerializable(); 332}