All Downloads are FREE. Search and download functionalities are using the official Maven repository.

squidpony.squidmath.StatefulRNG Maven / Gradle / Ivy

Go to download

SquidLib platform-independent logic and utility code. Please refer to https://github.com/SquidPony/SquidLib .

There is a newer version: 3.0.6
Show newest version
package squidpony.squidmath;

import java.io.Serializable;

/**
 * A slight variant on RNG that always uses a stateful RandomessSource and so can have its state
 * set or retrieved using setState() or getState().
 * Created by Tommy Ettinger on 9/15/2015.
 * @author Tommy Ettinger
 */
public class StatefulRNG extends RNG implements Serializable, IStatefulRNG {

	private static final long serialVersionUID = -2456306898212937163L;

	public StatefulRNG() {
        super();
    }

    public StatefulRNG(RandomnessSource random) {
        super((random instanceof StatefulRandomness) ? random : new DiverRNG(random.nextLong()));
    }

    /**
     * Seeded constructor uses DiverRNG, which is of high quality, but low period (which rarely matters for games),
     * and has good speed and tiny state size.
     */
    public StatefulRNG(long seed) {
        this(new DiverRNG(seed));
    }
    /**
     * String-seeded constructor uses the hash of the String as a seed for DiverRNG, which is of high quality, but
     * low period (which rarely matters for games), and has good speed and tiny state size.
     *
     * Note: This constructor changed behavior on April 22, 2017, again on December 23, 2017, and again on June 14,
     * 2018. The first was when it was noticed that it was not seeding very effectively (only assigning to 32 bits of
     * seed instead of all 64). The older behavior isn't fully preserved, since it used a rather low-quality String
     * hashing algorithm and so probably had problems producing good starting seeds, but you can get close by replacing
     * {@code new StatefulRNG(text)} with {@code new StatefulRNG(new LightRNG(CrossHash.hash(text)))}. The new technique
     * assigns to all 64 bits and has less correlation between similar inputs causing similar starting states. It's also
     * faster, but that shouldn't matter in a constructor. It uses a better hashing algorithm because CrossHash no
     * longer has the older, worse one. The latest change in June switched to DiverRNG instead of LightRNG.
     */
    public StatefulRNG(CharSequence seedString) {
        this(new DiverRNG(CrossHash.hash64(seedString)));
    }

    @Override
    public void setRandomness(RandomnessSource random) {
        super.setRandomness(random == null ? new DiverRNG() :
                (random instanceof StatefulRandomness) ? random : new DiverRNG(random.nextLong()));
    }

    /**
     * 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 StatefulRNG copy() {
        return new StatefulRNG(random.copy());
    }

    /**
     * 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.
     */
    public long getState()
    {
        return ((StatefulRandomness)random).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).
     */
    public void setState(long state)
    {
        ((StatefulRandomness)random).setState(state);
    }

    @Override
    public String toString() {
        return "StatefulRNG{" + Long.toHexString(((StatefulRandomness)random).getState()) + "}";
    }
    /**
     * Returns this StatefulRNG in a way that can be deserialized even if only {@link IRNG}'s methods can be called.
     * @return a {@link Serializable} view of this StatefulRNG; always {@code this}
     */
    @Override
    public Serializable toSerializable() {
        return this;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy