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}