Parcourir la source

Delete stuff I don't use in squidmath package

smelc il y a 6 ans
Parent
commit
2978990fc6

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 2791
squidlib-util/src/main/java/squidpony/squidmath/Arrangement.java


+ 0 - 93
squidlib-util/src/main/java/squidpony/squidmath/ChaosRNG.java

@@ -1,93 +0,0 @@
-package squidpony.squidmath;
-
-import squidpony.annotation.GwtIncompatible;
-
-import java.security.SecureRandom;
-
-/**
- * An RNG that cannot be seeded and should be fairly hard to predict what it will return next. Useful for competitions
- * where a seeded RNG is used for dungeon generation and enemy placement but an unpredictable RNG is needed for combat,
- * so players can't abuse the RNG to make improbable events guaranteed or unfavorable outcomes impossible. The
- * performance of this as a RandomnessSource is also fairly good, taking approximately 1.5x to 1.7x as long as LightRNG
- * to produce random 64-bit data, and of course it is far faster than java.util.Random (which is 10x slower than this).
- * In the secure random numbers category, where this isn't quite as secure as most, ChaosRNG is about 80x faster than
- * SecureRandom once SecureRandom warms up, which takes about 10 minutes of continuous number generation. Before that,
- * ChaosRNG is about 110x faster than SecureRandom for 64-bit data.
- * <br>
- * This is intended to be used as a RandomnessSource for an RNG, and does not have any methods other than those needed
- * for that interface, with one exception -- the randomize() method, which can be used to completely change all 1024
- * bits of state using cryptographic random numbers. If you create a ChaosRNG and keep it around for later, then you can
- * pass it to the RNG constructor and later call randomize() on the ChaosRNG if you suspect it may be becoming
- * predictable. The period on this RNG is (2 to the 1024) - 1, so predicting it may be essentially impossible unless the
- * user can poke around in the application, use reflection, etc.
- * Created by Tommy Ettinger on 3/17/2016.
- */
-@GwtIncompatible
-public class ChaosRNG implements RandomnessSource{
-
-    private transient long[] state = new long[16];
-    private transient int choice;
-    private transient SecureRandom sec;
-    private static final long serialVersionUID = -254415589291474491L;
-
-    /**
-     * Builds a ChaosRNG with a cryptographically-random seed. Future random generation uses less secure methods but
-     * should still make it extremely difficult to "divine" the future RNG results.
-     */
-    public ChaosRNG()
-    {
-        sec = new SecureRandom();
-        byte[] bytes = new byte[128];
-        sec.nextBytes(bytes);
-        for (int i = sec.nextInt() & 127, c = 0; c < 128; c++, i = i + 1 & 127) {
-            state[i & 15] |= bytes[c] << ((i >> 4) << 3);
-        }
-        choice = sec.nextInt(16);
-    }
-
-    @Override
-    public int next( int bits ) {
-        return (int)( nextLong() & ( 1L << bits ) - 1 );
-    }
-
-    /**
-     * Can return any long, positive or negative, of any size permissible in a 64-bit signed integer.
-     * @return any long, all 64 bits are random
-     */
-    @Override
-    public long nextLong() {
-        final long s0 = state[choice];
-        long s1 = state[choice = (choice + 1) & 15];
-        s1 ^= s1 << 31; // a
-        state[choice] = s1 ^ s0 ^ (s1 >>> 11) ^ (s0 >>> 30); // b,c
-        return state[choice] * 1181783497276652981L;
-    }
-
-    /**
-     * Produces another ChaosRNG with no relation to this one; this breaks the normal rules that RandomnessSource.copy
-     * abides by because this class should never have its generated number sequence be predictable.
-     * @return a new, unrelated ChaosRNG as a RandomnessSource
-     */
-    @Override
-    public RandomnessSource copy() {
-        return new ChaosRNG();
-    }
-
-    /**
-     * Changes the internal state to a new, fully-random version that should have no relation to the previous state.
-     * May be somewhat slow; you shouldn't need to call this often.
-     */
-    public void randomize()
-    {
-        byte[] bytes = sec.generateSeed(128);
-        for (int i = sec.nextInt() & 127, c = 0; c < 128; c++, i = i + 1 & 127) {
-            state[i & 15] |= bytes[c] << ((i >> 4) << 3);
-        }
-        choice = sec.nextInt(16);
-    }
-
-    @Override
-    public String toString() {
-        return "ChaosRNG with state determined by the power of friendship";
-    }
-}

+ 0 - 582
squidlib-util/src/main/java/squidpony/squidmath/DeckRNG.java

@@ -1,582 +0,0 @@
-package squidpony.squidmath;
-
-import squidpony.StringKit;
-import squidpony.annotation.GwtIncompatible;
-
-import java.io.Serializable;
-import java.util.*;
-
-/**
- * An RNG variant that has 16 possible grades of value it can produce and shuffles them like a deck of cards.
- * It repeats grades of value, but not exact values, every 16 numbers requested from it. Grades go in increments of
- * 0.0625 from 0.0 to 0.9375, and are added to a random double less than 0.0625 to get the random number for that
- * grade.
- * <p>
- * You can get values from this generator with: {@link #nextDouble()}, {@link #nextInt()},
- *   {@link #nextLong()}, and the bounded variants on each of those.
- *
- * Created by Tommy Ettinger on 5/2/2015.
- */
-public class DeckRNG extends StatefulRNG implements Serializable {
-	private static final long serialVersionUID = 7828346657944720807L;
-    private int step;
-    private long lastShuffledState;
-    private double[] baseDeck = new double[]{0.0, 0.0625, 0.125, 0.1875, 0.25, 0.3125, 0.375, 0.4375,
-                                             0.5, 0.5625, 0.625, 0.6875, 0.75, 0.8125, 0.875, 0.9375},
-            deck = new double[16];
-
-    /**
-     * Constructs a DeckRNG with a pseudo-random seed from Math.random().
-     */
-    public DeckRNG()
-    {
-        this((long)(Math.random() * ((1L << 50) - 1)));
-    }
-    /**
-     * Construct a new DeckRNG with the given seed.
-     *
-     * @param seed used to seed the default RandomnessSource.
-     */
-    public DeckRNG(final long seed) {
-        lastShuffledState = seed;
-        random = new LightRNG(seed);
-        step = 0;
-    }
-
-    /**
-     * String-seeded constructor uses the hash of the String as a seed for LightRNG, which is of high quality, but low
-     * period (which rarely matters for games), and has good speed and tiny state size.
-     *
-     * @param seedString a String to use as a seed; will be hashed in a uniform way across platforms.
-     */
-    public DeckRNG(String seedString) {
-        this(CrossHash.hash(seedString));
-    }
-    /**
-     * Seeds this DeckRNG using the RandomnessSource it is given. Does not assign the RandomnessSource to any fields
-     * that would affect future pseudo-random number generation.
-     * @param random will be used to generate a new seed, but will not be assigned as this object's RandomnessSource
-     */
-    public DeckRNG(RandomnessSource random) {
-        this(random.nextLong());
-
-    }
-
-    /**
-     * Generate a random double, altering the result if recently generated results have been leaning
-     * away from this class' fairness value.
-     * @return a double between 0.0 (inclusive) and 1.0 (exclusive)
-     */
-    @Override
-    public double nextDouble() {
-        if(step == 0)
-            shuffleInPlace(deck);
-        double gen = deck[step++];
-        step %= 16;
-        return gen;
-    }
-
-    /**
-     * This returns a random double between 0.0 (inclusive) and max (exclusive).
-     *
-     * @return a value between 0 (inclusive) and max (exclusive)
-     */
-    @Override
-    public double nextDouble(double max) {
-        return nextDouble() * max;
-    }
-
-    /**
-     * Returns a value from a even distribution from min (inclusive) to max
-     * (exclusive).
-     *
-     * @param min the minimum bound on the return value (inclusive)
-     * @param max the maximum bound on the return value (exclusive)
-     * @return the found value
-     */
-    @Override
-    public double between(double min, double max) {
-        return min + (max - min) * nextDouble();
-    }
-
-    /**
-     * 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.
-     *
-     * @param min the minimum bound on the return value (inclusive)
-     * @param max the maximum bound on the return value (exclusive)
-     * @return the found value
-     */
-    @Override
-    public int between(int min, int max) {
-        return nextInt(max - min) + min;
-    }
-
-    /**
-     * 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.
-     *
-     * @param min the minimum bound on the return value (inclusive)
-     * @param max the maximum bound on the return value (exclusive)
-     * @param samples the number of samples to take
-     * @return the found value
-     */
-    @Override
-    public int betweenWeighted(int min, int max, int samples) {
-        int sum = 0;
-        for (int i = 0; i < samples; i++) {
-            sum += between(min, max);
-        }
-
-        return Math.round((float) sum / samples);
-    }
-
-    /**
-     * Returns a random element from the provided array and maintains object
-     * type.
-     *
-     * @param <T> the type of the returned object
-     * @param array the array to get an element from
-     * @return the randomly selected element
-     */
-    @Override
-    public <T> T getRandomElement(T[] array) {
-        if (array.length < 1) {
-            return null;
-        }
-        return array[nextInt(array.length)];
-    }
-
-    /**
-     * Returns a random element from the provided list. If the list is empty
-     * then null is returned.
-     *
-     * @param <T> the type of the returned object
-     * @param list the list to get an element from
-     * @return the randomly selected element
-     */
-    @Override
-    public <T> T getRandomElement(List<T> list) {
-        if (list.size() <= 0) {
-            return null;
-        }
-        return list.get(nextInt(list.size()));
-    }
-
-    /**
-     * Returns a random element from the provided ShortSet. If the set is empty
-     * then an exception is thrown.
-     *
-     * <p>
-     * Requires iterating through a random amount of the elements in set, so performance depends on the size of set but
-     * is likely to be decent. This is mostly meant for internal use, the same as ShortSet.
-     * </p>
-     * @param set the ShortSet to get an element from
-     * @return the randomly selected element
-     */
-    public short getRandomElement(ShortSet set) {
-        if (set.size <= 0) {
-            throw new UnsupportedOperationException("ShortSet cannot be empty when getting a random element");
-        }
-        int n = nextInt(set.size);
-        short s = 0;
-        ShortSet.ShortSetIterator ssi = set.iterator();
-        while (n-- >= 0 && ssi.hasNext)
-            s = ssi.next();
-        ssi.reset();
-        return s;
-    }
-
-    /**
-     * 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.
-     *
-     * <p>
-     * 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 {@code getRandomElement(Queue)},
-     * since Queue implements Collection and the older Queue-using implementation was probably less efficient.
-     * </p>
-     * @param <T> the type of the returned object
-     * @param coll the Collection to get an element from; remember, Map does not implement Collection
-     * @return the randomly selected element
-     */
-    public <T> T getRandomElement(Collection<T> coll) {
-        if (coll.size() <= 0) {
-            return null;
-        }
-        int n = nextInt(coll.size());
-        T t = null;
-        Iterator<T> it = coll.iterator();
-        while (n-- >= 0 && it.hasNext())
-            t = it.next();
-        return t;
-    }
-
-
-    /**
-     * @return a value from the gaussian distribution
-     */
-    @Override
-    public synchronized double nextGaussian() {
-        if (haveNextNextGaussian) {
-            haveNextNextGaussian = false;
-            return nextNextGaussian;
-        } else {
-            double v1, v2, s;
-            do {
-                v1 = 2 * nextDouble() - 1; // between -1 and 1
-                v2 = 2 * nextDouble() - 1; // between -1 and 1
-                s = v1 * v1 + v2 * v2;
-            } while (s >= 1 || s == 0);
-            double multiplier = Math.sqrt(-2 * Math.log(s) / s);
-            nextNextGaussian = v2 * multiplier;
-            haveNextNextGaussian = true;
-            return v1 * multiplier;
-        }
-    }
-    /**
-     * Returns a random integer below the given bound, or 0 if the bound is 0 or
-     * negative. Affects the current fortune.
-     *
-     * @param bound the upper bound (exclusive)
-     * @return the found number
-     */
-    @Override
-    public int nextInt(int bound) {
-        if (bound <= 0) {
-            return 0;
-        }
-
-        return (int)(nextDouble() * bound);
-    }
-
-    /**
-     * Shuffle an array using the Fisher-Yates algorithm. Not GWT-compatible; use the overload that takes two arrays.
-     * <br>
-     * https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
-     *
-     * @param elements an array of T; will not be modified
-     * @return a shuffled copy of elements
-     */
-    @Override
-    @GwtIncompatible
-    public <T> T[] shuffle(T[] elements)
-    {
-        int n = elements.length;
-        T[] array = Arrays.copyOf(elements, n);
-        for (int i = 0; i < n; i++)
-        {
-            int r = i + nextIntHasty(n - i);
-            T t = array[r];
-            array[r] = array[i];
-            array[i] = t;
-        }
-        return array;
-    }
-
-
-    /**
-     * Generates a random permutation of the range from 0 (inclusive) to length (exclusive).
-     * Useful for passing to OrderedMap or OrderedSet's reorder() methods.
-     *
-     * @param length the size of the ordering to produce
-     * @return a random ordering containing all ints from 0 to length (exclusive)
-     */
-    @Override
-    public int[] randomOrdering(int length)
-    {
-        int[] dest = new int[length];
-        for (int i = 0; i < length; i++)
-        {
-            int r = nextIntHasty(i + 1);
-            if(r != i)
-                dest[i] = dest[r];
-            dest[r] = i;
-        }
-        return dest;
-    }
-
-    /**
-     * Returns a random non-negative integer below the given bound, or 0 if the bound is 0.
-     * Uses a slightly optimized technique. This method is considered "hasty" since
-     * it should be faster than nextInt() doesn't check for "less-valid" bounds values. It also
-     * has undefined behavior if bound is negative, though it will probably produce a negative
-     * number (just how negative is an open question).
-     *
-     * @param bound the upper bound (exclusive); behavior is undefined if bound is negative
-     * @return the found number
-     */
-    @Override
-    public int nextIntHasty(int bound) {
-        return (int)(nextDouble() * bound);
-    }
-
-    /**
-     * Returns a random integer, which may be positive or negative.
-     * @return A random int
-     */
-    @Override
-    public int nextInt() {
-        return (int)((nextDouble() * 2.0 - 1.0) * 0x7FFFFFFF);
-    }
-
-    /**
-     * Returns a random long, which may be positive or negative.
-     * @return A random long
-     */
-    @Override
-    public long nextLong() {
-        double nx = nextDouble();
-        return (long)((nx * 2.0 - 1.0) * 0x7FFFFFFFFFFFFFFFL);
-    }
-
-    /**
-     * Returns a random long below the given bound, or 0 if the bound is 0 or
-     * negative.
-     *
-     * @param bound the upper bound (exclusive)
-     * @return the found number
-     */
-    @Override
-	public long nextLong(long bound) {
-        if (bound <= 0) {
-            return 0;
-        }
-        double nx = nextDouble();
-        return (long)(nx * bound);
-        //return ((long)(nx * bound)) ^ (long)((nx * 0xFFFFFL) % bound) ^ (long)((nx * 0xFFFFF00000L) % bound);
-    }
-    /**
-     *
-     * @param bits the number of bits to be returned
-     * @return a random int of the number of bits specified.
-     */
-    @Override
-    public int next(int bits) {
-        if(bits <= 0)
-            return 0;
-        if(bits > 32)
-            bits = 32;
-        return (int)(nextDouble() * (1L << bits));
-
-    }
-
-    @Override
-    public Random asRandom() {
-        if(ran == null)
-        {
-            ran = new CustomRandom(new LightRNG(getState()));
-        }
-        return ran;
-    }
-
-    @Override
-    @GwtIncompatible
-    public <T> List<T> randomRotation(List<T> l) {
-        return super.randomRotation(l);
-    }
-
-    @Override
-    public <T> Iterable<T> getRandomStartIterable(List<T> list) {
-        return super.getRandomStartIterable(list);
-    }
-
-
-    /**
-     * Returns a value between min (inclusive) and max (exclusive).
-     * <p/>
-     * The inclusive and exclusive behavior is to match the behavior of the
-     * similar method that deals with floating point values.
-     *
-     * @param min the minimum bound on the return value (inclusive)
-     * @param max the maximum bound on the return value (exclusive)
-     * @return the found value
-     */
-    @Override
-    public long between(long min, long max) {
-        return nextLong(max - min) + min;
-    }
-
-    /*
-     * Shuffle an array using the Fisher-Yates algorithm.
-     *
-     * @param elements an array of T; will not be modified
-     * @return a shuffled copy of elements
-     * /
-    @Override
-    @GwtIncompatible
-    public <T> T[] shuffle(T[] elements) {
-        return super.shuffle(elements);
-    }
-*/
-    /**
-     * Shuffle an array using the Fisher-Yates algorithm.
-     *
-     * @param elements an array of T; will not be modified
-     * @param dest     Where to put the shuffle. It MUST have the same length as {@code elements}
-     * @return {@code dest}
-     * @throws IllegalStateException If {@code dest.length != elements.length}
-     */
-    @Override
-    public <T> T[] shuffle(T[] elements, T[] dest) {
-        return super.shuffle(elements, dest);
-    }
-
-    @Override
-    public <T> ArrayList<T> shuffle(Collection<T> elements) {
-        return super.shuffle(elements);
-    }
-
-    @Override
-    public float nextFloat() {
-        return (float)nextDouble();
-    }
-
-    @Override
-    public boolean nextBoolean() {
-        return nextDouble() >= 0.5;
-    }
-
-    @Override
-    public RandomnessSource getRandomness() {
-        return random;
-    }
-
-    /**
-     * Reseeds this DeckRNG using the RandomnessSource it is given. Does not assign the RandomnessSource to any fields
-     * that would affect future pseudo-random number generation.
-     * @param random will be used to generate a new seed, but will not be assigned as this object's RandomnessSource
-     */
-    @Override
-    public void setRandomness(RandomnessSource random) {
-        setState(((long)random.next(32) << 32) | random.next(32));
-
-    }
-
-    /**
-     * Creates a copy of this DeckRNG; it will generate the same random numbers, given the same calls in order, as
-     * this DeckRNG at the point copy() is called. The copy will not share references with this DeckRNG.
-     *
-     * @return a copy of this DeckRNG
-     */
-    public RNG copy()
-    {
-        DeckRNG next = new DeckRNG(lastShuffledState);
-        next.random = random.copy();
-        System.arraycopy(deck, 0, next.deck, 0, deck.length);
-        next.step = step;
-        return next;
-    }
-
-    /**
-     * 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; does this by
-     * shuffling a copy of data and getting a section of it that matches the length of output.
-     *
-     * Based on http://stackoverflow.com/a/21460179 , credit to Vincent van der Weele; modifications were made to avoid
-     * copying or creating a new generic array (a problem on GWT).
-     * @param data an array of T; will not be modified.
-     * @param output an array of T that will be overwritten; should always be instantiated with the portion length
-     * @param <T> can be any non-primitive type.
-     * @return an array of T that has length equal to output's length and may contain null elements if output is shorter
-     * than data
-     */
-    @Override
-    public <T> T[] randomPortion(T[] data, T[] output) {
-        return super.randomPortion(data, output);
-    }
-
-    /**
-     * Gets a random portion of a List and returns it as a new List. Will only use a given position in the given
-     * List at most once; does this by shuffling a copy of the List and getting a section of it.
-     *
-     * @param data  a List of T; will not be modified.
-     * @param count the non-negative number of elements to randomly take from data
-     * @return a List of T that has length equal to the smaller of count or data.length
-     */
-    @Override
-    public <T> List<T> randomPortion(List<T> data, int count) {
-        return super.randomPortion(data, count);
-    }
-
-    /**
-     * 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).
-     *
-     * @param start the start of the range of numbers to potentially use (inclusive)
-     * @param end   the end of the range of numbers to potentially use (exclusive)
-     * @param count the total number of elements to use; will be less if the range is smaller than count
-     * @return an int array that contains at most one of each number in the range
-     */
-    @Override
-    public int[] randomRange(int start, int end, int count) {
-        return super.randomRange(start, end, count);
-    }
-
-    /**
-     * Shuffle an array using the Fisher-Yates algorithm.
-     * @param array an array of double; WILL be modified
-     */
-    private void shuffleInPlace(double[] array)
-    {
-        lastShuffledState = ((LightRNG)random).getState();
-        int n = array.length;
-        System.arraycopy(baseDeck, 0, array, 0, n);
-        for (int i = 0; i < n; i++)
-        {
-            int r = i + ((LightRNG)random).nextInt(n - i);
-            double t = array[r];
-            array[r] = array[i];
-            array[i] =((LightRNG)random).nextDouble(0.0625) + t;
-        }
-    }
-
-    /**
-     * Get a long that can be used to reproduce the sequence of random numbers this object will generate starting now.
-     *
-     * @return a long that can be used as state.
-     */
-    @Override
-    public long getState() {
-        return lastShuffledState;
-    }
-
-    /**
-     * Sets the state of the random number generator to a given long, which will alter future random numbers this
-     * produces based on the state. Setting the state always causes the "deck" of random grades to be shuffled.
-     *
-     * @param state any long (this can tolerate states of 0)
-     */
-    @Override
-    public void setState(long state) {
-        ((LightRNG)random).setState(state);
-        shuffleInPlace(deck);
-        step = 0;
-
-    }
-
-    @Override
-    public String toString() {
-        return "DeckRNG{state: 0x" + StringKit.hex(lastShuffledState) + "L}";
-    }
-
-    public int getStep() {
-        return step;
-    }
-
-    public void setStep(int step) {
-        this.step = step;
-    }
-}

+ 0 - 586
squidlib-util/src/main/java/squidpony/squidmath/DharmaRNG.java

@@ -1,586 +0,0 @@
-package squidpony.squidmath;
-
-import squidpony.annotation.GwtIncompatible;
-
-import java.io.Serializable;
-import java.util.*;
-
-/**
- * An alteration to a RandomnessSource that attempts to produce values that are perceived as fair to an imperfect user.
- * <p>
- * This takes a RandomnessSource, defaulting to a LightRNG, and uses it to generate random values, but tracks the total
- * and compares it to the potential total of a generator of only numbers with a desired value (default 0.54,
- * so it compares against a sequence of all 0.54). If the current generated total is too high or low compared to the
- * desired total, the currently used seed is possibly changed, the generated number is moved in the direction of the
- * desired fairness, and it returns that instead of the number that would have pushed the current generated total
- * beyond the desired threshold. The new number, if one is changed, will always be closer to the desired fairness.
- * This is absolutely insecure for cryptographic purposes, but should seem more "fair" to a player than a
- * random number generator that seeks to be truly random.
- * You can create multiple DharmaRNG objects with different fairness values and seeds, and use favorable generators
- * (with fairness greater than 0.54) for characters that need an easier time, or unfavorable generators if you want
- * the characters that use that RNG to be impeded somewhat.
- * The name comes from the Wheel of Dharma.
- * This class currently will have a slight bias toward lower numbers with many RNGs unless fairness is tweaked; 0.54
- * can be used as a stand-in because 0.5 leans too low.
- *
- * <p>
- * You can get values from this generator with: {@link #nextDouble()}, {@link #nextInt()},
- *   {@link #nextLong()}, and the bounded variants on each of those.
- * <p>
- * You can alter the tracking information or requested fairness with {@link #resetFortune()},
- *   {@link #setFairness(double)}, and {@link #getFairness()}.
- *
- * Created by Tommy Ettinger on 5/2/2015.
- */
-public class DharmaRNG extends RNG implements Serializable{
-
-	/** Used to tweak the generator toward high or low values. */
-    private double fairness = 0.54;
-
-    /** Running total for what this has actually produced. */
-    private double produced = 0.0;
-
-    /** Running total for what this would produce if it always produced a value equal to fairness. */
-    private double baseline = 0.0;
-
-	private static final long serialVersionUID = -8919455766853811999L;
-
-    /**
-     * Constructs a DharmaRNG with a pseudo-random seed from Math.random().
-     */
-    public DharmaRNG()
-    {
-        this((long)(Math.random() * ((1L << 50) - 1)));
-    }
-    /**
-     * Construct a new DharmaRNG with the given seed.
-     *
-     * @param seed used to seed the default RandomnessSource.
-     */
-    public DharmaRNG(final long seed) {
-        super(seed);
-    }
-
-    /**
-     * Construct a new DharmaRNG with the given seed.
-     *
-     * @param seed used to seed the default RandomnessSource.
-     * @param fairness the desired fairness metric, which must be between 0.0 and 1.0
-     */
-    public DharmaRNG(final long seed, final double fairness) {
-        super(seed);
-        if(fairness < 0.0 || fairness >= 1.0)
-            this.fairness = 0.54;
-        else
-            this.fairness = fairness;
-    }
-
-
-    /**
-     * String-seeded constructor; uses a platform-independent hash of the String (it does not use String.hashCode) as a
-     * seed for LightRNG, which is of high quality, but low period (which rarely matters for games), and has good speed,
-     * tiny state size, and excellent 64-bit number generation.
-     *
-     * @param seedString a String as a seed
-     */
-    public DharmaRNG(String seedString) {
-        super(seedString);
-    }
-
-
-    /**
-     * String-seeded constructor; uses a platform-independent hash of the String (it does not use String.hashCode) as a
-     * seed for LightRNG, which is of high quality, but low period (which rarely matters for games), and has good speed,
-     * tiny state size, and excellent 64-bit number generation.
-     *
-     * @param seedString a String as a seed
-     */
-    public DharmaRNG(String seedString, double fairness) {
-        super(seedString);
-        if(fairness < 0.0 || fairness >= 1.0)
-            this.fairness = 0.54;
-        else
-            this.fairness = fairness;
-
-    }
-    /**
-     * Construct a new DharmaRNG with the given seed.
-     *
-     * @param rs the implementation used to generate random bits.
-     */
-    public DharmaRNG(final RandomnessSource rs) {
-        super(rs);
-    }
-    /**
-     * Construct a new DharmaRNG with the given seed.
-     *
-     * @param rs the implementation used to generate random bits.
-     * @param fairness the desired fairness metric, which must be between 0.0 and 1.0
-     */
-    public DharmaRNG(final RandomnessSource rs, final double fairness) {
-        super(rs);
-        if(fairness < 0.0 || fairness >= 1.0)
-            this.fairness = 0.54;
-        else
-            this.fairness = fairness;
-    }
-
-    /**
-     * Generate a random double, altering the result if recently generated results have been leaning
-     * away from this class' fairness value.
-     * @return a double between 0.0 (inclusive) and 1.0 (exclusive)
-     */
-    @Override
-    public double nextDouble() {
-        double gen = random.nextLong() * DOUBLE_UNIT;
-        /*if(Math.abs((produced + gen) - (baseline + fairness)) > 1.5) {
-            //do some reseeding here if possible
-        }*/
-        if(Math.abs((produced + gen) - (baseline + fairness)) > 0.5)
-        {
-            gen = (gen + fairness) / 2.0;
-            produced *= 0.5;
-            baseline *= 0.5;
-            produced += gen;
-            baseline += fairness;
-            return gen;
-        }
-        else
-        {
-            produced += gen;
-            baseline += fairness;
-            return gen;
-        }
-    }
-
-    /**
-     * This returns a random double between 0.0 (inclusive) and max (exclusive).
-     *
-     * @return a value between 0 (inclusive) and max (exclusive)
-     */
-    @Override
-    public double nextDouble(double max) {
-        return super.nextDouble(max);
-    }
-
-    /**
-     * Returns a value from a even distribution from min (inclusive) to max
-     * (exclusive).
-     *
-     * @param min the minimum bound on the return value (inclusive)
-     * @param max the maximum bound on the return value (exclusive)
-     * @return the found value
-     */
-    @Override
-    public double between(double min, double max) {
-        return super.between(min, max);
-    }
-
-    /**
-     * 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.
-     *
-     * @param min the minimum bound on the return value (inclusive)
-     * @param max the maximum bound on the return value (exclusive)
-     * @return the found value
-     */
-    @Override
-    public int between(int min, int max)
-    {
-        return super.between(min, max);
-    }
-
-    /**
-     * 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.
-     *
-     * @param min the minimum bound on the return value (inclusive)
-     * @param max the maximum bound on the return value (exclusive)
-     * @param samples the number of samples to take
-     * @return the found value
-     */
-    @Override
-    public int betweenWeighted(int min, int max, int samples) {
-        return super.betweenWeighted(min, max, samples);
-    }
-
-    /**
-     * Returns a random element from the provided array and maintains object
-     * type.
-     *
-     * @param <T> the type of the returned object
-     * @param array the array to get an element from
-     * @return the randomly selected element
-     */
-    @Override
-    public <T> T getRandomElement(T[] array) {
-        return super.getRandomElement(array);
-    }
-
-    /**
-     * Returns a random element from the provided list. If the list is empty
-     * then null is returned.
-     *
-     * @param <T> the type of the returned object
-     * @param list the list to get an element from
-     * @return the randomly selected element
-     */
-    @Override
-    public <T> T getRandomElement(List<T> list) {
-        return super.getRandomElement(list);
-    }
-
-    /**
-     * Returns a random element from the provided ShortSet. If the set is empty
-     * then an exception is thrown.
-     *
-     * <p>
-     * Requires iterating through a random amount of the elements in set, so performance depends on the size of set but
-     * is likely to be decent. This is mostly meant for internal use, the same as ShortSet.
-     * </p>
-     * @param set the ShortSet to get an element from
-     * @return the randomly selected element
-     */
-    public short getRandomElement(ShortSet set) {
-        return super.getRandomElement(set);
-    }
-
-    /**
-     * 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.
-     *
-     * <p>
-     * 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 {@code getRandomElement(Queue)},
-     * since Queue implements Collection and the older Queue-using implementation was probably less efficient.
-     * </p>
-     * @param <T> the type of the returned object
-     * @param coll the Collection to get an element from; remember, Map does not implement Collection
-     * @return the randomly selected element
-     */
-    public <T> T getRandomElement(Collection<T> coll) {
-        return super.getRandomElement(coll);
-    }
-
-    /**
-     * @return a value from the gaussian distribution
-     */
-    @Override
-    public synchronized double nextGaussian() {
-        return super.nextGaussian();
-    }
-    /**
-     * Returns a random integer below the given bound, or 0 if the bound is 0 or
-     * negative. Affects the current fortune.
-     *
-     * @param bound the upper bound (exclusive)
-     * @return the found number
-     */
-    @Override
-    public int nextInt(int bound) {
-        if (bound <= 0) {
-            return 0;
-        }
-
-        return (int)(nextDouble() * bound);
-    }
-
-    /**
-     * Returns a random integer, which may be positive or negative. Affects the current fortune.
-     * @return A random int
-     */
-    @Override
-    public int nextInt() {
-        return (int)((nextDouble() - 0.5) * 2.0 * 0x7FFFFFFF);
-    }
-
-    /**
-     * Returns a random long, which may be positive or negative. Affects the current fortune.
-     * @return A random long
-     */
-    @Override
-    public long nextLong() {
-        return (long)((nextDouble() - 0.5) * 2.0 * 0x7FFFFFFFFFFFFFFFL);
-    }
-
-    /**
-     * Returns a random long below the given bound, or 0 if the bound is 0 or
-     * negative.
-     *
-     * @param bound the upper bound (exclusive)
-     * @return the found number
-     */
-    @Override
-	public long nextLong(long bound) {
-        if (bound <= 0) {
-            return 0;
-        }
-        return (long)(nextDouble() * bound);
-    }
-    /**
-     * Gets the measure that this class uses for RNG fairness, defaulting to 0.54 (always between 0.0 and 1.0).
-     * @return the current fairness metric.
-     */
-    public double getFairness() {
-        return fairness;
-    }
-
-    /**
-     * Sets the measure that this class uses for RNG fairness, which must always be between 0.0 and 1.0, and will be
-     * set to 0.54 if an invalid value is passed.
-     * @param fairness the desired fairness metric, which must be 0.0 &lt;= fairness &lt; 1.0
-     */
-    public void setFairness(double fairness) {
-        if(fairness < 0.0 || fairness >= 1.0)
-            this.fairness = 0.54;
-        else
-            this.fairness = fairness;
-    }
-
-    /**
-     * Gets the status of the fortune used when calculating fairness adjustments.
-     * @return the current value used to determine whether the results should be adjusted toward fairness.
-     */
-    public double getFortune()
-    {
-        return Math.abs(produced - baseline);
-    }
-
-    /**
-     * Resets the stored history this RNG uses to try to ensure fairness.
-     */
-    public void resetFortune()
-    {
-        produced = 0.0;
-        baseline = 0.0;
-    }
-    /**
-     *
-     * @param bits the number of bits to be returned
-     * @return a random int of the number of bits specified.
-     */
-    @Override
-    public int next(int bits) {
-        if(bits <= 0)
-            return 0;
-        if(bits > 32)
-            bits = 32;
-        return (int)(nextDouble() * (1l << bits));
-
-    }
-
-    @Override
-    public Random asRandom() {
-        return super.asRandom();
-    }
-
-    @Override
-    @GwtIncompatible
-    public <T> List<T> randomRotation(List<T> l) {
-        return super.randomRotation(l);
-    }
-
-    @Override
-    public <T> Iterable<T> getRandomStartIterable(List<T> list) {
-        return super.getRandomStartIterable(list);
-    }
-/*
-    @Override
-    @GwtIncompatible
-    public <T> T[] shuffle(T[] elements) {
-        return super.shuffle(elements);
-    }
-*/
-    @Override
-    public <T> T[] shuffle(T[] elements, T[] dest) {
-        return super.shuffle(elements, dest);
-    }
-
-    @Override
-    public <T> ArrayList<T> shuffle(Collection<T> elements) {
-        return super.shuffle(elements);
-    }
-
-    /**
-     * Returns a value between min (inclusive) and max (exclusive).
-     * <p>
-     * The inclusive and exclusive behavior is to match the behavior of the
-     * similar method that deals with floating point values.
-     *
-     * @param min the minimum bound on the return value (inclusive)
-     * @param max the maximum bound on the return value (exclusive)
-     * @return the found value
-     */
-    @Override
-    public long between(long min, long max) {
-        return min + nextLong(max - min);
-    }
-
-    /**
-     * Shuffle an array using the Fisher-Yates algorithm. Not GWT-compatible; use the overload that takes two arrays.
-     * <br>
-     * https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
-     *
-     * @param elements an array of T; will not be modified
-     * @return a shuffled copy of elements
-     */
-    @GwtIncompatible
-    @Override
-    public <T> T[] shuffle(T[] elements) {
-        return super.shuffle(elements);
-    }
-
-    /**
-     * Generates a random permutation of the range from 0 (inclusive) to length (exclusive).
-     * Useful for passing to OrderedMap or OrderedSet's reorder() methods.
-     *
-     * @param length the size of the ordering to produce
-     * @return a random ordering containing all ints from 0 to length (exclusive)
-     */
-    @Override
-    public int[] randomOrdering(int length) {
-        return super.randomOrdering(length);
-    }
-
-
-    /**
-     * Returns a random non-negative integer below the given bound, or 0 if the bound is 0.
-     * Uses a slightly optimized technique. This method is considered "hasty" since
-     * it should be faster than nextInt() doesn't check for "less-valid" bounds values. It also
-     * has undefined behavior if bound is negative, though it will probably produce a negative
-     * number (just how negative is an open question).
-     *
-     * @param bound the upper bound (exclusive); behavior is undefined if bound is negative
-     * @return the found number
-     */
-    @Override
-    public int nextIntHasty(int bound) {
-        return (int)(nextDouble() * bound);
-    }
-
-    @Override
-    public float nextFloat() {
-        return (float)nextDouble();
-    }
-
-    @Override
-    public boolean nextBoolean() {
-        return nextDouble() >= 0.5;
-    }
-
-    @Override
-    public RandomnessSource getRandomness() {
-        return random;
-    }
-
-    @Override
-    public void setRandomness(RandomnessSource random) {
-        this.random = random;
-    }
-
-    /**
-     * Creates a copy of this DharmaRNG; it will generate the same random numbers, given the same calls in order, as
-     * this DharmaRNG at the point copy() is called. The copy will not share references with this DharmaRNG.
-     *
-     * @return a copy of this DharmaRNG
-     */
-    @Override
-    public RNG copy() {
-        DharmaRNG next = new DharmaRNG(random.copy(), fairness);
-        next.produced = produced;
-        next.baseline = baseline;
-        return next;
-    }
-
-    /**
-     * 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; does this by
-     * shuffling a copy of data and getting a section of it that matches the length of output.
-     *
-     * Based on http://stackoverflow.com/a/21460179 , credit to Vincent van der Weele; modifications were made to avoid
-     * copying or creating a new generic array (a problem on GWT).
-     * @param data an array of T; will not be modified.
-     * @param output an array of T that will be overwritten; should always be instantiated with the portion length
-     * @param <T> can be any non-primitive type.
-     * @return an array of T that has length equal to output's length and may contain null elements if output is shorter
-     * than data
-     */
-    @Override
-    public <T> T[] randomPortion(T[] data, T[] output) {
-        return super.randomPortion(data, output);
-    }
-
-    /**
-     * Gets a random portion of a List and returns it as a new List. Will only use a given position in the given
-     * List at most once; does this by shuffling a copy of the List and getting a section of it.
-     *
-     * @param data  a List of T; will not be modified.
-     * @param count the non-negative number of elements to randomly take from data
-     * @return a List of T that has length equal to the smaller of count or data.length
-     */
-    @Override
-    public <T> List<T> randomPortion(List<T> data, int count) {
-        return super.randomPortion(data, count);
-    }
-
-    /**
-     * 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).
-     *
-     * @param start the start of the range of numbers to potentially use (inclusive)
-     * @param end   the end of the range of numbers to potentially use (exclusive)
-     * @param count the total number of elements to use; will be less if the range is smaller than count
-     * @return an int array that contains at most one of each number in the range
-     */
-    @Override
-    public int[] randomRange(int start, int end, int count) {
-        return super.randomRange(start, end, count);
-    }
-
-    @Override
-    public String toString() {
-        return "DharmaRNG{" +
-                "fairness=" + fairness +
-                ", produced=" + produced +
-                ", baseline=" + baseline +
-                ", Randomness Source=" + random +
-                '}';
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        DharmaRNG dharmaRNG = (DharmaRNG) o;
-
-        if (Double.compare(dharmaRNG.fairness, fairness) != 0) return false;
-        return Double.compare(dharmaRNG.produced, produced) == 0 && Double.compare(dharmaRNG.baseline, baseline) == 0;
-
-    }
-
-    @Override
-    public int hashCode() {
-        int result;
-        long temp;
-        temp = Double.doubleToLongBits(fairness);
-        result = (int) (temp ^ (temp >>> 32));
-        temp = Double.doubleToLongBits(produced);
-        result = 31 * result + (int) (temp ^ (temp >>> 32));
-        temp = Double.doubleToLongBits(baseline);
-        result = 31 * result + (int) (temp ^ (temp >>> 32));
-        return result;
-    }
-}

+ 0 - 670
squidlib-util/src/main/java/squidpony/squidmath/EditRNG.java

@@ -1,670 +0,0 @@
-package squidpony.squidmath;
-
-import squidpony.annotation.GwtIncompatible;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Random;
-
-/**
- * A subclass of StatefulRNG (and thus RNG) that allows customizing many parts of the random number generation.
- * This is meant to be a more comprehensible version of the functionality present in RandomBias, and also for it to be
- * easier to use with methods that expect an RNG.
- * <br>
- * You can change the expected average for the values this produces, which uses the RandomBias.EXPONENTIAL distribution,
- * with all the caveats it has: it strongly favors either high or low values when the average gets especially high or
- * low, but it can essentially cover all averages between 0.0 and 1.0 (this class limits it to 0.1 and 0.9, so other
- * techniques can be used effectively).
- * <br>
- * You can also affect the "centrality" of random numbers, causing more to occur near the expected average (a bell curve
- * effect), or cause more near extreme ends of the random number spectrum. In practice, centrality changes are hard to
- * notice, but may be useful to simulate certain effects. An example of centrality changes in existing games include the
- * Nintendo title Advance Wars 2, where a brutish commander could increase the amount of damage his units dealt but also
- * suffered unpredictability; attacks could deal even more or much less damage than normal without any way to build
- * tactics around it. Square Enix's Final Fantasy XII also notably differentiated certain weapons (axes, hammers, and
- * "hand-cannons") from other similar options by making them deal less predictable damage. In both cases the connotation
- * is that more randomness is fitting for a brute-force approach to combat where pre-planned strategies are less
- * emphasized. It should also be noted that increasing the frequency of extreme results makes small bonuses to defense
- * or offense typically less useful, and small penalties less harmful. The opposite can be true for a carefully tuned
- * game where the most common results are tightly clustered, and most target numbers are just slightly above the
- * ordinary average. In tabletop games, 1d20 and 3d6 have the same average, but 1d20 is uniform, where 3d6 is clustered
- * around 10 and 11, each the result of 1/8 of rolls on their own and 1/4 together. This makes the case where a +1 bonus
- * to succeed changes the outcome on approximately 5% of 1d20 rolls, regardless of the required number to succeed if it
- * is less than 20. However, a +1 bonus matters on a variable portion of 3d6 rolls; if you become able to succeed on a
- * 10 or 11 where that was a failure before, the bonus applies approximately 12.5% of the time. Becoming able to succeed
- * on an 18 where that was a failure before is essentially worthless, affecting less than 0.5% of rolls. This property
- * of centralized results should be considered if game balance and/or the lethality of combat is important. One lengthy
- * stretch of extreme results by enemies that work against the favor of a player character generally result in a dead
- * player character, and RNGs that make extreme results more common may seem particularly cruel to players.
- * <br>
- * This generator sets a field, rawLatest, every time a random number is produced. This stores a pseudo-random double
- * between 0.0 (inclusive) and 1.0 (exclusive) that is not subject to the bias an expected average introduces, and is
- * close to uniformly distributed. You should expect rawLatest to be higher when higher numbers are returned from a
- * method like nextInt(), and lower when lower numbers are returned. This can be useful for rare effects that should not
- * be drastically more or less likely when slight changes are made to the expected average; if the expected average is
- * 0.65, many more random doubles from nextDouble() will be between 0.95 and 1.0 (probably more than 10% of random
- * numbers), but rawLatest will only be between 0.95 and 1.0 for close to 5% of all generations.
- * <br>
- * You can get and set the state this uses internally, and this is stored as a 64-bit long.
- * <br>
- * The choice of RandomnessSource doesn't really matter since this will always use a LightRNG internally. LightRNG is
- * the current best StatefulRandomness implementation, with excellent performance characteristics and few flaws, though
- * its relatively low period may sometimes be a detriment.
- * <br>
- * More customizations may be added in the future to the ones available currently.
- */
-public class EditRNG extends StatefulRNG implements Serializable{
-
-	/** Used to tweak the generator toward high or low values. */
-    private double expected = 0.5;
-
-    /**
-     * When positive, makes the generator more likely to generate values close to the average (bell curve).
-     * When zero (the default), makes no changes to the centering of values.
-     * When negative, makes the generator swing more toward extremes rather than gravitate toward the average.
-     * Values are typically between -100 and 100, but can have extreme weight and overshadow other parts of the RNG if
-     * they go much higher than 200.
-     */
-    private double centrality = 0.0;
-    /**
-     * The latest generated double, between 0.0 and 1.0, before changes for centrality and expected average.
-     * Doubles are used to generate all random numbers this class produces, so be aware that calling getRandomElement()
-     * will change this just as much as nextDouble(), nextInt(), or between() will. Primarily useful to obtain
-     * uniformly-distributed random numbers that are related to the biased random numbers this returns as a main result,
-     * such as to find when the last number generated was in the bottom 5% (less than 0.05, which could represent some
-     * kind of critical failure or fumble) or top 10% (greater than or equal to 0.9, which could grant a critical
-     * success or luck-based reward of some kind).
-     */
-    public double rawLatest = 0.5;
-	private static final long serialVersionUID = -2458726316853811777L;
-
-    /**
-     * Constructs an EditRNG with a pseudo-random seed from Math.random().
-     */
-    public EditRNG()
-    {
-    }
-    /**
-     * Construct a new EditRNG with the given seed.
-     *
-     * @param seed used to seed the default RandomnessSource.
-     */
-    public EditRNG(final long seed) {
-        super(seed);
-    }
-    /**
-     * Construct a new EditRNG with the given seed.
-     *
-     * @param seed used to seed the default RandomnessSource.
-     */
-    public EditRNG(final String seed) {
-        super(seed);
-    }
-
-    /**
-     * Construct a new EditRNG with the given seed.
-     *
-     * @param seed used to seed the default RandomnessSource.
-     * @param expected the expected average for random doubles, which will be capped between 0.1 and 0.9
-     */
-    public EditRNG(final long seed, double expected) {
-        super(seed);
-        this.expected = Math.max(0.1, Math.min(0.89999994, expected));
-    }
-    /**
-     * Construct a new EditRNG with the given seed.
-     *
-     * @param seed used to seed the default RandomnessSource.
-     * @param expected the expected average for random doubles, which will be capped between 0.1 and 0.9
-     */
-    public EditRNG(final String seed, double expected) {
-        super(seed);
-        this.expected = Math.max(0.1, Math.min(0.89999994, expected));
-    }
-
-    /**
-     * Construct a new EditRNG with the given seed.
-     *
-     * @param seed used to seed the default RandomnessSource.
-     * @param expected the expected average for random doubles, which will be capped between 0.1 and 0.9
-     * @param centrality if positive, makes results more likely to be near expected; if negative, the opposite. The
-     *                   absolute value of centrality affects how centered results will be, with 0 having no effect
-     */
-    public EditRNG(final long seed, double expected, double centrality) {
-        super(seed);
-        this.expected = Math.max(0.1, Math.min(0.89999994, expected));
-        this.centrality = centrality;
-    }
-    /**
-     * Construct a new EditRNG with the given seed.
-     *
-     * @param seed used to seed the default RandomnessSource.
-     * @param expected the expected average for random doubles, which will be capped between 0.1 and 0.9
-     * @param centrality if positive, makes results more likely to be near expected; if negative, the opposite. The
-     *                   absolute value of centrality affects how centered results will be, with 0 having no effect
-     */
-    public EditRNG(final String seed, double expected, double centrality) {
-        super(seed);
-        this.expected = Math.max(0.1, Math.min(0.89999994, expected));
-        this.centrality = centrality;
-    }
-
-    /**
-     * Construct a new EditRNG with the given seed.
-     *
-     * @param rs the implementation used to generate random bits.
-     */
-    public EditRNG(final RandomnessSource rs) {
-        super(rs);
-    }
-    /**
-     * Construct a new EditRNG with the given seed.
-     *
-     * @param rs the implementation used to generate random bits.
-     * @param expected the expected average for random doubles, which will be capped between 0.1 and 0.9
-     */
-    public EditRNG(final RandomnessSource rs, double expected) {
-        super(rs);
-        this.expected = Math.max(0.1, Math.min(0.89999994, expected));
-    }
-    /**
-     * Construct a new EditRNG with the given seed.
-     *
-     * @param rs the implementation used to generate random bits.
-     * @param expected the expected average for random doubles, which will be capped between 0.1 and 0.9
-     * @param centrality if positive, makes results more likely to be near expected; if negative, the opposite. The
-     *                   absolute value of centrality affects how centered results will be, with 0 having no effect
-     */
-    public EditRNG(final RandomnessSource rs, double expected, double centrality) {
-        super(rs);
-        this.expected = Math.max(0.1, Math.min(0.89999994, expected));
-        this.centrality = centrality;
-    }
-
-    /**
-     * Generate a random double, altered to try to match the expected average and centrality.
-     * @return a double between 0.0 (inclusive) and 1.0 (exclusive)
-     */
-    @Override
-    public double nextDouble() {
-        long l = random.nextLong();
-        double gen = (l & 0x1fffffffffffffL) * DOUBLE_UNIT, scatter = (l & 0xffffffL) * FLOAT_UNIT;
-        rawLatest = 0.9999999999999999 - gen;
-        gen = 0.9999999999999999 - Math.pow(gen, 1.0 / (1.0 - expected) - 1.0);
-        if(centrality > 0) {
-            scatter = 0.9999999999999999 - Math.pow(scatter, 1.0 / (1.0 - expected) - 1.0);
-            gen = (gen * 100 + scatter * centrality) / (100 + centrality);
-        }
-        else if(centrality < 0)
-        {
-            scatter = Math.sin(scatter * Math.PI * 0.5);
-            scatter *= scatter;
-            if(expected >= 0.5)
-                scatter = scatter * (1.0 - expected) * 2 + expected - (1.0 - expected);
-            else
-                scatter *= expected * 2;
-            gen = (gen * 100 - scatter * centrality) / (100 - centrality);
-        }
-
-        return gen;
-
-    }
-
-    /**
-     * This returns a random double between 0.0 (inclusive) and max (exclusive).
-     *
-     * @return a value between 0 (inclusive) and max (exclusive)
-     */
-    @Override
-    public double nextDouble(double max) {
-        return nextDouble() * max;
-    }
-
-    /**
-     * Returns a value from a even distribution from min (inclusive) to max
-     * (exclusive).
-     *
-     * @param min the minimum bound on the return value (inclusive)
-     * @param max the maximum bound on the return value (exclusive)
-     * @return the found value
-     */
-    @Override
-    public double between(double min, double max) {
-        return super.between(min, max);
-    }
-
-    /**
-     * 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.
-     *
-     * @param min the minimum bound on the return value (inclusive)
-     * @param max the maximum bound on the return value (exclusive)
-     * @return the found value
-     */
-    @Override
-    public int between(int min, int max)
-    {
-        return super.between(min, max);
-    }
-
-    @Override
-    public long between(long min, long max) {
-        return super.between(min, max);
-    }
-
-    /**
-     * 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.
-     *
-     * @param min the minimum bound on the return value (inclusive)
-     * @param max the maximum bound on the return value (exclusive)
-     * @param samples the number of samples to take
-     * @return the found value
-     */
-    @Override
-    public int betweenWeighted(int min, int max, int samples) {
-        return super.betweenWeighted(min, max, samples);
-    }
-
-    /**
-     * Returns a random element from the provided array and maintains object
-     * type.
-     *
-     * @param <T> the type of the returned object
-     * @param array the array to get an element from
-     * @return the randomly selected element
-     */
-    @Override
-    public <T> T getRandomElement(T[] array) {
-        return super.getRandomElement(array);
-    }
-
-    /**
-     * Returns a random element from the provided list. If the list is empty
-     * then null is returned.
-     *
-     * @param <T> the type of the returned object
-     * @param list the list to get an element from
-     * @return the randomly selected element
-     */
-    @Override
-    public <T> T getRandomElement(List<T> list) {
-        return super.getRandomElement(list);
-    }
-
-    /**
-     * Returns a random element from the provided ShortSet. If the set is empty
-     * then an exception is thrown.
-     *
-     * <p>
-     * Requires iterating through a random amount of the elements in set, so performance depends on the size of set but
-     * is likely to be decent. This is mostly meant for internal use, the same as ShortSet.
-     * </p>
-     * @param set the ShortSet to get an element from
-     * @return the randomly selected element
-     */
-    public short getRandomElement(ShortSet set) {
-        return super.getRandomElement(set);
-    }
-
-    /**
-     * 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.
-     *
-     * <p>
-     * 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 {@code getRandomElement(Queue)},
-     * since Queue implements Collection and the older Queue-using implementation was probably less efficient.
-     * </p>
-     * @param <T> the type of the returned object
-     * @param coll the Collection to get an element from; remember, Map does not implement Collection
-     * @return the randomly selected element
-     */
-    public <T> T getRandomElement(Collection<T> coll) {
-        return super.getRandomElement(coll);
-    }
-
-    /**
-     * @return a value from the gaussian distribution
-     */
-    @Override
-    public synchronized double nextGaussian() {
-        return super.nextGaussian();
-    }
-    /**
-     * Returns a random integer below the given bound, or 0 if the bound is 0 or
-     * negative.
-     *
-     * @param bound the upper bound (exclusive)
-     * @return the found number
-     */
-    @Override
-    public int nextInt(int bound) {
-        if (bound <= 0) {
-            return 0;
-        }
-
-        return (int)(nextDouble() * bound);
-    }
-
-    /**
-     * Returns a random integer, which may be positive or negative.
-     * @return A random int
-     */
-    @Override
-    public int nextInt() {
-        return (int)((nextDouble() * 2.0 - 1.0) * 0x7FFFFFFF);
-    }
-
-    /**
-     * Returns a random long, which may be positive or negative.
-     * @return A random long
-     */
-    @Override
-    public long nextLong() {
-        return (long)((nextDouble() * 2.0 - 1.0) * 0x7FFFFFFFFFFFFFFFL);
-    }
-
-    /**
-     * Returns a random long below the given bound, or 0 if the bound is 0 or
-     * negative.
-     *
-     * @param bound the upper bound (exclusive)
-     * @return the found number
-     */
-    @Override
-	public long nextLong(long bound) {
-        if (bound <= 0) {
-            return 0;
-        }
-        return (long)(nextDouble() * bound);
-    }
-    /**
-     * Gets the current expected average for this EditRNG.
-     * @return the current expected average.
-     */
-    public double getExpected() {
-        return expected;
-    }
-
-    /**
-     * Sets the expected average for random doubles this produces, which must always be between 0.1 and 0.9, and will be
-     * set to 0.5 if an invalid value is passed.
-     * @param expected the expected average to use, which should be 0.1 &lt;= fairness &lt; 0.9
-     */
-    public void setExpected(double expected) {
-        if(expected < 0.0 || expected >= 1.0)
-            this.expected = 0.5;
-        else
-            this.expected = expected;
-    }
-
-    /**
-     * Gets the current centrality measure of this EditRNG.
-     * Centrality has several possible effects:
-     * When positive, makes the generator more likely to generate values close to the average (bell curve).
-     * When zero (the default), makes no changes to the centering of values.
-     * When negative, makes the generator swing more toward extremes rather than gravitate toward the average.
-     * <br>
-     * Values are typically between -100 and 100, but can have extreme weight and overshadow other parts of the RNG if
-     * they go much higher than 200.
-     * @return the current centrality
-     */
-    public double getCentrality() {
-        return centrality;
-    }
-
-    /**
-     * Gets the current centrality measure of this EditRNG.
-     * Centrality has several possible effects:
-     * When positive, makes the generator more likely to generate values close to the average (bell curve).
-     * When zero (the default), makes no changes to the centering of values.
-     * When negative, makes the generator swing more toward extremes rather than gravitate toward the average.
-     * <br>
-     * Values are typically between -100 and 100, but can have extreme weight and overshadow other parts of the RNG if
-     * they go much higher than 200.
-     * @param centrality the new centrality measure to use
-     */
-    public void setCentrality(double centrality) {
-        this.centrality = centrality;
-    }
-
-    /**
-     *
-     * @param bits the number of bits to be returned
-     * @return a random int of the number of bits specified.
-     */
-    @Override
-    public int next(int bits) {
-        if(bits <= 0)
-            return 0;
-        if(bits > 32)
-            bits = 32;
-        return (int)(nextDouble() * (1L << bits));
-
-    }
-
-    @Override
-    public Random asRandom() {
-        return super.asRandom();
-    }
-
-    @Override
-    @GwtIncompatible
-    public <T> List<T> randomRotation(List<T> l) {
-        return super.randomRotation(l);
-    }
-
-    @Override
-    public <T> Iterable<T> getRandomStartIterable(List<T> list) {
-        return super.getRandomStartIterable(list);
-    }
-
-    @Override
-    public <T> T[] shuffle(T[] elements, T[] dest) {
-        return super.shuffle(elements, dest);
-    }
-
-    @Override
-    public <T> ArrayList<T> shuffle(Collection<T> elements) {
-        return super.shuffle(elements);
-    }
-
-    @Override
-    public float nextFloat() {
-        return (float)nextDouble();
-    }
-
-    @Override
-    public boolean nextBoolean() {
-        return nextDouble() >= 0.5;
-    }
-
-    @Override
-    public RandomnessSource getRandomness() {
-        return random;
-    }
-
-    @Override
-    public void setRandomness(RandomnessSource random) {
-        this.random = random;
-    }
-
-    /**
-     * 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; does this by
-     * shuffling a copy of data and getting a section of it that matches the length of output.
-     *
-     * Based on http://stackoverflow.com/a/21460179 , credit to Vincent van der Weele; modifications were made to avoid
-     * copying or creating a new generic array (a problem on GWT).
-     * @param data an array of T; will not be modified.
-     * @param output an array of T that will be overwritten; should always be instantiated with the portion length
-     * @param <T> can be any non-primitive type.
-     * @return an array of T that has length equal to output's length and may contain null elements if output is shorter
-     * than data
-     */
-    @Override
-    public <T> T[] randomPortion(T[] data, T[] output) {
-        return super.randomPortion(data, output);
-    }
-
-    /**
-     * Gets a random portion of a List and returns it as a new List. Will only use a given position in the given
-     * List at most once; does this by shuffling a copy of the List and getting a section of it.
-     *
-     * @param data  a List of T; will not be modified.
-     * @param count the non-negative number of elements to randomly take from data
-     * @return a List of T that has length equal to the smaller of count or data.length
-     */
-    @Override
-    public <T> List<T> randomPortion(List<T> data, int count) {
-        return super.randomPortion(data, count);
-    }
-
-    /**
-     * 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).
-     *
-     * @param start the start of the range of numbers to potentially use (inclusive)
-     * @param end   the end of the range of numbers to potentially use (exclusive)
-     * @param count the total number of elements to use; will be less if the range is smaller than count
-     * @return an int array that contains at most one of each number in the range
-     */
-    @Override
-    public int[] randomRange(int start, int end, int count) {
-        return super.randomRange(start, end, count);
-    }
-
-    /**
-     * Gets the latest "un-biased" random double used to produce the most recent (potentially) biased random number
-     * generated for another method in this class, such as nextDouble(), between(), or getRandomElement(). This is a
-     * double between 0.0 (inclusive) and 1.0 (exclusive).
-     * @return the latest uniformly-distributed double before bias is added; between 0.0 and 1.0 (exclusive upper)
-     */
-    public double getRawLatest() {
-        return rawLatest;
-    }
-
-    /**
-     * Creates a copy of this StatefulRNG; it will generate the same random numbers, given the same calls in order, as
-     * this StatefulRNG at the point copy() is called. The copy will not share references with this StatefulRNG.
-     *
-     * @return a copy of this StatefulRNG
-     */
-    @Override
-    public RNG copy() {
-        EditRNG next = new EditRNG(random.copy(), expected, centrality);
-        next.rawLatest = rawLatest;
-        return next;
-    }
-
-    /**
-     * Get a long that can be used to reproduce the sequence of random numbers this object will generate starting now.
-     *
-     * @return a long that can be used as state.
-     */
-    @Override
-    public long getState() {
-        return super.getState();
-    }
-
-    /**
-     * Sets the state of the random number generator to a given long, which will alter future random numbers this
-     * produces based on the state.
-     *
-     * @param state a long, which typically should not be 0 (some implementations may tolerate a state of 0, however).
-     */
-    @Override
-    public void setState(long state) {
-        super.setState(state);
-    }
-
-    @Override
-    public String toString() {
-        return "EditRNG{" +
-                "expected=" + expected +
-                ", centrality=" + centrality +
-                ", Randomness Source=" + random +
-                '}';
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        EditRNG editRNG = (EditRNG) o;
-
-        if (Double.compare(editRNG.expected, expected) != 0) return false;
-        return Double.compare(editRNG.centrality, centrality) == 0 && Double.compare(editRNG.rawLatest, rawLatest) == 0;
-
-    }
-
-    @Override
-    public int hashCode() {
-        int result;
-        long temp;
-        temp = Double.doubleToLongBits(expected);
-        result = (int) (temp ^ (temp >>> 32));
-        temp = Double.doubleToLongBits(centrality);
-        result = 31 * result + (int) (temp ^ (temp >>> 32));
-        temp = Double.doubleToLongBits(rawLatest);
-        result = 31 * result + (int) (temp ^ (temp >>> 32));
-        return result;
-    }
-
-    /**
-     * Shuffle an array using the Fisher-Yates algorithm. Not GWT-compatible; use the overload that takes two arrays.
-     * <br>
-     * https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
-     *
-     * @param elements an array of T; will not be modified
-     * @return a shuffled copy of elements
-     */
-    @GwtIncompatible
-    @Override
-    public <T> T[] shuffle(T[] elements) {
-        return super.shuffle(elements);
-    }
-
-    /**
-     * Generates a random permutation of the range from 0 (inclusive) to length (exclusive).
-     * Useful for passing to OrderedMap or OrderedSet's reorder() methods.
-     *
-     * @param length the size of the ordering to produce
-     * @return a random ordering containing all ints from 0 to length (exclusive)
-     */
-    @Override
-    public int[] randomOrdering(int length) {
-        return super.randomOrdering(length);
-    }
-
-    /**
-     * Returns a random non-negative integer below the given bound, or 0 if the bound is 0.
-     * Uses a slightly optimized technique. This method is considered "hasty" since
-     * it should be faster than nextInt() doesn't check for "less-valid" bounds values. It also
-     * has undefined behavior if bound is negative, though it will probably produce a negative
-     * number (just how negative is an open question).
-     *
-     * @param bound the upper bound (exclusive); behavior is undefined if bound is negative
-     * @return the found number
-     */
-    @Override
-    public int nextIntHasty(int bound) {
-        return (int)(nextDouble() * bound);
-    }
-}

+ 0 - 470
squidlib-util/src/main/java/squidpony/squidmath/K2.java

@@ -1,470 +0,0 @@
-package squidpony.squidmath;
-
-import squidpony.annotation.Beta;
-
-import java.util.Iterator;
-import java.util.SortedSet;
-
-/**
- * An ordered bidirectional map-like data structure, with unique A keys and unique B keys updated together like a map
- * that can be queried by A keys, B keys, or int indices. Does not implement any interfaces that you would expect for a
- * data structure, because almost every method it has needs to specify whether it applies to A or B items, but you can
- * get collections that implement SortedSet of its A or B keys.
- * <br>
- * Called K2 because it has 2 key sets; other collections can have other keys or have values, like K2V1.
- * Created by Tommy Ettinger on 10/25/2016.
- */
-@Beta
-public class K2<A, B>
-{
-    Arrangement<A> keysA;
-    Arrangement<B> keysB;
-
-    /**
-     * Constructs an empty K2.
-     */
-    public K2()
-    {
-        keysA = new Arrangement<>();
-        keysB = new Arrangement<>();
-    }
-
-    /**
-     * Constructs a K2 with the expected number of indices to hold (the number of A and number of B items is always
-     * the same, and this will be more efficient if expected is greater than that number).
-     * @param expected
-     */
-    public K2(int expected)
-    {
-        keysA = new Arrangement<>(expected);
-        keysB = new Arrangement<>(expected);
-    }
-
-    /**
-     * Constructs a K2 with the expected number of indices to hold (the number of A and number of B items is always
-     * the same, and this will be more efficient if expected is greater than that number) and the load factor to use,
-     * between 0.1f and 0.8f usually (using load factors higher than 0.8f can cause problems).
-     * @param expected the amount of indices (the count of A items is the same as the count of B items) this should hold
-     * @param f the load factor, probably between 0.1f and 0.8f
-     */
-    public K2(int expected, float f)
-    {
-        keysA = new Arrangement<>(expected, f);
-        keysB = new Arrangement<>(expected, f);
-    }
-
-    /**
-     * Constructs a K2 from a pair of Iterables that will be processed in pairs, adding a unique A from aKeys if and
-     * only if it can also add a unique B from bKeys, otherwise skipping that pair.
-     * @param aKeys an Iterable of A that should all be unique
-     * @param bKeys an Iterable of B that should all be unique
-     */
-    public K2(Iterable<A> aKeys, Iterable<B> bKeys)
-    {
-        keysA = new Arrangement<>();
-        keysB = new Arrangement<>();
-        if(aKeys != null && bKeys != null)
-            putAll(aKeys, bKeys);
-    }
-
-    public K2(K2<A, B> other)
-    {
-        if(other == null)
-        {
-            keysA = new Arrangement<>();
-            keysB = new Arrangement<>();
-        }
-        else
-        {
-            keysA = new Arrangement<>(other.keysA);
-            keysB = new Arrangement<>(other.keysB);
-        }
-    }
-
-    public K2(Arrangement<A> aItems, Arrangement<B> bItems)
-    {
-        if(aItems == null || bItems == null)
-        {
-            keysA = new Arrangement<>();
-            keysB = new Arrangement<>();
-        }
-        else
-        {
-            int amt = Math.min(aItems.size, bItems.size);
-            keysA = aItems.take(amt);
-            keysB = bItems.take(amt);
-        }
-    }
-    /**
-     * Returns true if this contains the A, key, in its collection of A items.
-     * @param key the A to check the presence of
-     * @return true if key is present in this; false otherwise
-     */
-    public boolean containsA(A key) { return keysA.containsKey(key); }
-    /**
-     * Returns true if this contains the B, key, in its collection of B items.
-     * @param key the B to check the presence of
-     * @return true if key is present in this; false otherwise
-     */
-    public boolean containsB(B key) { return keysB.containsKey(key); }
-
-    /**
-     * Returns true if index is between 0 (inclusive) and {@link #size()} (exclusive), or false otherwise.
-     * @param index the index to check
-     * @return true if index is a valid index in the ordering of this K2
-     */
-    public boolean containsIndex(int index) { return keysA.containsValue(index); }
-
-    /**
-     * Given an A object key, finds the position in the ordering that A has, or -1 if key is not present.
-     * Unlike {@link java.util.List#indexOf(Object)}, this runs in constant time.
-     * @param key the A to find the position of
-     * @return the int index of key in the ordering, or -1 if it is not present
-     */
-    public int indexOfA(Object key)
-    {
-        return keysA.getInt(key);
-    }
-    /**
-     * Given a B object key, finds the position in the ordering that B has, or -1 if key is not present.
-     * Unlike {@link java.util.List#indexOf(Object)}, this runs in constant time.
-     * @param key the B to find the position of
-     * @return the int index of key in the ordering, or -1 if it is not present
-     */
-    public int indexOfB(Object key)
-    {
-        return keysB.getInt(key);
-    }
-
-    /**
-     * Given an int index, finds the associated A key (using index as a point in the ordering).
-     * @param index an int index into this K2
-     * @return the A object with index for its position in the ordering, or null if index was invalid
-     */
-    public A getAAt(int index)
-    {
-        return keysA.keyAt(index);
-    }
-    /**
-     * Given an int index, finds the associated B key (using index as a point in the ordering).
-     * @param index an int index into this K2
-     * @return the B object with index for its position in the ordering, or null if index was invalid
-     */
-    public B getBAt(int index)
-    {
-        return keysB.keyAt(index);
-    }
-
-    /**
-     * Given an A object, finds the associated B object (it will be at the same point in the ordering).
-     * @param key an A object to use as a key
-     * @return the B object associated with key, or null if key was not present
-     */
-    public B getBFromA(Object key)
-    {
-        return keysB.keyAt(keysA.getInt(key));
-    }
-
-    /**
-     * Given a B object, finds the associated A object (it will be at the same point in the ordering).
-     * @param key a B object to use as a key
-     * @return the A object associated with key, or null if key was not present
-     */
-    public A getAFromB(Object key)
-    {
-        return keysA.keyAt(keysB.getInt(key));
-    }
-
-    /**
-     * Gets a random A from this K2 using the given RNG.
-     * @param random generates a random index to get an A with
-     * @return a randomly chosen A, or null if this is empty
-     */
-    public A randomA(RNG random)
-    {
-        return keysA.randomKey(random);
-    }
-
-    /**
-     * Gets a random B from this K2 using the given RNG.
-     * @param random generates a random index to get a B with
-     * @return a randomly chosen B, or null if this is empty
-     */
-    public B randomB(RNG random)
-    {
-        return keysB.randomKey(random);
-    }
-    /**
-     * Changes an existing A key, {@code past}, to another A key, {@code future}, if past exists in this K2
-     * and future does not yet exist in this K2. This will retain past's point in the ordering for future, so
-     * the associated other key(s) will still be associated in the same way.
-     * @param past an A key, that must exist in this K2's A keys, and will be changed
-     * @param future an A key, that cannot currently exist in this K2's A keys, but will if this succeeds
-     * @return this for chaining
-     */
-    public K2<A, B> alterA(A past, A future)
-    {
-        if(keysA.containsKey(past) && !keysA.containsKey(future))
-            keysA.alter(past, future);
-        return this;
-    }
-
-    /**
-     * Changes an existing B key, {@code past}, to another B key, {@code future}, if past exists in this K2
-     * and future does not yet exist in this K2. This will retain past's point in the ordering for future, so
-     * the associated other key(s) will still be associated in the same way.
-     * @param past a B key, that must exist in this K2's B keys, and will be changed
-     * @param future a B key, that cannot currently exist in this K2's B keys, but will if this succeeds
-     * @return this for chaining
-     */
-    public K2<A, B> alterB(B past, B future)
-    {
-        if(keysB.containsKey(past) && !keysB.containsKey(future))
-            keysB.alter(past, future);
-        return this;
-    }
-
-    /**
-     * Changes the A key at {@code index} to another A key, {@code future}, if index is valid and future does not
-     * yet exist in this K2. The position in the ordering for future will be the same as index, and the same
-     * as the key this replaced, if this succeeds, so the other key(s) at that position will still be associated in
-     * the same way.
-     * @param index a position in the ordering to change; must be at least 0 and less than {@link #size()}
-     * @param future an A key, that cannot currently exist in this K2's A keys, but will if this succeeds
-     * @return this for chaining
-     */
-    public K2<A, B> alterAAt(int index, A future)
-    {
-        if(!keysA.containsKey(future) && index >= 0 && index < keysA.size)
-            keysA.alter(keysA.keyAt(index), future);
-        return this;
-    }
-
-
-    /**
-     * Changes the B key at {@code index} to another B key, {@code future}, if index is valid and future does not
-     * yet exist in this K2. The position in the ordering for future will be the same as index, and the same
-     * as the key this replaced, if this succeeds, so the other key(s) at that position will still be associated in
-     * the same way.
-     * @param index a position in the ordering to change; must be at least 0 and less than {@link #size()}
-     * @param future a B key, that cannot currently exist in this K2's B keys, but will if this succeeds
-     * @return this for chaining
-     */
-    public K2<A, B> alterBAt(int index, B future)
-    {
-        if(!keysB.containsKey(future) && index >= 0 && index < keysB.size)
-            keysB.alter(keysB.keyAt(index), future);
-        return this;
-    }
-    /**
-     * Adds an A key and a B key at the same point in the ordering (the end) to this K2. Neither parameter can be
-     * present in this collection before this is called. If you want to change or update an existing key, use
-     * {@link #alterA(Object, Object)} or {@link #alterB(Object, Object)}.
-     * @param a an A key to add; cannot already be present
-     * @param b a B key to add; cannot already be present
-     * @return true if this collection changed as a result of this call
-     */
-    public boolean put(A a, B b)
-    {
-        if(!keysA.containsKey(a) && !keysB.containsKey(b))
-        {
-            keysA.add(a);
-            keysB.add(b);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Puts all unique A and B keys in {@code aKeys} and {@code bKeys} into this K2 at the end. If an A in aKeys or a B
-     * in bKeys is already present when this would add one, this will not put the A and B keys at that point in the
-     * iteration order, and will place the next unique A and B it finds in the arguments at that position instead.
-     * @param aKeys an Iterable or Collection of A keys to add; should all be unique (like a Set)
-     * @param bKeys an Iterable or Collection of B keys to add; should all be unique (like a Set)
-     * @return true if this collection changed as a result of this call
-     */
-    public boolean putAll(Iterable<A> aKeys, Iterable<B> bKeys)
-    {
-        if(aKeys == null || bKeys == null) return false;
-        Iterator<A> aIt = aKeys.iterator();
-        Iterator<B> bIt = bKeys.iterator();
-        boolean changed = false;
-        while (aIt.hasNext() && bIt.hasNext())
-        {
-            changed = put(aIt.next(), bIt.next()) || changed;
-        }
-        return changed;
-    }
-    /**
-     * Puts all unique A and B keys in {@code other} into this K2, respecting other's ordering. If an A or a B in other
-     * is already present when this would add one, this will not put the A and B keys at that point in the iteration
-     * order, and will place the next unique A and B it finds in the arguments at that position instead.
-     * @param other another K2 collection with the same A and B types
-     * @return true if this collection changed as a result of this call
-     */
-    public boolean putAll(K2<A, B> other)
-    {
-        if(other == null) return false;
-        boolean changed = false;
-        int sz = other.size();
-        for (int i = 0; i < sz; i++) {
-            changed = put(other.getAAt(i), other.getBAt(i)) || changed;
-        }
-        return changed;
-    }
-
-    /**
-     * Adds an A key and a B key at the given index in the ordering to this K2. Neither a nor b can be
-     * present in this collection before this is called. If you want to change or update an existing key, use
-     * {@link #alterA(Object, Object)} or {@link #alterB(Object, Object)}. The index this is given should be at
-     * least 0 and no greater than {@link #size()}.
-     * @param index the point in the ordering to place a and b into; later entries will be shifted forward
-     * @param a an A key to add; cannot already be present
-     * @param b a B key to add; cannot already be present
-     * @return true if this collection changed as a result of this call
-     */
-    public boolean putAt(int index, A a, B b)
-    {
-        if(!keysA.containsKey(a) && !keysB.containsKey(b))
-        {
-            keysA.addAt(index, a);
-            keysB.addAt(index, b);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Removes a given A key, if {@code removing} exists in this K2's A keys, and also removes any keys
-     * associated with its point in the ordering.
-     * @param removing the A key to remove
-     * @return this for chaining
-     */
-    public K2<A, B> removeA(A removing)
-    {
-        keysB.removeAt(keysA.removeInt(removing));
-        return this;
-    }
-    /**
-     * Removes a given B key, if {@code removing} exists in this K2's B keys, and also removes any keys
-     * associated with its point in the ordering.
-     * @param removing the B key to remove
-     * @return this for chaining
-     */
-    public K2<A, B> removeB(B removing)
-    {
-        keysA.removeAt(keysB.removeInt(removing));
-        return this;
-    }
-    /**
-     * Removes a given point in the ordering, if {@code index} is at least 0 and less than {@link #size()}.
-     * @param index the position in the ordering to remove
-     * @return this for chaining
-     */
-    public K2<A, B> removeAt(int index)
-    {
-        keysA.removeAt(index);
-        keysB.removeAt(index);
-        return this;
-    }
-
-    /**
-     * Reorders this K2 using {@code ordering}, which have the same length as this K2's {@link #size()}
-     * and can be generated with {@link squidpony.GwtCompatibility#range(int)} (which, if applied, would produce no
-     * change to the current ordering), {@link RNG#randomOrdering(int)} (which gives a random ordering, and if
-     * applied immediately would be the same as calling {@link #shuffle(RNG)}), or made in some other way. If you
-     * already have an ordering and want to make a different ordering that can undo the change, you can use
-     * {@link squidpony.GwtCompatibility#invertOrdering(int[])} called on the original ordering.
-     * @param ordering an int array or vararg that should contain each int from 0 to {@link #size()} (or less)
-     * @return this for chaining
-     */
-    public K2<A, B> reorder(int... ordering)
-    {
-        keysA.reorder(ordering);
-        keysB.reorder(ordering);
-        return this;
-    }
-
-    /**
-     * Generates a random ordering with rng and applies the same ordering to all kinds of keys this has; they will
-     * maintain their current association to other keys but their ordering/indices will change.
-     * @param rng an RNG to produce the random ordering this will use
-     * @return this for chaining
-     */
-    public K2<A, B> shuffle(RNG rng)
-    {
-        int[] ordering = rng.randomOrdering(keysA.size);
-        keysA.reorder(ordering);
-        keysB.reorder(ordering);
-        return this;
-    }
-
-    /**
-     * Creates a new iterator over the A keys this holds. This can be problematic for garbage collection if called very
-     * frequently; it may be better to access items by index (which also lets you access other keys associated with that
-     * index) using {@link #getAAt(int)} in a for(int i=0...) loop.
-     * @return a newly-created iterator over this K2's A keys
-     */
-    public Iterator<A> iteratorA()
-    {
-        return keysA.iterator();
-    }
-    /**
-     * Creates a new iterator over the B keys this holds. This can be problematic for garbage collection if called very
-     * frequently; it may be better to access items by index (which also lets you access other keys associated with that
-     * index) using {@link #getBAt(int)} in a for(int i=0...) loop.
-     * @return a newly-created iterator over this K2's B keys
-     */
-    public Iterator<B> iteratorB()
-    {
-        return keysB.iterator();
-    }
-
-    /**
-     * Gets and caches the A keys as a Collection that implements SortedSet (and so also implements Set).
-     * @return the A keys as a SortedSet
-     */
-    public SortedSet<A> getSetA() {
-        return keysA.keySet();
-    }
-    /**
-     * Gets and caches the B keys as a Collection that implements SortedSet (and so also implements Set).
-     * @return the B keys as a SortedSet
-     */
-    public SortedSet<B> getSetB() {
-        return keysB.keySet();
-    }
-
-    /**
-     * To be called sparingly, since this allocates a new OrderedSet instead of reusing one.
-     * @return the A keys as an OrderedSet
-     */
-    public OrderedSet<A> getOrderedSetA() {
-        return keysA.keysAsOrderedSet();
-    }
-
-    /**
-     * To be called sparingly, since this allocates a new OrderedSet instead of reusing one.
-     * @return the B keys as an OrderedSet
-     */
-    public OrderedSet<B> getOrderedSetB() {
-        return keysB.keysAsOrderedSet();
-    }
-
-    public int keyCount() {
-        return 2;
-    }
-    public int valueCount() {
-        return 0;
-    }
-
-    public int size() {
-        return keysA.size;
-    }
-    
-    public boolean isEmpty()
-    {
-        return keysA.isEmpty();
-    }
-
-}

+ 0 - 548
squidlib-util/src/main/java/squidpony/squidmath/K2V1.java

@@ -1,548 +0,0 @@
-package squidpony.squidmath;
-
-import squidpony.GwtCompatibility;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.SortedSet;
-
-/**
- * An ordered multi-directional map-like data structure with two sets of keys and one list of values.
- *
- * This is structured so that the two keys, of types A and B, are always associated with each other and the same value,
- * of type Q, but may have their index in the ordering change. You can look up a B key with an A key or index, an A key
- * with a B key or index, and a Q value with an A key, B key, or index.
- * Created by Tommy Ettinger on 10/27/2016.
- */
-public class K2V1<A, B, Q> {
-    K2<A, B> keys;
-    ArrayList<Q> values;
-
-    /**
-     * Constructs an empty K2V1 with the default parameters: 32 expected indices and a load factor of 0.5f.
-     */
-    public K2V1()
-    {
-        this(32, 0.5f);
-    }
-
-    /**
-     * Constructs an empty K2V1 that can hold {@code expected} indices before resizing and has a load factor of 0.5f.
-     * @param expected the expected number of items of any single type that this will hold; each put counts as one item
-     */
-    public K2V1(int expected)
-    {
-        this(expected, 0.5f);
-    }
-
-    /**
-     * Constructs an empty K2V1 that can hold {@code expected} indices before resizing and has load factor {@code f}.
-     * @param expected the expected number of items of any single type that this will hold; each put counts as one item
-     * @param f the load factor; must be greater than 0 and less than 1, but should ideally be between 0.2 and 0.8
-     */
-    public K2V1(int expected, float f)
-    {
-        keys = new K2<>(expected, f);
-        values = new ArrayList<>(expected);
-    }
-
-    /**
-     * Constructs a K2V1 from an A iterable, a B iterable, and a Q iterable, where the A and B items should be unique
-     * (if they aren't, each item that would be associated with a duplicate A or B will be skipped). The K2V1 this
-     * constructs will only take enough items from all Iterables to exhaust the shortest Iterable, so the lengths can be
-     * different between arguments. If there are no duplicate A keys or duplicate B keys (e.g. you can have an A key
-     * that is equal to a B key, but not to another A key), then all items will be used in the order the Iterable
-     * parameters provide them; otherwise the keys and value that would be associated with a duplicate are skipped.
-     * @param aKeys an Iterable of A keys; if null will be considered empty and this K2V1 will be empty
-     * @param bKeys an Iterable of B keys; if null will be considered empty and this K2V1 will be empty
-     * @param qValues an Iterable of Q values; if null will be considered empty and this K2V1 will be empty
-     */
-    public K2V1(Iterable<A> aKeys, Iterable<B> bKeys, Iterable<Q> qValues)
-    {
-        this(32, 0.5f);
-        putAll(aKeys, bKeys, qValues);
-    }
-
-    /**
-     * Constructs a K2V1 from another K2V1 with ths same A, B, and Q types. This will have an expected size equal to the
-     * current size of other, use the same load factor (f) as other, and will have the same items put into it in the
-     * same order.
-     * @param other a K2V1 to copy into this; must have the same A, B, and Q types
-     */
-    public K2V1(K2V1<A, B, Q> other)
-    {
-        this(other == null ? 32 : other.size(), other == null ? 0.5f : other.keys.keysA.f);
-        putAll(other);
-    }
-    /**
-     * Returns true if this contains the A, key, in its collection of A items, or false otherwise.
-     * @param key the A to check the presence of
-     * @return true if key is present in this; false otherwise
-     */
-    public boolean containsA(A key) { return keys.containsA(key); }
-    /**
-     * Returns true if this contains the B, key, in its collection of B items, or false otherwise.
-     * @param key the B to check the presence of
-     * @return true if key is present in this; false otherwise
-     */
-    public boolean containsB(B key) { return keys.containsB(key); }
-
-    /**
-     * Returns true if this contains at least one Q value, or false otherwise
-     * @param value the value to check
-     * @return true if value is present at least once in this collection's Q collection
-     */
-    public boolean containsQ(Q value) { return values.contains(value); }
-
-    /**
-     * Returns true if index is between 0 (inclusive) and {@link #size()} (exclusive), or false otherwise.
-     * @param index the index to check
-     * @return true if index is a valid index in the ordering of this K2V1
-     */
-    public boolean containsIndex(int index) { return keys.containsIndex(index); }
-
-    /**
-     * Given an A object key, finds the position in the ordering which that A has, or -1 if key is not present.
-     * Unlike {@link java.util.List#indexOf(Object)}, this runs in constant time.
-     * @param key the A to find the position of
-     * @return the int index of key in the ordering, or -1 if it is not present
-     */
-    public int indexOfA(Object key)
-    {
-        return keys.indexOfA(key);
-    }
-    /**
-     * Given a B object key, finds the position in the ordering which that B has, or -1 if key is not present.
-     * Unlike {@link java.util.List#indexOf(Object)}, this runs in constant time.
-     * @param key the B to find the position of
-     * @return the int index of key in the ordering, or -1 if it is not present
-     */
-    public int indexOfB(Object key)
-    {
-        return keys.indexOfB(key);
-    }
-
-    /**
-     * Given a Q value, finds the first position in the ordering which contains that value, or -1 if not present.
-     * Runs in linear time normally, since this uses {@link ArrayList#indexOf(Object)} to search the values.
-     * @param value the value to find the position of, which should be a Q
-     * @return the first int index of value in the ordering, or -1 if it is not present
-     */
-    public int indexOfQ(Object value) {
-        //noinspection SuspiciousMethodCalls
-        return values.indexOf(value);
-    }
-
-    /**
-     * Given an int index, finds the associated A key (using index as a point in the ordering).
-     * @param index an int index into this K2V1
-     * @return the A object with index for its position in the ordering, or null if index was invalid
-     */
-    public A getAAt(int index)
-    {
-        return keys.getAAt(index);
-    }
-    /**
-     * Given an int index, finds the associated B key (using index as a point in the ordering).
-     * @param index an int index into this K2V1
-     * @return the B object with index for its position in the ordering, or null if index was invalid
-     */
-    public B getBAt(int index)
-    {
-        return keys.getBAt(index);
-    }
-
-    /**
-     * Given an int index, finds the associated Q value (using index as a point in the ordering).
-     * @param index an int index into this K2V1
-     * @return the Q value with index for its position in the ordering, or null if index was invalid
-     */
-    public Q getQAt(int index)
-    {
-        if(index < 0 || index >= keys.keysA.size)
-            return null;
-        return values.get(index);
-    }
-
-    /**
-     * Given an A object, finds the associated B object (it will be at the same point in the ordering).
-     * @param key an A object to use as a key
-     * @return the B object associated with key, or null if key was not present
-     */
-    public B getBFromA(Object key)
-    {
-        return keys.getBFromA(key);
-    }
-
-    /**
-     * Given a B object, finds the associated A object (it will be at the same point in the ordering).
-     * @param key a B object to use as a key
-     * @return the A object associated with key, or null if key was not present
-     */
-    public A getAFromB(Object key)
-    {
-        return keys.getAFromB(key);
-    }
-    /**
-     * Given an A object, finds the associated Q value (it will be at the same point in the ordering).
-     * @param key an A object to use as a key
-     * @return the Q value associated with key, or null if key was not present
-     */
-    public Q getQFromA(Object key)
-    {
-        int idx = keys.indexOfA(key);
-        if(idx >= 0)
-            return values.get(idx);
-        return null;
-    }
-    /**
-     * Given a B object, finds the associated Q value (it will be at the same point in the ordering).
-     * @param key a B object to use as a key
-     * @return the Q value associated with key, or null if key was not present
-     */
-    public Q getQFromB(Object key)
-    {
-        int idx = keys.indexOfB(key);
-        if(idx >= 0)
-            return values.get(idx);
-        return null;
-    }
-
-    /**
-     * Gets a random A from this K2V1 using the given RNG.
-     * @param random generates a random index to get an A with
-     * @return a randomly chosen A, or null if this is empty
-     */
-    public A randomA(RNG random)
-    {
-        return keys.randomA(random);
-    }
-
-    /**
-     * Gets a random B from this K2V1 using the given RNG.
-     * @param random generates a random index to get a B with
-     * @return a randomly chosen B, or null if this is empty
-     */
-    public B randomB(RNG random)
-    {
-        return keys.randomB(random);
-    }
-
-    /**
-     * Gets a random Q from this K2V1 using the given RNG.
-     * @param random generates a random index to get a Q with
-     * @return a randomly chosen Q, or null if this is empty
-     */
-    public Q randomQ(RNG random) {
-        if(random == null || values.isEmpty())
-            return null;
-        return values.get(random.nextIntHasty(values.size()));
-    }
-
-    /**
-     * Changes an existing A key, {@code past}, to another A key, {@code future}, if past exists in this K2V1
-     * and future does not yet exist in this K2V1. This will retain past's point in the ordering for future, so
-     * the associated other key(s) will still be associated in the same way.
-     * @param past an A key, that must exist in this K2V1's A keys, and will be changed
-     * @param future an A key, that cannot currently exist in this K2V1's A keys, but will if this succeeds
-     * @return this for chaining
-     */
-    public K2V1<A, B, Q> alterA(A past, A future)
-    {
-        keys.alterA(past, future);
-        return this;
-    }
-
-    /**
-     * Changes an existing B key, {@code past}, to another B key, {@code future}, if past exists in this K2V1
-     * and future does not yet exist in this K2V1. This will retain past's point in the ordering for future, so
-     * the associated other key(s) will still be associated in the same way.
-     * @param past a B key, that must exist in this K2V1's B keys, and will be changed
-     * @param future a B key, that cannot currently exist in this K2V1's B keys, but will if this succeeds
-     * @return this for chaining
-     */
-    public K2V1<A, B, Q> alterB(B past, B future)
-    {
-        keys.alterB(past, future);
-        return this;
-    }
-
-    /**
-     * Changes the A key at {@code index} to another A key, {@code future}, if index is valid and future does not
-     * yet exist in this K2V1. The position in the ordering for future will be the same as index, and the same
-     * as the key this replaced, if this succeeds, so the other key(s) at that position will still be associated in
-     * the same way.
-     * @param index a position in the ordering to change; must be at least 0 and less than {@link #size()}
-     * @param future an A key, that cannot currently exist in this K2V1's A keys, but will if this succeeds
-     * @return this for chaining
-     */
-    public K2V1<A, B, Q> alterAAt(int index, A future)
-    {
-        keys.alterAAt(index, future);
-        return this;
-    }
-
-
-    /**
-     * Changes the B key at {@code index} to another B key, {@code future}, if index is valid and future does not
-     * yet exist in this K2V1. The position in the ordering for future will be the same as index, and the same
-     * as the key this replaced, if this succeeds, so the other key(s) at that position will still be associated in
-     * the same way.
-     * @param index a position in the ordering to change; must be at least 0 and less than {@link #size()}
-     * @param future a B key, that cannot currently exist in this K2V1's B keys, but will if this succeeds
-     * @return this for chaining
-     */
-    public K2V1<A, B, Q> alterBAt(int index, B future)
-    {
-        keys.alterBAt(index, future);
-        return this;
-    }
-
-    /**
-     * Changes the Q value at {@code index} to another Q value, {@code future}, if index is valid. The position in the
-     * ordering for future will be the same as index, and the same as the key this replaced, if this succeeds, so the
-     * keys at that position will still be associated in the same way.
-     * @param index a position in the ordering to change; must be at least 0 and less than {@link #size()}
-     * @param future a Q value that will be set at the given index if this succeeds
-     * @return this for chaining
-     */
-    public K2V1<A, B, Q> alterQAt(int index, Q future)
-    {
-        values.set(index, future);
-        return this;
-    }
-    /**
-     * Adds an A key, a B key, and a Q value at the same point in the ordering (the end) to this K2V1. Neither aKey nor
-     * bKey can be present in this collection before this is called. If you want to change or update an existing key,
-     * use {@link #alterA(Object, Object)} or {@link #alterB(Object, Object)}. The value, qValue, has no restrictions.
-     * @param aKey an A key to add; cannot already be present
-     * @param bKey a B key to add; cannot already be present
-     * @param qValue a Q value to add; can be present any number of times
-     * @return true if this collection changed as a result of this call
-     */
-
-    public boolean put(A aKey, B bKey, Q qValue)
-    {
-        if(keys.put(aKey, bKey))
-        {
-            values.add(qValue);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Adds an A key, a B key, and a Q value at the given index in the ordering to this K2V1. Neither a nor b can be
-     * present in this collection before this is called. If you want to change or update an existing key, use
-     * {@link #alterA(Object, Object)} or {@link #alterB(Object, Object)}. The value, q, has no restrictions. The index
-     * this is given should be at least 0 and no greater than {@link #size()}.
-     * @param index the point in the ordering to place a and b into; later entries will be shifted forward
-     * @param a an A key to add; cannot already be present
-     * @param b a B key to add; cannot already be present
-     * @param q a Q value to add; can be present any number of times
-     * @return true if this collection changed as a result of this call
-     */
-    public boolean putAt(int index, A a, B b, Q q)
-    {
-        if(keys.putAt(index, a, b))
-        {
-            values.add(index, q);
-            return true;
-        }
-        return false;
-    }
-    public boolean putAll(Iterable<A> aKeys, Iterable<B> bKeys, Iterable<Q> qValues)
-    {
-        if(aKeys == null || bKeys == null || qValues == null) return false;
-        Iterator<A> aIt = aKeys.iterator();
-        Iterator<B> bIt = bKeys.iterator();
-        Iterator<Q> qIt = qValues.iterator();
-        boolean changed = false;
-        while (aIt.hasNext() && bIt.hasNext() && qIt.hasNext())
-        {
-            changed = put(aIt.next(), bIt.next(), qIt.next()) || changed;
-        }
-        return changed;
-    }
-    /**
-     * Puts all unique A and B keys in {@code other} into this K2V1, respecting other's ordering. If an A or a B in other
-     * is already present when this would add one, this will not put the A and B keys at that point in the iteration
-     * order, and will place the next unique A and B it finds in the arguments at that position instead.
-     * @param other another K2V1 collection with the same A and B types
-     * @return true if this collection changed as a result of this call
-     */
-    public boolean putAll(K2V1<A, B, Q> other)
-    {
-        if(other == null) return false;
-        boolean changed = false;
-        int sz = other.size();
-        for (int i = 0; i < sz; i++) {
-            changed = put(other.getAAt(i), other.getBAt(i), other.getQAt(i)) || changed;
-        }
-        return changed;
-    }
-    /**
-     * Removes a given A key, if {@code removing} exists in this K2V1's A keys, and also removes any B key or Q value
-     * associated with its point in the ordering.
-     * @param removing the A key to remove
-     * @return this for chaining
-     */
-    public K2V1<A, B, Q> removeA(A removing)
-    {
-        int i = keys.keysA.removeInt(removing);
-        if(i >= 0) {
-            keys.keysB.removeAt(i);
-            values.remove(i);
-        }
-        return this;
-    }
-
-    /**
-     * Removes a given B key, if {@code removing} exists in this K2V1's B keys, and also removes any A key or Q value
-     * associated with its point in the ordering.
-     * @param removing the B key to remove
-     * @return this for chaining
-     */
-    public K2V1<A, B, Q> removeB(B removing)
-    {
-        int i = keys.keysB.removeInt(removing);
-        if(i >= 0) {
-            keys.keysA.removeAt(i);
-            values.remove(i);
-        }
-        return this;
-    }
-    /**
-     * Removes a given point in the ordering, if {@code index} is at least 0 and less than {@link #size()}.
-     * @param index the position in the ordering to remove
-     * @return this for chaining
-     */
-    public K2V1<A, B, Q> removeAt(int index)
-    {
-        if (index >= 0 && index < keys.keysA.size) {
-            keys.removeAt(index);
-            values.remove(index);
-        }
-        return this;
-    }
-
-    /**
-     * Reorders this K2V1 using {@code ordering}, which have the same length as this K2V1's {@link #size()}
-     * and can be generated with {@link squidpony.GwtCompatibility#range(int)} (which, if applied, would produce no
-     * change to the current ordering), {@link RNG#randomOrdering(int)} (which gives a random ordering, and if
-     * applied immediately would be the same as calling {@link #shuffle(RNG)}), or made in some other way. If you
-     * already have an ordering and want to make a different ordering that can undo the change, you can use
-     * {@link squidpony.GwtCompatibility#invertOrdering(int[])} called on the original ordering.
-     * @param ordering an int array or vararg that should contain each int from 0 to {@link #size()} (or less)
-     * @return this for chaining
-     */
-    public K2V1<A, B, Q> reorder(int... ordering)
-    {
-        keys.reorder(ordering);
-        GwtCompatibility.reorder(values, ordering);
-        return this;
-    }
-
-    /**
-     * Generates a random ordering with rng and applies the same ordering to all keys and values this has; they will
-     * maintain their current association to other keys and values but their ordering/indices will change.
-     * @param rng an RNG to produce the random ordering this will use
-     * @return this for chaining
-     */
-    public K2V1<A, B, Q> shuffle(RNG rng)
-    {
-        int[] ordering = rng.randomOrdering(keys.keysA.size);
-        keys.reorder(ordering);
-        GwtCompatibility.reorder(values, ordering);
-        return this;
-    }
-    /**
-     * Creates a new iterator over the A keys this holds. This can be problematic for garbage collection if called very
-     * frequently; it may be better to access items by index (which also lets you access other keys associated with that
-     * index) using {@link #getAAt(int)} in a for(int i=0...) loop.
-     * @return a newly-created iterator over this K2V1's A keys
-     */
-    public Iterator<A> iteratorA()
-    {
-        return keys.iteratorA();
-    }
-
-    /**
-     * Creates a new iterator over the B keys this holds. This can be problematic for garbage collection if called very
-     * frequently; it may be better to access items by index (which also lets you access other keys associated with that
-     * index) using {@link #getBAt(int)} in a for(int i=0...) loop.
-     * @return a newly-created iterator over this K2V1's B keys
-     */
-    public Iterator<B> iteratorB()
-    {
-        return keys.iteratorB();
-    }
-
-    /**
-     * Creates a new iterator over the Q values this holds. This can be problematic for garbage collection if called
-     * very frequently; it may be better to access values by index (which also lets you access other keys associated
-     * with that index) using {@link #getQAt(int)} in a for(int i=0...) loop.
-     * @return a newly-created iterator over this K2V1's Q values
-     */
-    public Iterator<Q> iteratorQ()
-    {
-        return values.iterator();
-    }
-
-    /**
-     * Gets and caches the A keys as a Collection that implements SortedSet (and so also implements Set). It retains the
-     * current ordering.
-     * @return the A keys as a SortedSet
-     */
-    public SortedSet<A> getSetA()
-    {
-        return keys.getSetA();
-    }
-
-    /**
-     * Gets and caches the B keys as a Collection that implements SortedSet (and so also implements Set). It retains the
-     * current ordering.
-     * @return the B keys as a SortedSet
-     */
-    public SortedSet<B> getSetB()
-    {
-        return keys.getSetB();
-    }
-
-    /**
-     * Gets the Q values as a freshly-copied ArrayList of Q; unlike {@link #getSetA()} or {@link #getSetB()}, this does
-     * not cache the value list. It retains the current ordering.
-     * @return the Q values as an ArrayList
-     */
-    public ArrayList<Q> getListQ()
-    {
-        return new ArrayList<>(values);
-    }
-
-    /**
-     * Gets the size of this collection. That's the number of A keys, which is always the same as the number of B keys,
-     * which is always the same as the number of indices, which is also always the same as the size of the values List.
-     * @return the current number of indices in this K2V1, which can be thought of as the number of A keys
-     */
-    public int size()
-    {
-        return keys.keysA.size;
-    }
-
-    /**
-     * I think you can guess what this does.
-     * @return true if there are no items in this K2V1; false if there are items present
-     */
-    public boolean isEmpty()
-    {
-        return values.isEmpty();
-    }
-
-    public int keyCount() {
-        return 2;
-    }
-    public int valueCount() {
-        return 1;
-    }
-
-}

+ 0 - 392
squidlib-util/src/main/java/squidpony/squidmath/LongPeriodRNG.java

@@ -1,392 +0,0 @@
-package squidpony.squidmath;
-
-import squidpony.StringKit;
-
-import java.util.Arrays;
-
-/**
- * An RNG that has a drastically longer period than the other generators in SquidLib, other than MersenneTwister,
- * without sacrificing speed or HTML target compatibility. If you don't already know what the period of an RNG is, this
- * probably isn't needed for your purposes, or many purposes in games at all. It is primarily meant for applications
- * that need to generate massive amounts of random numbers, more than pow(2, 64) (18,446,744,073,709,551,616), without
- * repeating sequences of generated numbers. An RNG's period refers to the number of numbers it generates given a single
- * seed before the sequence repeats from the beginning. The period of this class is pow(2, 1024) minus 1
- * (179,769,313,486,231,590,772,930,519,078,902,473,361,797,697,894,230,657,273,430,081,157,732,675,805,500,963,132,708,
- * 477,322,407,536,021,120,113,879,871,393,357,658,789,768,814,416,622,492,847,430,639,474,124,377,767,893,424,865,485,
- * 276,302,219,601,246,094,119,453,082,952,085,005,768,838,150,682,342,462,881,473,913,110,540,827,237,163,350,510,684,
- * 586,298,239,947,245,938,479,716,304,835,356,329,624,224,137,215).
- * This class may be particularly useful in conjunction with the shuffle method of RNG; the period of an RNG determines
- * how many possible "shuffles", a.k.a orderings or permutations, can be produced over all calls to a permuting method
- * like shuffle. A LightRNG-backed RNG with a period of pow(2, 64) will only be able to produce all possible "shuffles"
- * for lists or arrays of 20 items or less. If a LongPeriodRNG is given to the constructor of an RNG and a large enough
- * state has been given to the LongPeriodRNG (the String or long[] constructors can allow this), then lists or arrays of up
- * to 170 elements can have all possible orderings produced by shuffle(), though it will take near-impossibly-many calls.
- * This class has 128 bytes of state plus more in overhead (compare to the 16-byte-with-overhead LightRNG), but due to
- * its massive period and createMany() static method, you can create a large number of subsequences with rather long
- * periods themselves from a single seed. This uses the xorshift-1024* algorithm, and has competitive speed.
- * Created by Tommy Ettinger on 3/21/2016.
- * Ported from CC0-licensed C code by Sebastiano Vigna, at http://xorshift.di.unimi.it/xorshift1024star.c
- */
-public class LongPeriodRNG implements RandomnessSource {
-
-    public long[] state = new long[16];
-    public int choice;
-    private static final long serialVersionUID = 163524490381383244L;
-    private static final long jumpTable[] = {0x84242f96eca9c41dL,
-            0xa3c65b8776f96855L, 0x5b34a39f070b5837L, 0x4489affce4f31a1eL,
-            0x2ffeeb0a48316f40L, 0xdc2d9891fe68c022L, 0x3659132bb12fea70L,
-            0xaac17d8efa43cab8L, 0xc4cb815590989b13L, 0x5ee975283d71c93bL,
-            0x691548c86c1bd540L, 0x7910c41d10a1e6a5L, 0x0b5fc64563b3e2a8L,
-            0x047f7684e9fc949dL, 0xb99181f2d8f685caL, 0x284600e3f30e38c3L
-    };
-
-    /**
-     * Builds a LongPeriodRNG and initializes this class' 1024 bits of state with a random seed passed into SplitMix64,
-     * the algorithm also used by LightRNG. A different algorithm is used in non-constructor code to generate random
-     * numbers, which is a recommended technique to generate seeds.
-     */
-    public LongPeriodRNG() {
-        reseed();
-    }
-
-    /**
-     * Builds a LongPeriodRNG and initializes this class' 1024 bits of state with many calls to a SplitMix64-based RNG
-     * with a random seed influenced by Math.random() and also the time (in milliseconds to keep GWT compatibility),
-     * mixing Math.random() calls in to alter the SplitMix64 state at uneven intervals.
-     * @param seed a 64-bit seed; can be any value.
-     */
-    public LongPeriodRNG(long seed) {
-        reseed(seed);
-    }
-
-    public void reseed()
-    {
-        LightRNG lr = new LightRNG(System.currentTimeMillis() ^
-                (Double.doubleToLongBits(Math.random()) << 32) |
-                (Double.doubleToLongBits(Math.random()) & 0xffffffffL));
-        long ts = lr.nextLong() ^ lr.nextLong() ^ lr.nextLong();
-        if (ts == 0)
-            ts++;
-        choice = (int) (ts & 15);
-        state[0] = ts;
-        for (int i = 1; i < 16; i++) {
-            //Chosen by trial and error to unevenly reseed 4 times, where i is 2, 5, 10, or 13
-            if((6 & (i * 1281783497376652987L)) == 6)
-                lr.state ^= (Double.doubleToLongBits(Math.random()) << 32) |
-                    (Double.doubleToLongBits(Math.random()) & 0xffffffffL);
-            state[i] = lr.nextLong() ^ lr.nextLong() ^ lr.nextLong();
-            state[i - 1] ^= state[i];
-            if(state[i - 1] == 0) state[i - 1]++;
-        }
-    }
-    /**
-     * Reinitializes this class' 1024 bits of state with the given seed passed into SplitMix64, the algorithm also used by
-     * LightRNG. A different algorithm is used in actual number generating code, which is a recommended technique to
-     * generate seeds.
-     *
-     * @param seed a 64-bit seed; can be any value.
-     */
-    public void reseed(long seed) {
-        state = init(seed);
-        choice = (int) (seed & 15);
-    }
-    /**
-     * Builds a LongPeriodRNG and initializes this class' 1024 bits of state with the given seed, using a different
-     * strategy depending on the seed. If seed is null, this uses the same state as any other null seed. If seed is a
-     * String with length 15 or less, this generates a 64-bit hash of the seed and uses it in the same way the constructor
-     * that takes a long creates 1024 bits of state from a 64-bit seed. If seed is a String with length 16 or more, this
-     * splits the string up and generates 16 hashes from progressively smaller substrings of seed. The highest quality
-     * states will result from passing this a very long String.
-     *
-     * @param seed a String seed; can be any value, but produces the best results if it at least 16 characters long
-     */
-    public LongPeriodRNG(String seed) {
-        reseed(seed);
-    }
-
-    /**
-     * Reinitializes this class' 1024 bits of state with the given seed, using a different strategy depending on the seed.
-     * If seed is null, this uses the same state as any other null seed. If seed is a String with length 15 or less, this
-     * generates a 64-bit hash of the seed and uses it in the same way the constructor that takes a long creates 1024 bits
-     * of state from a 64-bit seed. If seed is a String with length 16 or more, this splits the string up and generates 16
-     * hashes from progressively smaller substrings of seed. The highest quality states will result from passing this a
-     * very long String.
-     *
-     * @param seed a String seed; can be any value, but produces the best results if it at least 16 characters long
-     */
-    public void reseed(String seed)
-    {
-        if (seed == null) {
-            state = new long[]{0x0101, 0x1212, 0x2323, 0x3434, 0x4545, 0x5656, 0x6767, 0x7878,
-                    0x8989, 0x9A9A, 0xABAB, 0xBCBC, 0xCDCD, 0xDEDE, 0xEFEF, 0xF0F0};
-            choice = 0;
-        } else {
-            int len = seed.length();
-            if (len < 16) {
-                long h = CrossHash.hash64(seed);
-                state = init(h);
-                choice = (int) (h & 15);
-            } else {
-                char[] chars = seed.toCharArray();
-                state = new long[]
-                        {
-                                validate(CrossHash.hash64(chars)),
-                                validate(CrossHash.hash64(chars, len / 16, len)),
-                                validate(CrossHash.hash64(chars, 2 * len / 16, len)),
-                                validate(CrossHash.hash64(chars, 3 * len / 16, len)),
-                                validate(CrossHash.hash64(chars, 4 * len / 16, len)),
-                                validate(CrossHash.hash64(chars, 5 * len / 16, len)),
-                                validate(CrossHash.hash64(chars, 6 * len / 16, len)),
-                                validate(CrossHash.hash64(chars, 7 * len / 16, len)),
-                                validate(CrossHash.hash64(chars, 8 * len / 16, len)),
-                                validate(CrossHash.hash64(chars, 9 * len / 16, len)),
-                                validate(CrossHash.hash64(chars, 10 * len / 16, len)),
-                                validate(CrossHash.hash64(chars, 11 * len / 16, len)),
-                                validate(CrossHash.hash64(chars, 12 * len / 16, len)),
-                                validate(CrossHash.hash64(chars, 13 * len / 16, len)),
-                                validate(CrossHash.hash64(chars, 14 * len / 16, len)),
-                                validate(CrossHash.hash64(chars, 15 * len / 16, len)),
-                        };
-                choice = (int) (state[0] & 15);
-            }
-        }
-    }
-    /**
-     * Builds a LongPeriodRNG and initializes this class' 1024 bits of state with the given seed as a long array, which
-     * may or may not have 16 elements (though it is less wasteful to run this with 16 longs since that is exactly 1024
-     * bits). If seed is null, this produces the same state as the String constructor does when given a null seed. If seed
-     * has fewer than 16 elements, this repeats earlier elements once it runs out of unused longs. If seed has 16 or more
-     * elements, this exclusive-ors elements after the sixteenth with longs it has already placed into the state, causing
-     * all elements of the seed to have an effect on the state, and making the 16-element case copy all longs exactly.
-     * @param seed a long array seed; can have any number of elements, though 16 is ideal
-     */
-    public LongPeriodRNG(long[] seed) {
-        reseed(seed);
-    }
-
-    /**
-     * Reinitializes this class' 1024 bits of state with the given seed as a long array, which may or may not have 16
-     * elements (though it is less wasteful to run this with 16 longs since that is exactly 1024 bits). If seed is null,
-     * this produces the same state as the String constructor does when given a null seed. If seed has fewer than 16
-     * elements, this repeats earlier elements once it runs out of unused longs. If seed has 16 or more elements, this
-     * exclusive-ors elements after the sixteenth with longs it has already placed into the state, causing all elements of
-     * the seed to have an effect on the state, and making the 16-element case copy all longs exactly.
-     * @param seed a long array seed; can have any number of elements, though 16 is ideal
-     */
-    public void reseed(long[] seed)
-    {
-        if (seed == null || seed.length == 0) {
-            state = new long[]{0x0101, 0x1212, 0x2323, 0x3434, 0x4545, 0x5656, 0x6767, 0x7878,
-                    0x8989, 0x9A9A, 0xABAB, 0xBCBC, 0xCDCD, 0xDEDE, 0xEFEF, 0xF0F0};
-            choice = 0;
-        } else if(seed.length < 16)
-        {
-            for (int i = 0, s = 0; i < 16; i++, s = (s+1) % seed.length) {
-                state[i] = seed[s];
-                if(state[i] == 0) state[i]++;
-            }
-            choice = (int) (state[0] & 15);
-        }
-        else
-        {
-            for (int i = 0, s = 0; s < seed.length; s++, i = (i+1) % 16) {
-                state[i] ^= seed[s];
-                if(state[i] == 0) state[i]++;
-            }
-            choice = (int) (state[0] & 15);
-        }
-    }
-
-    private static long validate(long seed)
-    {
-        if(seed == 0) return 1;
-        else return seed;
-    }
-    private static long[] init(long seed)
-    {
-        long[] state = new long[16];
-        for (int i = 0; i < 16; i++) {
-            long z = seed += 0x9E3779B97F4A7C15L;
-            z = (z ^ (z >>> 30)) * 0xBF58476D1CE4E5B9L;
-            z = (z ^ (z >>> 27)) * 0x94D049BB133111EBL;
-            state[i] = z ^ (z >>> 31);
-            if(state[i] == 0) state[i]++;
-        }
-        return state;
-    }
-    public LongPeriodRNG(LongPeriodRNG other)
-    {
-        choice = other.choice;
-        System.arraycopy(other.state, 0, state, 0, 16);
-    }
-
-    @Override
-    public int next( int bits ) {
-        return (int)( nextLong() & ( 1L << bits ) - 1 );
-    }
-
-    /**
-     * Can return any long, positive or negative, of any size permissible in a 64-bit signed integer.
-     * <br>
-     * Written by Sebastiano Vigna, from http://xorshift.di.unimi.it/xorshift1024star.c
-     * @return any long, all 64 bits are random
-     */
-    @Override
-    public long nextLong() {
-        final long s0 = state[choice];
-        long s1 = state[choice = (choice + 1) & 15];
-        s1 ^= s1 << 31; // a
-        state[choice] = s1 ^ s0 ^ (s1 >>> 11) ^ (s0 >>> 30); // b,c
-        return state[choice] * 1181783497276652981L;
-    }
-
-    /**
-     * Produces a copy of this RandomnessSource that, if next() and/or nextLong() are called on this object and the
-     * copy, both will generate the same sequence of random numbers from the point copy() was called. This just need to
-     * copy the state so it isn't shared, usually, and produce a new value with the same exact state.
-     *
-     * @return a copy of this RandomnessSource
-     */
-    @Override
-    public RandomnessSource copy() {
-        LongPeriodRNG next = new LongPeriodRNG();
-        System.arraycopy(state, 0, next.state, 0, 16);
-        next.choice = choice;
-        return next;
-
-    }
-
-    /**
-     * This is the jump function for the generator. It is equivalent to 2^512 calls to nextLong(); it can be used to
-     * generate 2^512 non-overlapping subsequences for parallel computations. Alters the state of this object.
-     * <br>
-     * Written by Sebastiano Vigna, from http://xorshift.di.unimi.it/xorshift1024star.c , don't ask how it works.
-     * */
-    public void jump() {
-
-        long[] t = new long[16];
-        for(int i = 0; i < 16; i++)
-        for(int b = 0; b < 64; b++) {
-            if ((jumpTable[i] & 1L << b) != 0) {
-                for (int j = 0; j < 16; j++)
-                    t[j] ^= state[(j + choice) & 15];
-            }
-            nextLong();
-        }
-
-        for(int j = 0; j < 16; j++)
-            state[(j + choice) & 15] = t[j];
-    }
-
-    /**
-     * Creates many LongPeriodRNG objects in an array, where each will generate a sequence of 2 to the 512 numbers that
-     * will not overlap with other sequences in the array. The number of items in the array is specified by count.
-     * @param count the number of LongPeriodRNG objects to generate in the array.
-     * @return an array of LongPeriodRNG where none of the RNGs will generate overlapping sequences.
-     */
-    public static LongPeriodRNG[] createMany(int count)
-    {
-        if(count < 1) count = 1;
-        LongPeriodRNG origin = new LongPeriodRNG();
-        LongPeriodRNG[] values = new LongPeriodRNG[count];
-        for (int i = 0; i < count; i++) {
-            values[i] = new LongPeriodRNG(origin);
-            origin.jump();
-        }
-        return values;
-    }
-
-    /**
-     * Creates many LongPeriodRNG objects in an array, where each will generate a sequence of pow(2, 512) numbers that
-     * will not overlap with other sequences in the array. The number of items in the array is specified by count. A
-     * seed can be given that will affect all items in the array, but with each item using a different section of the
-     * massive period this class supports. Essentially, each LongPeriodRNG in the array will generate a different random
-     * sequence relative to any other element of the array, but the sequences are reproducible if the same seed is given
-     * to this method a different time (useful for testing).
-     * @param count the number of LongPeriodRNG objects to generate in the array.
-     * @param seed the RNG seed that will determine the different sequences the returned LongPeriodRNG objects produce
-     * @return an array of LongPeriodRNG where none of the RNGs will generate overlapping sequences.
-     */
-    public static LongPeriodRNG[] createMany(int count, long seed)
-    {
-        if(count < 1) count = 1;
-        LongPeriodRNG origin = new LongPeriodRNG(seed);
-        LongPeriodRNG[] values = new LongPeriodRNG[count];
-        for (int i = 0; i < count; i++) {
-            values[i] = new LongPeriodRNG(origin);
-            origin.jump();
-        }
-        return values;
-    }
-
-    /**
-     * Creates many LongPeriodRNG objects in an array, where each will generate a sequence of pow(2, 512) numbers that
-     * will not overlap with other sequences in the array. The number of items in the array is specified by count. A
-     * seed can be given that will affect all items in the array, but with each item using a different section of the
-     * massive period this class supports. Essentially, each LongPeriodRNG in the array will generate a different random
-     * sequence relative to any other element of the array, but the sequences are reproducible if the same seed is given
-     * to this method a different time (useful for testing).
-     * @param count the number of LongPeriodRNG objects to generate in the array.
-     * @param seed the RNG seed that will determine the different sequences the returned LongPeriodRNG objects produce
-     * @return an array of LongPeriodRNG where none of the RNGs will generate overlapping sequences.
-     */
-    public static LongPeriodRNG[] createMany(int count, String seed)
-    {
-        if(count < 1) count = 1;
-        LongPeriodRNG origin = new LongPeriodRNG(seed);
-        LongPeriodRNG[] values = new LongPeriodRNG[count];
-        for (int i = 0; i < count; i++) {
-            values[i] = new LongPeriodRNG(origin);
-            origin.jump();
-        }
-        return values;
-    }
-
-    /**
-     * Creates many LongPeriodRNG objects in an array, where each will generate a sequence of pow(2, 512) numbers that
-     * will not overlap with other sequences in the array. The number of items in the array is specified by count. A
-     * seed can be given that will affect all items in the array, but with each item using a different section of the
-     * massive period this class supports. Essentially, each LongPeriodRNG in the array will generate a different random
-     * sequence relative to any other element of the array, but the sequences are reproducible if the same seed is given
-     * to this method a different time (useful for testing).
-     * @param count the number of LongPeriodRNG objects to generate in the array.
-     * @param seed the RNG seed that will determine the different sequences the returned LongPeriodRNG objects produce
-     * @return an array of LongPeriodRNG where none of the RNGs will generate overlapping sequences.
-     */
-    public static LongPeriodRNG[] createMany(int count, long[] seed)
-    {
-        if(count < 1) count = 1;
-        LongPeriodRNG origin = new LongPeriodRNG(seed);
-        LongPeriodRNG[] values = new LongPeriodRNG[count];
-        for (int i = 0; i < count; i++) {
-            values[i] = new LongPeriodRNG(origin);
-            origin.jump();
-        }
-        return values;
-    }
-
-
-    @Override
-    public String toString() {
-        return "LongPeriodRNG with state hash 0x" + StringKit.hexHash(state) + "L, choice 0x" + StringKit.hex(choice);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        LongPeriodRNG that = (LongPeriodRNG) o;
-
-        if (choice != that.choice) return false;
-        return Arrays.equals(state, that.state);
-
-    }
-
-    @Override
-    public int hashCode() {
-        int result = CrossHash.Lightning.hash(state);
-        result = 31 * result + choice;
-        return result;
-    }
-}

+ 0 - 496
squidlib-util/src/main/java/squidpony/squidmath/MerlinNoise.java

@@ -1,496 +0,0 @@
-package squidpony.squidmath;
-
-import squidpony.annotation.Beta;
-
-/**
- * Simple somewhat-continuous noise functions that use int coordinates instead of the traditional double (this approach
- * works better on a grid). It's called this because it should be possible to replace PerlinNoise with MerlinNoise, and
- * because working with noise functions makes me feel like a wizard.
- */
-@Beta
-public class MerlinNoise {
-
-    private MerlinNoise() {
-
-    }
-
-    /*
-    public static int rawNoise2D(int a, int b) {
-        //final int mx = x * 17 ^ ((x ^ 11) + (y ^ 13)), my = y * 29 ^ (7 + x + y),
-        int out = -1;
-        //final int alpha = (a + b) * 17 + (a * 19 + b * 23) * 29, beta = (a * b) * 11 + (a * 41 ^ b * 31) * 37;
-        for (int x = (a ^ 0x7C15) * 0x7F4A - 4; x <= (a ^ 0x7C15) * 0x7F4A + 4; x++) {
-            for (int y = (b ^ 0x79B9) * 0x9E37 - 4; y <= (b ^ 0x79B9) * 0x9E37 + 4; y++) {
-                //final int
-                //        gx = x ^ (x >>> 1), gy = y ^ (y >>> 1),
-                //        z = gx + gy, w = gx ^ -gy,
-                //        gz = z ^ (z >>> 1), gw = w ^ (w >>> 1),
-                //        p = ~gx & gw + gz * gy, q = gw * gz ^ ~gy - gx,
-                //        gp = p ^ (p >>> 1), gq = q ^ (q >>> 1);
-                out += (x >>> 2 & 7) + (y >>> 2 & 7) - ((x + y) >>> 3 & 3);
-            }
-        }
-        //mx = (x * 127 ^ y * 113) ^ (x * 131 + y * 119), my = (x * 119 ^ y * 127) ^ (x * 113 + y * 131),
-        //final int mx = (x ^ y) * 0x7C15 + (y + x) * 0x9E37, my = (y ^ x) * 0xA47F ^ (x + y) * 0x79B9,
-        //gx = mx ^ (x >> 1), gy = my ^ (y >> 1),
-        //sx = (x + 16) >> 1, sy = (y + 16) >> 1,
-        //mx = x * 127 + (x >> 1) * 353 ^ (31 + (x << 1) - y), my = y * 131 + (y >> 1) * 301 ^ (37 + (y << 1) - x),
-        //out = ((sx * sy * mx * my) >>> 8 & 0x1ff); //((Integer.bitCount(gx) + Integer.bitCount(gy) & 63) << 3) ^
-        out &= 0x1ff;
-        return ((out & 0x100) != 0) ? ~out & 0xff : out & 0xff;
-    }
-    */
-
-    /*
-    public static int rawNoise2D(int x, int y) {
-        //final int mx = x * 17 ^ ((x ^ 11) + (y ^ 13)), my = y * 29 ^ (7 + x + y),
-        final int
-                gx = x ^ (x >>> 1), gy = y ^ (y >>> 1),
-                z = gx + gy, w = gx ^ -gy,
-                gz = z ^ (z >>> 1), gw = w ^ (w >>> 1),
-                p = ~gx & gw * gx + gz * gy, q = gz * gw ^ ~gy - gx,
-                gp = p ^ (p >>> 1), gq = q ^ (q >>> 1),
-                //gcz = Long.bitCount(gz * 0x9E3779B97F4A7C15L), gcw = Long.bitCount(gw * 0x9E3779B97F4A7C15L),
-                //gcp = Long.bitCount(gp * 0x9E3779B97F4A7C15L), gcq = Long.bitCount(gq * 0x9E3779B97F4A7C15L),
-                //mx = (x * 127 ^ y * 113) ^ (x * 131 + y * 119), my = (x * 119 ^ y * 127) ^ (x * 113 + y * 131),
-                //final int mx = (x ^ y) * 0x7C15 + (y + x) * 0x9E37, my = (y ^ x) * 0xA47F ^ (x + y) * 0x79B9,
-                //gx = mx ^ (x >> 1), gy = my ^ (y >> 1),
-                //sx = (x + 16) >> 1, sy = (y + 16) >> 1,
-                //mx = x * 127 + (x >> 1) * 353 ^ (31 + (x << 1) - y), my = y * 131 + (y >> 1) * 301 ^ (37 + (y << 1) - x),
-                //out = ((sx * sy * mx * my) >>> 8 & 0x1ff); //((Integer.bitCount(gx) + Integer.bitCount(gy) & 63) << 3) ^
-                out = ((gz * 19) ^ (gw * 11) ^ (gp * 13) ^ (gq * 17)) & 0x1ff;
-        return ((out & 0x100) != 0) ? ~out & 0xff : out & 0xff;
-    }*/
-
-    public static int rawNoise2D(final int x, final int y) {
-        return ((x * 0x9E3779B9 ^ 0xC6BC2796) * (y * 0x92B5CC83 + 0xD9B4E019) - (x ^ ~y) * 0x632BE59B * (~x + y) * 0x7F4A7C15) >>> 8 & 0xff;
-    }
-
-    public static int rawNoise3D(final int x, final int y, final int z) {
-        return (((z * 0xD0E89D2D + 0x311E289F) ^ x * 0x9E3779B9 ^ 0xC6BC2796 ^ (y * 0x92B5CC83 + 0xD9B4E019)) +
-                //(z * 0xD0E89D2D ^ x * 0xC6BC2796 ^ y * 0x92B5CC83 ^
-                (x ^ ~y + z) * 0x632BE59B + (z ^ ~x + y) * 0x7F4A7C15 + (y ^ ~z + x) * 0x9E3779B9) >>> 8 & 0xff; //0x311E289F
-    }
-    public static int rawNoise2D_alt(final int x, final int y) {
-
-        int s,
-                result = (s = 0x632BE5AB ^ x * 0x85157AF5) + 0xC5C5581A // equal to 0x62E2AC0D + 0x62E2AC0D
-                        + (s ^= y * 0xA1687A2F);
-        return (result ^ ((s ^ result) >>> 8) * 0x9E3779B9) >>> 24;
-    }
-    public static int rawNoise3D_alt(final int x, final int y, final int z) {
-
-        int s,
-                result = (s = 0x632BE5AB ^ x * 0x85157AF5) + 0x28A80427 // equal to 0x62E2AC0D + 0x62E2AC0D + 0x62E2AC0D
-                        + (s ^= y * 0x92B5CC85)
-                        + (s ^= z * 0xA1687A2F); //0x7F4A7C1F
-        return (result ^ ((s ^ result) >>> 8) * 0x9E3779B9) & 255; // >>> 24
-    }
-    /**
-     * 2D merlin noise.
-     *
-     * @param x x input
-     * @param y y input
-     * @return noise from 0 to 255, inclusive
-     */
-    public static int noise2D(int x, int y) {
-        return (rawNoise2D(x - 1, y - 1) & 43) + (rawNoise2D(x - 1, y + 1) & 43) +
-                (rawNoise2D(x + 1, y - 1) & 43) + (rawNoise2D(x + 1, y + 1) & 43) +
-                (rawNoise2D(x - 1, y) & 53) + (rawNoise2D(x + 1, y) & 53) +
-                (rawNoise2D(x, y - 1) & 53) + (rawNoise2D(x, y - 1) & 53) +
-                (rawNoise2D(x, y) & 127) >>> 1;
-    }/**
-     * 2D merlin noise.
-     *
-     * @param x x input
-     * @param y y input
-     * @return noise from 0 to 255, inclusive
-     */
-    public static int noise2D_alt(int x, int y) {
-        return
-
-                (rawNoise2D_alt(x - 1, y + 1) + rawNoise2D_alt(x + 1, y + 1) +
-                rawNoise2D_alt(x + 1, y - 1) + rawNoise2D_alt(x - 1, y - 1) +
-                rawNoise2D_alt(x - 1, y) + rawNoise2D_alt(x + 1, y) +
-                rawNoise2D_alt(x, y - 1) + rawNoise2D_alt(x, y - 1)) * 3
-                + (rawNoise2D_alt(x, y) << 3) >>> 5;
-    }
-
-    /**
-     * 3D merlin noise.
-     *
-     * @param x x input
-     * @param y y input
-     * @param z z input
-     * @return noise from 0 to 255, inclusive
-     */
-    public static int noise3D(int x, int y, int z) {
-        /*return (rawNoise3D(x-1,y-1,z-1) & 12) + (rawNoise3D(x-1,y+1,z-1) & 12) +
-                (rawNoise3D(x+1,y-1,z-1) & 12) + (rawNoise3D(x+1,y+1,z-1) & 12) +
-                (rawNoise3D(x-1,y-1,z+1) & 12) + (rawNoise3D(x-1,y+1,z+1) & 12) +
-                (rawNoise3D(x+1,y-1,z+1) & 12) + (rawNoise3D(x+1,y+1,z+1) & 12) +
-
-                (rawNoise3D(x-1,y-1,z) & 25) + (rawNoise3D(x+1,y-1,z) & 25) +
-                (rawNoise3D(x-1,y+1,z) & 25) + (rawNoise3D(x+1,y+1,z) & 25) +
-                (rawNoise3D(x-1,y,z-1) & 25) + (rawNoise3D(x+1,y,z-1) & 25) +
-                (rawNoise3D(x-1,y,z+1) & 25) + (rawNoise3D(x+1,y,z+1) & 25) +
-                (rawNoise3D(x,y-1,z-1) & 25) + (rawNoise3D(x,y+1,z-1) & 25) +
-                (rawNoise3D(x,y-1,z+1) & 25) + (rawNoise3D(x,y+1,z+1) & 25) +
-
-                (rawNoise3D(x-1,y,z) & 62) + (rawNoise3D(x+1,y,z) & 62) +
-                (rawNoise3D(x,y-1,z) & 62) + (rawNoise3D(x,y+1,z) & 62) +
-                (rawNoise3D(x,y,z-1) & 62) + (rawNoise3D(x,y,z+1) & 62) +
-                */
-        return  (rawNoise3D(x - 1, y, z) & 55) + (rawNoise3D(x + 1, y, z) & 55) +
-                (rawNoise3D(x, y - 1, z) & 55) + (rawNoise3D(x, y + 1, z) & 55) +
-                (rawNoise3D(x, y, z - 1) & 55) + (rawNoise3D(x, y, z + 1) & 55) +
-
-                (rawNoise3D(x, y, z) & 181) >>> 1;
-    }
-    public static int noiseBalanced3D(int x, int y, int z) {
-        return  rawNoise3D(x - 1, y, z) + rawNoise3D(x + 1, y, z) +
-                rawNoise3D(x, y - 1, z) + rawNoise3D(x, y + 1, z) +
-                rawNoise3D(x, y, z - 1) + rawNoise3D(x, y, z + 1) +
-                (rawNoise3D(x, y, z) << 1) >>> 3;
-    }
-    public static int noiseBalanced3D_alt(int x, int y, int z) {
-        return  rawNoise3D_alt(x - 1, y, z) + rawNoise3D_alt(x + 1, y, z) +
-                rawNoise3D_alt(x, y - 1, z) + rawNoise3D_alt(x, y + 1, z) +
-                rawNoise3D_alt(x, y, z - 1) + rawNoise3D_alt(x, y, z + 1) +
-                /*
-                (rawNoise3D_alt(x - 1, y - 1, z) + rawNoise3D_alt(x + 1, y - 1, z) +
-                rawNoise3D_alt(x, y - 1, z - 1) + rawNoise3D_alt(x, y + 1, z - 1) +
-                rawNoise3D_alt(x - 1, y, z - 1) + rawNoise3D_alt(x - 1, y, z + 1) +
-                rawNoise3D_alt(x - 1, y + 1, z) + rawNoise3D_alt(x + 1, y + 1, z) +
-                rawNoise3D_alt(x, y - 1, z + 1) + rawNoise3D_alt(x, y + 1, z + 1) +
-                rawNoise3D_alt(x + 1, y, z - 1) + rawNoise3D_alt(x + 1, y, z + 1) << 4) +
-                */
-                (rawNoise3D_alt(x, y, z) << 1);
-    }
-                        /*(
-                                cellA * (0.5 + absA - absB) +// * (1 - aCoreBias) +
-                                cellB * (0.5 + absB - absA)// * (1 - bCoreBias) +
-                             //   cellAr * aCoreBias + cellBr * bCoreBias
-                        ) * (mx)
-                        */
-                                        /*(cellAB * cornerPref * 2.0 +
-                        cellA * (1.0 + absA - absB - cornerPref) * (1 - aCoreBias) +
-                        cellB * (1.0 + absB - absA - cornerPref) * (1 - bCoreBias) +
-                        cellAr * (1.0 - cornerPref) * aCoreBias + cellBr * bCoreBias * (1.0 - cornerPref)
-                ) * mx * 0.5
-                */
-/*
-                (cellAB * cornerPref * 2.0 +
-                                cellA * (1.0 + absA - absB - cornerPref) * (1 - aCoreBias) +
-                                cellB * (1.0 + absB - absA - cornerPref) * (1 - bCoreBias) +
-                                cellAr * (1.0 - cornerPref) * aCoreBias + cellBr * bCoreBias * (1.0 - cornerPref)
-                        ) * mx * 0.5
-                */
-                /*
-                                cellA * (0.5 + absA - absB - cornerPref) +
-                                cellB * (0.5 + absB - absA - cornerPref)) * mx
-
-                 */
-
-    /**
-     * 2D merlin noise with a zoom factor.
-     *
-     * @param x    x input
-     * @param y    y input
-     * @param zoom if greater than 1.0, will make the details of the noise larger; if less, will make them smaller
-     * @return noise from 0 to 255, inclusive
-     */
-    /*
-    public static int noise2D(int x, int y, double zoom) {
-        final double alef = x / (zoom * 8.0), bet = y / (zoom * 8.0);
-        final int alpha = (int) ((x >> 3) / zoom), beta = (int) ((y >> 3) / zoom);
-        final double aBias = (alef - alpha), bBias = (bet - beta),
-                absA = Math.abs(aBias - 0.5), absB = Math.abs(bBias - 0.5),
-                //cornerPref = 0.5 * (absA + absB),
-                cornerPref = Math.max(absA + absB - 0.5, 0) * 0.5,
-                mx = (Math.max(absA, absB))// * 0.5 + (absA + absB) * 0.5),
-                //aCoreBias = Math.max(0.25 - absA, 0), bCoreBias = Math.max(0.25 - absB, 0)
-                ;
-        final int aCond = (aBias < 0.5 ? -1 : 1), bCond = (bBias < 0.5 ? -1 : 1),
-                centerCell = rawNoise2D(alpha, beta),
-                cellA = rawNoise2D(alpha + aCond, beta),
-                cellB = rawNoise2D(alpha, beta + bCond),
-                cellAr = rawNoise2D(alpha - aCond, beta),
-                cellBr = rawNoise2D(alpha, beta - bCond),
-                //cellAB   = (rawNoise2D(alpha + aCond, beta + bCond) + (cellA + cellB)) / 3;
-                //cellArB  = (rawNoise2D(alpha - aCond, beta + bCond) * 6 + (cellAr + cellB) * 5) >> 4,
-                //cellABr  = (rawNoise2D(alpha + aCond, beta - bCond) * 6 + (cellA + cellBr) * 5) >> 4,
-                //cellArBr = (rawNoise2D(alpha - aCond, beta - bCond) * 6 + (cellAr + cellBr) * 5) >> 4;
-        return (int)(((centerCell)// * (1 - aCoreBias - bCoreBias) + cellAr * aCoreBias + cellBr * bCoreBias)
-                * (1 - mx) +
-                ((absA > absB) ? cellA * (1.4 + (absA - absB)) + cellB * (0.6 - (absA - absB)) :
-                        cellB * (1.4 + (absB - absA)) + cellA * (0.6 - (absB - absA))) * mx * 0.5)
-        );
-    }*/
-    public static int noise2D(int x, int y, int zoom) {
-        if (zoom < 1)
-            return 0;
-        int v = 0, a = x << 1, b = y << 1;
-        for (int s = zoom; s > 0; s--) {
-            v += noise2D((a += 379) / s, (b += 379) / s) + noise2D(a / s, (b + 1) / s) + noise2D((a + 1) / s, b / s);
-        }
-        //return v / zoom;
-        /*
-        double adj = Math.sin((v / (zoom * 1530.0)) * Math.PI);
-        return (int)(adj * adj * 255.5);
-        */
-        double adj = Math.sin((v / (zoom * 1530.0)) * Math.PI);
-        adj *= adj;
-        return (int) (Math.pow(adj, 2.0 - 2.0 * adj) * 255.5);
-    }
-    public static int noise2D_alt(final int x, final int y, final int zoom) {
-        if (zoom < 1)
-            return 0;
-        int v = 0, a = x, b = y, t = 0, m;
-        for (int s = zoom, u = 1; s > 0; s--, u++) {
-            v += ((m = noise2D_alt((a += 76379) >>> s, (b += 76379) >>> s))
-                    + noise2D_alt((a+(m&2)-1) >>> s, (b+((m&1)<<1)-1) >>> s)
-            ) << u;
-            t += 1 << u;
-        }
-        return lookup[(v / (t << 1))];
-    }
-    public static int noise2D_emphasized(final int x, final int y, final int zoom) {
-        if (zoom < 1)
-            return 0;
-        int v = 0, a = x, b = y, t = 0, m;
-        for (int s = zoom, u = 1; s > 0; s--, u++) {
-            v += ((m = noise2D_alt((a += 76379) >>> s, (b += 76379) >>> s))
-                    + noise2D_alt((a+(m&2)-1) >>> s, (b+((m&1)<<1)-1) >>> s)
-            ) << u;
-            t += 1 << u;
-        }
-        return lookup_extreme[(v / (t << 1))];
-    }
-    public static int noise3D(int x, int y, int z, int zoom) {
-        if (zoom < 1)
-            return 0;
-        int v = 0, a = x, b = y, c = z, t = 0;
-        for (int s = zoom, u = zoom; s > 0; s--, u++) {
-            v += (noiseBalanced3D((a += 379) / s, (b += 379) / s, (c += 379) / s) + noiseBalanced3D((a+1) / s, (b+1) / s, (c+1) / s)) * u;
-            t += u;
-        }
-        //v += noise3D((a+(v&1)) / s, (b+(v>>1&1)) / s, (c+(v>>2&1)) / s) +
-        //        noise3D((a-(v>>3&1)) / s, (b-(v>>4&1)) / s, (c-(v>>5&1)) / s);
-        //v += t + noise3D((a + (t & 3)) / s, (b + (t >> 2 & 3)) / s, (c + (t >> 4 & 3)) / s);
-        //+ noise3D((a - (t >> 3 & 1)) / s, (b - (t >> 4 & 1)) / s, (c - (t >> 5 & 1)) / s);
-                    /*
-                    + noise3D((a) / s, (b+1) / s, (c) / s)
-                    + noise3D((a+1) / s, (b) / s, (c) / s)
-                    + noise3D((a) / s, (b) / s, (c+1) / s);*/
-        //v += noise3D((a+(v&3)) / s, (b+(v>>2&3)) / s, (c+(v>>4&3)) / s);
-
-        //return v / zoom;
-        /*
-        double adj = Math.sin((v / (zoom * 1530.0)) * Math.PI);
-        return (int)(adj * adj * 255.5);
-        */
-
-        double adj = Math.sin((v / (1020.0 * t)) * Math.PI);
-        //return (int)(adj * adj * 255.5);
-        adj *= adj;
-        return (int) (Math.pow(adj, 2.0 - 2.0 * adj) * 255.5);
-    }
-
-    private static final int[] lookup_extreme = {
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
-            1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11,
-            11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 25, 26, 27, 29,
-            30, 31, 33, 35, 36, 38, 40, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59,
-            61, 63, 65, 68, 70, 72, 75, 77, 79, 82, 84, 87, 89, 92, 94, 97, 100,
-            102, 105, 108, 110, 113, 115, 118, 121, 123, 126, 129, 132, 134, 137,
-            139, 142, 145, 147, 150, 153, 155, 158, 160, 163, 165, 168, 170, 172,
-            175, 177, 179, 182, 184, 186, 188, 191, 193, 195, 197, 199, 201, 203,
-            205, 206, 208, 210, 212, 213, 215, 217, 218, 220, 221, 223, 224, 225,
-            227, 228, 229, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
-            241, 242, 243, 244, 244, 245, 246, 246, 247, 247, 248, 248, 249, 249,
-            250, 250, 251, 251, 251, 252, 252, 252, 253, 253, 253, 253, 253, 254,
-            254, 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 256, 255, 255,
-            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-            255, 255, 255, 255, 254, 254, 254, 254, 254, 254, 253, 253, 253, 253,
-            253, 252, 252, 252, 251, 251, 251, 250, 250, 249, 249, 248, 248, 247,
-            247, 246, 246, 245, 244, 244, 243, 242, 241, 241, 240, 239, 238, 237,
-            236, 235, 234, 233, 232, 231, 229, 228, 227, 225, 224, 223, 221, 220,
-            218, 217, 215, 213, 212, 210, 208, 206, 205, 203, 201, 199, 197, 195,
-            193, 191, 188, 186, 184, 182, 179, 177, 175, 172, 170, 168, 165, 163,
-            160, 158, 155, 153, 150, 147, 145, 142, 139, 137, 134, 132, 129, 126,
-            123, 121, 118, 115, 113, 110, 108, 105, 102, 100, 97, 94, 92, 89, 87,
-            84, 82, 79, 77, 75, 72, 70, 68, 65, 63, 61, 59, 57, 55, 53, 51, 49,
-            47, 45, 43, 41, 40, 38, 36, 35, 33, 31, 30, 29, 27, 26, 25, 23, 22,
-            21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 11, 10, 9, 9, 8, 7, 7, 6,
-            6, 5, 5, 5, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-            },
-            lookup = {
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3,
-            4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11, 12, 13, 13, 14, 15,
-            15, 16, 17, 18, 19, 20, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
-            31, 32, 33, 34, 35, 36, 37, 38, 40, 41, 42, 43, 44, 45, 47, 48, 49,
-            50, 52, 53, 54, 55, 57, 58, 59, 61, 62, 63, 65, 66, 68, 69, 70, 72,
-            73, 75, 76, 78, 79, 81, 82, 83, 85, 86, 88, 89, 91, 92, 94, 96, 97,
-            99, 100, 102, 103, 105, 106, 108, 109, 111, 113, 114, 116, 117, 119,
-            120, 122, 124, 125, 127, 128, 130, 131, 133, 135, 136, 138, 139, 141,
-            142, 144, 146, 147, 149, 150, 152, 153, 155, 156, 158, 159, 161, 163,
-            164, 166, 167, 169, 170, 172, 173, 174, 176, 177, 179, 180, 182, 183,
-            185, 186, 187, 189, 190, 191, 193, 194, 196, 197, 198, 200, 201, 202,
-            203, 205, 206, 207, 208, 210, 211, 212, 213, 214, 215, 217, 218, 219,
-            220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233,
-            234, 235, 235, 236, 237, 238, 239, 240, 240, 241, 242, 242, 243, 244,
-            244, 245, 246, 246, 247, 247, 248, 248, 249, 249, 250, 250, 251, 251,
-            252, 252, 252, 253, 253, 253, 254, 254, 254, 254, 255, 255, 255, 255,
-            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-            255, 255, 255, 254, 254, 254, 254, 253, 253, 253, 252, 252, 252, 251,
-            251, 250, 250, 249, 249, 248, 248, 247, 247, 246, 246, 245, 244, 244,
-            243, 242, 242, 241, 240, 240, 239, 238, 237, 236, 235, 235, 234, 233,
-            232, 231, 230, 229, 228, 227, 226, 225, 224, 223, 222, 221, 220, 219,
-            218, 217, 215, 214, 213, 212, 211, 210, 208, 207, 206, 205, 203, 202,
-            201, 200, 198, 197, 196, 194, 193, 191, 190, 189, 187, 186, 185, 183,
-            182, 180, 179, 177, 176, 174, 173, 172, 170, 169, 167, 166, 164, 163,
-            161, 159, 158, 156, 155, 153, 152, 150, 149, 147, 146, 144, 142, 141,
-            139, 138, 136, 135, 133, 131, 130, 128, 127, 125, 124, 122, 120, 119,
-            117, 116, 114, 113, 111, 109, 108, 106, 105, 103, 102, 100, 99, 97,
-            96, 94, 92, 91, 89, 88, 86, 85, 83, 82, 81, 79, 78, 76, 75, 73, 72,
-            70, 69, 68, 66, 65, 63, 62, 61, 59, 58, 57, 55, 54, 53, 52, 50, 49,
-            48, 47, 45, 44, 43, 42, 41, 40, 38, 37, 36, 35, 34, 33, 32, 31, 30,
-            29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 20, 19, 18, 17, 16, 15, 15,
-            14, 13, 13, 12, 11, 11, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3,
-            3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-            };
-
-    public static int noise3D_alt(final int x, final int y, final int z, final int zoom) {
-        if (zoom < 1)
-            return 0;
-        int v = 0, a = x, b = y, c = z, t = 0, m;
-        for (int s = zoom, u = 1; s > 0; s--, u++) {
-            v += ((m = noiseBalanced3D_alt((a += 76379) >>> s, (b += 76379) >>> s, (c += 76379) >>> s)) * 5
-                    + noiseBalanced3D_alt((a+((m&2))-1) >>> s, (b+((m&1)<<1)-1) >>> s, (c+((m&4)>>>1)-1) >>> s) * 3
-                    >>> 5
-                    //+ (noiseBalanced3D_alt((a+((m&2048)>>>10)-1) >>> s, (b+((m&4096)>>>11)-1) >>> s, (c+((m&8192)>>>12)-1) >>> s) & 127)
-            ) << u;
-            t += 2 << u;
-        }
-        return lookup[v / t];
-    }
-    public static int noise3D_emphasized(final int x, final int y, final int z, final int zoom) {
-        if (zoom < 1)
-            return 0;
-        int v = 0, a = x, b = y, c = z, t = 0, m;
-        for (int s = zoom, u = 1; s > 0; s--, u++) {
-            v += ((m = noiseBalanced3D_alt((a += 76379) >>> s, (b += 76379) >>> s, (c += 76379) >>> s)) * 5
-                    + noiseBalanced3D_alt((a+((m&2))-1) >>> s, (b+((m&1)<<1)-1) >>> s, (c+((m&4)>>>1)-1) >>> s) * 3
-                    >>> 5
-            /*
-            v += (((m = noiseBalanced3D_alt((a += 76379) >>> s, (b += 76379) >>> s, (c += 76379) >>> s)) & 255)
-                    + (noiseBalanced3D_alt((a+((m&2))-1) >>> s, (b+((m&4)>>>1)-1) >>> s, (c+((m&8)>>>2)-1) >>> s) & 255)
-                    */
-                    //+ (noiseBalanced3D_alt((a+((m&2048)>>>10)-1) >>> s, (b+((m&4096)>>>11)-1) >>> s, (c+((m&8192)>>>12)-1) >>> s) & 127)
-            ) << u;
-            t += 2 << u;
-        }
-        return lookup_extreme[v / t];
-    }
-
-    /*
-    public static int noise2D(int x, int y, double zoom) {
-        final double alef = x / (zoom * 8.0), bet = y / (zoom * 8.0);
-        final int alpha = (int) ((x >> 3) / zoom), beta = (int) ((y >> 3) / zoom);
-        final double aBias = (alef - alpha), bBias = (bet - beta),
-                absA = Math.abs(aBias - 0.5), absB = Math.abs(bBias - 0.5),
-                cornerPref = Math.max(absA + absB - 0.5, 0),
-                mx = Math.max(absA, absB) * 3.6 + (absA + absB) * 4.2;
-        final int centerCell = rawNoise2D(alpha, beta),
-                aCell = rawNoise2D(alpha + (aBias < 0.5 ? -1 : 1), beta),
-                bCell = rawNoise2D(alpha, beta + (bBias < 0.5 ? -1 : 1)),
-                cornerCell = (rawNoise2D(alpha + (aBias < 0.5 ? -1 : 1), beta + (bBias < 0.5 ? -1 : 1)) * 6 + (aCell + bCell) * 5) >> 4;
-        return (int) ( //(centerCell * (1 - absA - absB) + aCell * absA + bCell * absB)
-                centerCell * (8 - mx) +
-                        (cornerCell * cornerPref * 2.0 +
-                                aCell * (0.5 + absA - absB - cornerPref) +
-                                bCell * (0.5 + absB - absA - cornerPref)) * mx
-        ) >>> 3;
-    }
-    */
-
-    /**
-     * Generates higher-quality continuous-style noise than the other methods, but requires pre-calculating a grid.
-     * Does allow taking a seed because internally it uses a ThunderRNG to quickly generate initial white noise before
-     * processing it into more continuous noise. This generates a lot of random numbers (at least 1 + 14 * height, or
-     * more if width is greater than 64), so ThunderRNG's high speed and presumed higher-than-2-to-the-64 period are
-     * both assets here.
-     * <br>
-     * The 2D int array this produces has ints ranging from 1 to 255, with extreme values very unlikely. Because 0 is
-     * impossible for this to generate, it should be fine to use values from this as denominators in division.
-     *
-     * @param width  the width of the 2D int array to generate
-     * @param height the height of the 2D int array to generate
-     * @param seed   the RNG seed to use when pseudo-randomly generating the initial white noise this then processes
-     * @return a 2D int array where each int should be between 1 and 255, inclusive
-     */
-    public static int[][] preCalcNoise2D(int width, int height, long seed) {
-        ThunderRNG random = new ThunderRNG(seed);
-        int w = (width << 1) + 2, h = (height << 1) + 2;
-        GreasedRegion[] regions = new GreasedRegion[]{
-                new GreasedRegion(random, w, h).retract().expand(3), new GreasedRegion(random, w, h).retract().expand(3),
-                new GreasedRegion(random, w, h).retract().expand(3), new GreasedRegion(random, w, h).retract().expand(3),
-                new GreasedRegion(random, w, h).retract().expand(3), new GreasedRegion(random, w, h).retract().expand(3),
-                new GreasedRegion(random, w, h).retract().expand(3)
-        };
-        random.reseed(random.nextLong());
-        int[][] data = GreasedRegion.bitSum(regions);
-
-        regions = new GreasedRegion[]{
-                new GreasedRegion(random, w, h).retract().expand(3), new GreasedRegion(random, w, h).retract().expand(3),
-                new GreasedRegion(random, w, h).retract().expand(3), new GreasedRegion(random, w, h).retract().expand(3),
-                new GreasedRegion(random, w, h).retract().expand(3), new GreasedRegion(random, w, h).retract().expand(3),
-                new GreasedRegion(random, w, h).retract().expand(3)
-        };
-        int[][] data2 = GreasedRegion.bitSum(regions), data3 = new int[width][height];
-        for (int x = 0; x < w; x++) {
-            for (int y = 0; y < h; y++) {
-                data[x][y] += 128 - data2[x][y];
-            }
-        }
-        for (int x = 0, dx = 1; x < width; x++, dx += 2) {
-            for (int y = 0, dy = 1; y < height; y++, dy += 2) {
-                data3[x][y] = ((data[dx][dy] << 2) + data[dx - 1][dy] + data[dx + 1][dy] + data[dx][dy + 1] + data[dx][dy - 1]) >>> 3;
-            }
-        }
-        return data3;
-        /*
-        int[][] data = GreasedRegion.bitSum(regions);
-        return GreasedRegion.selectiveNegate(data, new GreasedRegion(random, width, height), 0xff);
-        */
-    }
-
-
-    /*
-    public static int noise2D(int x, int y, double zoom) {
-        final double alef = x / zoom, bet = y / zoom;
-        final int alpha = (int) (alef), beta = (int) (bet),
-                north = rawNoise2D(alpha, beta - 1), south = rawNoise2D(alpha, beta + 1),
-                east = rawNoise2D(alpha + 1, beta), west = rawNoise2D(alpha - 1, beta),
-                center = rawNoise2D(alpha, beta);
-        final double aBias = (alef - alpha), bBias = (bet - beta);
-        return (((aBias - 0.75) < 0 ? west : center) * 3 + ((aBias + 0.75) >= 1 ? east : center) * 3 +
-                ((aBias - 0.25) < 0 ? west : center) * 2 + ((aBias + 0.25) >= 1 ? east : center) * 2 +
-                ((bBias - 0.75) < 0 ? north : center) * 3 + ((bBias + 0.75) >= 1 ? south : center) * 3 +
-                ((bBias - 0.25) < 0 ? north : center) * 2 + ((bBias + 0.25) >= 1 ? south : center) * 2
-        ) / 20;
-    }*/
-                    /*+
-                ((aBias - 0.5) < 0 ? west : center) * 17 + ((aBias + 0.5) >= 1 ? east : center) * 17 +
-                ((aBias - 0.3) < 0 ? west : center) * 15 + ((aBias + 0.3) >= 1 ? east : center) * 15 +
-                ((bBias - 0.5) < 0 ? north : center) * 17 + ((bBias + 0.5) >= 1 ? south : center) * 17 +
-                ((bBias - 0.3) < 0 ? north : center) * 15 + ((bBias + 0.3) >= 1 ? south : center) * 15*/
-
-}

+ 0 - 252
squidlib-util/src/main/java/squidpony/squidmath/ThunderRNG.java

@@ -1,252 +0,0 @@
-package squidpony.squidmath;
-
-import squidpony.StringKit;
-import squidpony.annotation.Beta;
-
-import java.io.Serializable;
-
-/**
- * Like LightRNG, but shares a lot in common with CrossHash's hashing mechanism. The name comes from its
- * similarity to the nickname for that hash, Lightning, but also to how the current version acts like LightRNG,
- * sort-of, but involves a thunder-like "echo" where the earlier results are used as additional state for the
- * next result. Why should you consider it? It appears to be the fastest RandomnessSource we have available,
- * and is the only RNG in the library that can generate 1 billion random long values in under 1 second (or
- * rather, under 900 ms) on an Intel i7-4700MQ laptop processor (second-fastest RandomnessSource depends on
- * other factors, but is effectively a tie between LightRNG and XoRoRNG at roughly 1200 ms on the same laptop).
- * Any layer on top of generating long values slows this down, which is the case for most of the
- * RandomnessSource implementations, but ThunderRNG's {@link #nextInt()} method, which gets the most
- * significant 32 bits of a random long and returns them as an int, is also the fastest way we have to generate
- * int values. This does not implement StatefulRandomness because it stores state in two parts, each a long;
- * each is incremented by a different addend with each number generated. Part B is always odd, and is
- * incremented by a large, empirically-chosen number that is even; because odd + even = odd, always, part B
- * never becomes even. Part A is always incremented by an irregular selection of the bits in Part B, but the
- * selection never causes the increment to be by an even number (this also means it never increments by 0).
- * This irregular increment seems to increase ThunderRNG's period, but by how much is not clear.
- * <br>
- * The reason why nextInt() uses only the most significant half of the bits, even though it requires a shift in
- * addition to a cast, is because the period of the less significant bits is lower, though by how much isn't
- * clear. One early test used a 512x512 pixel window with a call to ThunderRNG's next() method for each pixel
- * (2 to the 18 calls per render), getting only two bits at time (yes, this is wasteful and a bad idea in
- * practice). Though the seed wasn't being reset each frame, the generated 2-bit values were effectively
- * identical between frames (adding one additional call to next() made the random sections move predictably
- * along one axis, one pixel at a time, which indicates they would be the same values every frame if the extra
- * call was removed). The early version that had this likely flaw always took the lowest bits, here the lowest
- * two bits, in next(), but changing next() to use the same number of bits from higher in the random long
- * eliminated this issue. Calls to nextLong() should still be expected to have a lower-than-normal period for
- * the low bits, with the bottom 2 bits likely having a period of 4096 or less. The period of the full 64
- * bits is unknown at this time, but is probably higher than 2 to the 64, and is almost certainly at least 2 to
- * the 63 (which is the probable period of Part B on its own, and because Part A changes every time by a
- * random-seeming, non-zero subset of Part B where the LSB is always set, the final result can't have a lower
- * period than Part B).
- * <br>
- * The tool used for testing this RNG is PractRand, http://pracrand.sourceforge.net/ > The binaries it provides
- * don't seem to work as intended on Windows, so I built from source, generated 64MB files of random 64-bit
- * output with various generators as "Thunder.dat", "Light.dat" and so on, then ran the executables I had
- * built with the MS compilers, with the command line {@code RNG_test.exe stdin64 < Thunder.dat} . For most of
- * the other generators I tried, there were no or nearly-no statistical failures it could find, and as of the (second)
- * commit on August 31, ThunderRNG also has no statistical failures or even anomalies. Earlier versions were
- * slightly faster (at best speed, 600-700ms) but had multiple outright failures (the fastest ones failed the
- * majority of tests).
- * <br>
- * Created by Tommy Ettinger on 8/23/2016.
- */
-@Beta
-public class ThunderRNG implements RandomnessSource, Serializable {
-    private static final long serialVersionUID = 3L;
-
-    /** The state can be seeded with any value. */
-    public long state;
-    protected long jumble;
-    /** Creates a new generator seeded using Math.random. */
-    public ThunderRNG() {
-        this((long) (Math.random() * Integer.MAX_VALUE) << 32 | (int)(Math.random() * Integer.MAX_VALUE));
-    }
-
-    /**
-     * Creates a new generator given only 64 bits of state, and uses that to fill out 127 bits of less-random state.
-     * @param seed any long; 0 is permitted
-     */
-    public ThunderRNG( final long seed ) {
-        state = (seed + bitPermute(seed + 0xC6BC279692B5CC83L)) * 0x9E3779B97F4A7C15L + 0x632BE59BD9B4E019L;
-        jumble = (state + bitPermute(state + 0x9E3779B97F4A7C15L)) * 0xC6BC279692B5CC83L + 0x632BE59BD9B4E019L | 1L;
-        state += jumble & (jumble += 0xAB79B96DCD7FE75EL);
-    }
-
-    /**
-     * Creates a new generator using exactly the values of partA and partB for this ThunderRNG's two-part state, with
-     * the exception that the least significant bit of partB will always be set to 1.
-     * @param partA any long; all 64 bits will be used
-     * @param partB any long; the most significant 63 bits will be used and the "1's place" bit will be disregarded
-     */
-    public ThunderRNG(final long partA, final long partB)
-    {
-        state = partA;
-        jumble = partB | 1L;
-    }
-
-    /**
-     * Not needed for external use, but it may be handy in code that needs to alter a long in some random-seeming way.
-     * Passing 0 to this yields 0. May actually change the number of set bits, so it isn't quite a permutation in the
-     * normal way of thinking about it.
-     * @param p a number that should have its bits permuted, as a long
-     * @return a permuted-bits version of p, as a long
-     */
-    public static long bitPermute(long p)
-    {
-        p ^= p >>> (5 + (p >>> 59));
-        p *= 0xAEF17502108EF2D9L;
-        return p ^ (p >>> 43);
-    }
-
-    @Override
-    public int next( int bits ) {
-        //return (int)( nextLong() & ( 1L << bits ) - 1 );
-        return (int)( nextLong() >>> (64 - bits) );
-    }
-
-    /**
-     * Can return any long, positive or negative, of any size permissible in a 64-bit signed integer.
-     * @return any long, all 64 bits are random
-     */
-    @Override
-    public long nextLong() {
-        //return ((state << 4L) + 0xC6BC279692B5CC83L) * ((state += 0x9E3779B97F4A7C15L) >>> 5) + 0x632BE59BD9B4E019L;
-        //return 0xD0E89D2D311E289FL * ((state += 0x9E3779B97F4A7C15L) >> 18L); //very fast
-        //return ((state *= 0x9E3779B97F4A7C15L) * (++state >>> 7));
-        //return ((((state += 0x9E3779B97F4A7C15L) >> 13) * 0xD0E89D2D311E289FL) >> 9) * 0xC6BC279692B5CC83L;
-        //return ((state += 0x9E3779B97F4A7C15L) >> 16) * 0xD0E89D2D311E289FL;
-        //return state * ((state += 0x9E3779B97F4A7C15L) >> 5) * 0xD0E89D2D311E289FL;
-        //return ((state += 0x9E3779B97F4A7C15L) >> (state >>> 60L)) * 0xD0E89D2D311E289FL;
-        //return (state * 0xD0E89D2D311E289FL) ^ (state += 0x9E3779B97F4A7C15L);
-        //return ((state >> 5) * 0xC6BC279692B5CC83L) ^ (state += 0x9E3779B97F4A7C15L);
-        //return ((state += 0x9E3779B97F4A7C15L) >>> (state >>> 60L)) * 0x632BE59BD9B4E019L; //pretty good quality
-        //return 0xC6BC279692B5CC83L * (lag ^= 0xD0E89D2D311E289FL * ((state += 0x9E3779B97F4A7C15L) >> 18L));
-        //return lag += 0xC6BC279692B5CC83L * ((state += 0x9E3779B97F4A7C15L) * 2862933555777941757L + 7046029254386353087L);
-        //return (lag += (state += 0x9E3779B97F4A7C15L) & 0xDF5DFFDADFE8FFFFL) * 2862933555777941757L + 7046029254386353087L;
-        //return (lag += ((state += 0x9E3779B97F4A7C15L) >> 3) & 0xDF5DFFDADFE8FFFFL) * 2862933555777941757L + 7046029254386353087L;
-        //return state ^ ((state += 0x9E3779B97F4A7C15L) >> 18) * 0xC6BC279692B5CC83L;
-        //return (state >> 18) * 0xC6BC279692B5CC83L + (state += 0x9E3779B97F4A7C15L);
-        //return (state ^ ((state += 0x9E3779B97F4A7C15L) >> 18)) * 0xC6BC279692B5CC83L; // former best
-        //return (state ^ ((state += jumble) >> 17)) * (jumble += 0x8D784F2D256B9906L);
-        //return (state ^ ((state ^= jumble) >> 17)) * (jumble += 0xC6BC279692B5CC83L);
-        //return (state ^ ((state += jumble) >> 17)) * (jumble += 0x8D784F2D256B9906L);
-        //return state ^ 0xC6BC279692B5CC83L * ((state += jumble & (jumble += 0xBC6EF372FEB7FC6AL)) >> 16); //known excellent
-        //return state ^ 0xC6BC279692B5CC83L * ((state += jumble & (jumble += 0x3779B97F57FF375EL)) >> 25);
-        //BEST KNOWN
-        return state ^ (0x9E3779B97F4A7C15L * ((state += jumble & (jumble += 0xAB79B96DCD7FE75EL)) >> 20));
-
-        //return ((state >> 4) * 0x9E3779B97F4A7C15L ^ (state += 0xBC6756B4A5B16C57L));
-        //return ((state >> 16) * 0x9E3779B97F4A7C15L ^ (state += 0xC6BC279692B5CC83L));
-        //return state ^ (((state += 0xC6BC279692B5CC83L) >> 12) * 0x9E3779B97F4A7C15L);
-        //return (state += ((jumble += 0xD0E89D2D311E289FL) >> 28) * 0xC6BC279692B5CC83L) * 0x9E3779B97F4A7C15L;
-
-        //return state = state * 2862933555777941757L + 7046029254386353087L; // LCG for comparison
-    }
-
-    public int nextInt()
-    {
-        return (int)(nextLong() >>> 32);
-    }
-    /**
-     * This returns a maximum of 0.9999999999999999 because that is the largest
-     * Double value that is less than 1.0
-     *
-     * @return a value between 0 (inclusive) and 0.9999999999999999 (inclusive)
-     */
-    public double nextDouble() {
-        return Double.longBitsToDouble(0x3FFL << 52 | nextLong() >>> 12) - 1.0;
-    }
-
-    /**
-     * Get "Part A" of the current internal state of the ThunderRNG as a long. Reconstituting the state of this
-     * ThunderRNG requires Part A (given by this) and Part B (given by {@link #getStatePartB()})
-     *
-     * @return part A of the current internal state of this object.
-     */
-    public long getStatePartA() {
-        return state;
-    }
-
-    /**
-     * Get "Part A" of the current internal state of the ThunderRNG as a long. Reconstituting the state of this
-     * ThunderRNG requires Part A (given by {@link #getStatePartA()}) and Part B (given by this).
-     *
-     * @return part B of the current internal state of this object.
-     */
-    public long getStatePartB() {
-        return jumble;
-    }
-
-    /**
-     * Set the current internal state of this ThunderRNG with two long parts, often obtained using the previous
-     * state of another ThunderRNG using {@link #getStatePartA()} and {@link #getStatePartB()}, but any values
-     * are allowed for both parts. Only the upper 63 bits are used of partB; the bottom bit of partB is always
-     * changed to 1 internally so the RNG works as intended.
-     *
-     * @param partA any 64-bit long
-     * @param partB any 64-bit long, but the least significant bit will be ignored (e.g. 2 and 3 are identical)
-     */
-    public void setState(long partA, long partB) {
-        state = partA;
-        jumble = partB | 1L;
-    }
-
-    /**
-     * Replicates the behavior of the constructor that takes one long, and sets both parts of the state to what that
-     * constructor would assign given the same seed.
-     * @param seed any long
-     */
-    public void reseed( final long seed ) {
-        state = (seed + bitPermute(seed + 0xC6BC279692B5CC83L)) * 0x9E3779B97F4A7C15L + 0x632BE59BD9B4E019L;
-        jumble = (state + bitPermute(state + 0x9E3779B97F4A7C15L)) * 0xC6BC279692B5CC83L + 0x632BE59BD9B4E019L | 1L;
-        state += jumble & (jumble += 0xAB79B96DCD7FE75EL);
-        /*
-        jumble = (seed ^ ((seed + 0x9E3779B97F4A7C15L) >> 18)) * 0xC6BC279692B5CC83L;
-        jumble ^= (((seed + 0x9E3779B97F4A7C15L) ^ ((seed + 0x9E3779B97F4A7C15L + 0x9E3779B97F4A7C15L) >> 18)) * 0xC6BC279692B5CC83L) >>> 32;
-        jumble |= 1L;
-        */
-    }
-
-    /**
-     * Produces a copy of this RandomnessSource that, if next() and/or nextLong() are called on this object and the
-     * copy, both will generate the same sequence of random numbers from the point copy() was called. This just needs to
-     * copy the state so it isn't shared, usually, and produces a new value with the same exact state.
-     *
-     * @return a copy of this RandomnessSource
-     */
-    @Override
-    public RandomnessSource copy() {
-        return new ThunderRNG(state, jumble);
-    }
-
-    @Override
-    public String toString() {
-        return "ThunderRNG with state parts A=0x" + StringKit.hex(state) + "L, B=0x"  + StringKit.hex(jumble)+ 'L';
-    }
-
-    public static long determine(final int x)
-    {
-        long a = ((x ^ 0xC6BC279692B5CC83L) << 16) ^ x, b = (((x ^ 0x632BE59BD9B4E019L) << 16) ^ x) | 1L;
-        a += b & (b += 0xAB79B96DCD7FE75EL);
-        return a ^ (0x9E3779B97F4A7C15L * ((a + b & (b + 0xAB79B96DCD7FE75EL)) >> 20));
-    }
-
-    public static long determine(final int x, final int y)
-    {
-        long a = ((x ^ 0xC6BC279692B5CC83L) << 16) ^ x, b = (((y ^ 0x632BE59BD9B4E019L) << 16) ^ y) | 1L;
-        a += b & (b += 0xAB79B96DCD7FE75EL);
-        return a ^ (0x9E3779B97F4A7C15L * ((a + b & (b + 0xAB79B96DCD7FE75EL)) >> 20));
-    }
-    public static long determine(final int x, final int y, final int z)
-    {
-        long a = ((x ^ 0xC6BC279692B5CC83L) << 16) ^ (z + y), b = (((y ^ 0x632BE59BD9B4E019L) << 16) ^ (z + x)) | 1L;
-        a += b & (b += 0xAB79B96DCD7FE75EL);
-        return a ^ (0x9E3779B97F4A7C15L * ((a + b & (b + 0xAB79B96DCD7FE75EL)) >> 20));
-    }
-    public static long determine(final int x, final int y, final int z, final int w)
-    {
-        long a = (((x + z) ^ 0xC6BC279692B5CC83L) << 16) ^ (z + y), b = ((((y + w) ^ 0x632BE59BD9B4E019L) << 16) ^ (w + x)) | 1L;
-        a += b & (b += 0xAB79B96DCD7FE75EL);
-        return a ^ (0x9E3779B97F4A7C15L * ((a + b & (b + 0xAB79B96DCD7FE75EL)) >> 20));
-    }
-}

+ 0 - 172
squidlib-util/src/main/java/squidpony/squidmath/XoRoRNG.java

@@ -1,172 +0,0 @@
-/*  Written in 2016 by David Blackman and Sebastiano Vigna (vigna@acm.org)
-
-To the extent possible under law, the author has dedicated all copyright
-and related and neighboring rights to this software to the public domain
-worldwide. This software is distributed without any warranty.
-
-See <http://creativecommons.org/publicdomain/zero/1.0/>. */
-package squidpony.squidmath;
-
-import squidpony.StringKit;
-
-/**
- * A port of Blackman and Vigna's xoroshiro 128+ generator; should be very fast and produce high-quality output.
- * Testing shows it is within 5% the speed of LightRNG, sometimes faster and sometimes slower, and has a larger period.
- * It's called XoRo because it involves Xor as well as Rotate operations on the 128-bit pseudo-random state.
- * Original version at http://xoroshiro.di.unimi.it/xoroshiro128plus.c
- * Written in 2016 by David Blackman and Sebastiano Vigna (vigna@acm.org)
- * @author Sebastiano Vigna
- * @author David Blackman
- * @author Tommy Ettinger
- */
-public class XoRoRNG implements RandomnessSource {
-
-	private static final long DOUBLE_MASK = (1L << 53) - 1;
-    private static final double NORM_53 = 1. / (1L << 53);
-    private static final long FLOAT_MASK = (1L << 24) - 1;
-    private static final double NORM_24 = 1. / (1L << 24);
-
-	private static final long serialVersionUID = 1018744536171610261L;
-
-    private long state0, state1;
-
-    /**
-     * Creates a new generator seeded using Math.random.
-     */
-    public XoRoRNG() {
-        this((long) (Math.random() * Long.MAX_VALUE));
-    }
-
-    public XoRoRNG(final long seed) {
-        setSeed(seed);
-    }
-
-    @Override
-    public int next(int bits) {
-        return (int) (nextLong() & (1L << bits) - 1);
-    }
-
-    @Override
-    public long nextLong() {
-        final long s0 = state0;
-        long s1 = state1;
-        final long result = s0 + s1;
-
-        s1 ^= s0;
-        state0 = Long.rotateLeft(s0, 55) ^ s1 ^ (s1 << 14); // a, b
-        state1 = Long.rotateLeft(s1, 36); // c
-
-        return result;
-    }
-
-    /**
-     * Produces a copy of this RandomnessSource that, if next() and/or nextLong() are called on this object and the
-     * copy, both will generate the same sequence of random numbers from the point copy() was called. This just need to
-     * copy the state so it isn't shared, usually, and produce a new value with the same exact state.
-     *
-     * @return a copy of this RandomnessSource
-     */
-    @Override
-    public RandomnessSource copy() {
-        XoRoRNG next = new XoRoRNG(state0);
-        next.state0 = state0;
-        next.state1 = state1;
-        return next;
-    }
-
-
-    /**
-     * Can return any int, positive or negative, of any size permissible in a 32-bit signed integer.
-     * @return any int, all 32 bits are random
-     */
-    public int nextInt() {
-        return (int)nextLong();
-    }
-
-    /**
-     * Exclusive on the upper bound.  The lower bound is 0.
-     * @param bound the upper bound; should be positive
-     * @return a random int less than n and at least equal to 0
-     */
-    public int nextInt( final int bound ) {
-        if ( bound <= 0 ) return 0;
-        int threshold = (0x7fffffff - bound + 1) % bound;
-        for (;;) {
-            int bits = (int)(nextLong() & 0x7fffffff);
-            if (bits >= threshold)
-                return bits % 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);
-    }
-
-    /**
-     * Exclusive on the upper bound. The lower bound is 0.
-     * @param bound the upper bound; should be positive
-     * @return a random long less than n
-     */
-    public long nextLong( final long bound ) {
-        if ( bound <= 0 ) return 0;
-        long threshold = (0x7fffffffffffffffL - bound + 1) % bound;
-        for (;;) {
-            long bits = nextLong() & 0x7fffffffffffffffL;
-            if (bits >= threshold)
-                return bits % bound;
-        }
-    }
-
-    public double nextDouble() {
-        return (nextLong() & DOUBLE_MASK) * NORM_53;
-    }
-
-    public float nextFloat() {
-        return (float) ((nextLong() & FLOAT_MASK) * NORM_24);
-    }
-
-    public boolean nextBoolean() {
-        return (nextLong() & 1) != 0L;
-    }
-
-    public void nextBytes(final byte[] bytes) {
-        int i = bytes.length, n = 0;
-        while (i != 0) {
-            n = Math.min(i, 8);
-            for (long bits = nextLong(); n-- != 0; bits >>>= 8) {
-                bytes[--i] = (byte) bits;
-            }
-        }
-    }
-
-    /**
-     * Sets the seed of this generator. Passing this 0 will just set it to -1
-     * instead.
-     *
-     * @param seed the number to use as the seed
-     */
-    public void setSeed(final long seed) {
-
-        long state = seed + 0x9E3779B97F4A7C15L,
-                z = state;
-        z = (z ^ (z >>> 30)) * 0xBF58476D1CE4E5B9L;
-        z = (z ^ (z >>> 27)) * 0x94D049BB133111EBL;
-        state0 = z ^ (z >>> 31);
-        state += state0 + 0x9E3779B97F4A7C15L;
-        z = state;
-        z = (z ^ (z >>> 30)) * 0xBF58476D1CE4E5B9L;
-        z = (z ^ (z >>> 27)) * 0x94D049BB133111EBL;
-        state1 = z ^ (z >>> 31);
-    }
-
-    @Override
-    public String toString() {
-        return "XoRoRNG with state hash 0x" + StringKit.hexHash(state0, state1) + 'L';
-    }
-}

+ 0 - 144
squidlib-util/src/main/java/squidpony/squidmath/XorRNG.java

@@ -1,144 +0,0 @@
-/*
-Written in 2015 by Sebastiano Vigna (vigna@acm.org)
-
-To the extent possible under law, the author has dedicated all copyright
-and related and neighboring rights to this software to the public domain
-worldwide. This software is distributed without any warranty.
-
-See <http://creativecommons.org/publicdomain/zero/1.0/>. */
-package squidpony.squidmath;
-
-import squidpony.StringKit;
-
-/**
- * A port of Sebastiano Vigna's XorShift 128+ generator. Should be very fast and produce high-quality output.
- * Original version at http://xorshift.di.unimi.it/xorshift128plus.c
- * Written in 2015 by Sebastiano Vigna (vigna@acm.org)
- * @author Sebastiano Vigna
- * @author Tommy Ettinger
- */
-public class XorRNG implements RandomnessSource {
-
-	private static final long DOUBLE_MASK = (1L << 53) - 1;
-    private static final double NORM_53 = 1. / (1L << 53);
-    private static final long FLOAT_MASK = (1L << 24) - 1;
-    private static final double NORM_24 = 1. / (1L << 24);
-
-	private static final long serialVersionUID = 1263134736171610359L;
-
-    private long state0, state1;
-
-    /**
-     * Creates a new generator seeded using Math.random.
-     */
-    public XorRNG() {
-        this((long) (Math.random() * Long.MAX_VALUE));
-    }
-
-    public XorRNG(final long seed) {
-        setSeed(seed);
-    }
-
-    @Override
-    public int next(int bits) {
-        return (int) (nextLong() & (1L << bits) - 1);
-    }
-
-    @Override
-    public long nextLong() {
-        long s1 = state0;
-        final long s0 = state1;
-        state0 = s0;
-        s1 ^= s1 << 23; // a
-        return ( state1 = s1 ^ s0 ^ ( s1 >>> 17 ) ^ ( s0 >>> 26 )) + s0; // b, c
-    }
-
-    public int nextInt() {
-        return (int) nextLong();
-    }
-
-    public int nextInt(final int n) {
-        if (n <= 0) {
-            throw new IllegalArgumentException();
-        }
-        return (int) ((nextLong() >>> 1) % n);
-    }
-
-    public long nextLong(final long n) {
-        if (n <= 0) {
-            throw new IllegalArgumentException();
-        }
-        for (;;) {
-            final long bits = nextLong() >>> 1;
-            final long value = bits % n;
-            if (bits - value + (n - 1) >= 0) {
-                return value;
-            }
-        }
-    }
-
-    public double nextDouble() {
-        return (nextLong() & DOUBLE_MASK) * NORM_53;
-    }
-
-    public float nextFloat() {
-        return (float) ((nextLong() & FLOAT_MASK) * NORM_24);
-    }
-
-    public boolean nextBoolean() {
-        return (nextLong() & 1) != 0L;
-    }
-
-    public void nextBytes(final byte[] bytes) {
-        int i = bytes.length, n = 0;
-        while (i != 0) {
-            n = Math.min(i, 8);
-            for (long bits = nextLong(); n-- != 0; bits >>>= 8) {
-                bytes[--i] = (byte) bits;
-            }
-        }
-    }
-
-    private long avalanche ( long k )
-    {
-        k ^= k >>> 33;
-        k *= 0xff51afd7ed558ccdL;
-        k ^= k >>> 33;
-        k *= 0xc4ceb9fe1a85ec53L;
-        k ^= k >>> 33;
-
-        return k;
-    }
-
-    /**
-     * Sets the seed of this generator. Passing this 0 will just set it to -1
-     * instead.
-     *
-     * @param seed the number to use as the seed
-     */
-    public void setSeed(final long seed) {
-        state0 = avalanche(seed == 0 ? -1 : seed);
-        state1 = avalanche(state0);
-        state0 = avalanche(state1);
-    }
-
-    @Override
-    public String toString() {
-        return "XorRNG with state hash 0x" + StringKit.hexHash(state0, state1) + 'L';
-    }
-
-    /**
-     * Produces a copy of this RandomnessSource that, if next() and/or nextLong() are called on this object and the
-     * copy, both will generate the same sequence of random numbers from the point copy() was called. This just need to
-     * copy the state so it isn't shared, usually, and produce a new value with the same exact state.
-     *
-     * @return a copy of this RandomnessSource
-     */
-    @Override
-    public RandomnessSource copy() {
-        XorRNG next = new XorRNG(state0);
-        next.state0 = state0;
-        next.state1 = state1;
-        return next;
-    }
-}

+ 0 - 4
squidlib-util/src/main/java/squidpony/squidmath/package-info.java

@@ -1,4 +0,0 @@
-/**
- * A very broad package containing random number generators, geometry tools, and some classes for combinatorics.
- */
-package squidpony.squidmath;