001package squidpony.squidmath;
002
003/**
004 * A slight variant on RNG that always uses a stateful RandomessSource and so can have its state
005 * set or retrieved using setState() or getState().
006 * Created by Tommy Ettinger on 9/15/2015.
007 * @author Tommy Ettinger
008 */
009public class StatefulRNG extends RNG {
010
011        private static final long serialVersionUID = -2456306898212937163L;
012
013        public StatefulRNG() {
014        super(new LightRNG());
015    }
016
017    public StatefulRNG(RandomnessSource random) {
018        super((random instanceof StatefulRandomness) ? random : new LightRNG(random.nextLong()));
019    }
020
021    /**
022     * Seeded constructor uses LightRNG, which is of high quality, but low period (which rarely matters for games),
023     * and has good speed and tiny state size.
024     */
025    public StatefulRNG(long seed) {
026        this(new LightRNG(seed));
027    }
028    /**
029     * String-seeded constructor uses the hash of the String as a seed for LightRNG, which is of high quality, but low
030     * period (which rarely matters for games), and has good speed and tiny state size.
031     */
032    public StatefulRNG(String seedString) {
033        this(new LightRNG(CrossHash.hash(seedString)));
034    }
035
036    @Override
037    public void setRandomness(RandomnessSource random) {
038        super.setRandomness((random instanceof StatefulRandomness) ? random : new LightRNG(random.nextLong()));
039    }
040
041    /**
042     * Creates a copy of this StatefulRNG; it will generate the same random numbers, given the same calls in order, as
043     * this StatefulRNG at the point copy() is called. The copy will not share references with this StatefulRNG.
044     *
045     * @return a copy of this StatefulRNG
046     */
047    @Override
048    public RNG copy() {
049        return new StatefulRNG(random.copy());
050    }
051
052    /**
053     * Get a long that can be used to reproduce the sequence of random numbers this object will generate starting now.
054     * @return a long that can be used as state.
055     */
056    public long getState()
057    {
058        return ((StatefulRandomness)random).getState();
059    }
060
061    /**
062     * Sets the state of the random number generator to a given long, which will alter future random numbers this
063     * produces based on the state.
064     * @param state a long, which typically should not be 0 (some implementations may tolerate a state of 0, however).
065     */
066    public void setState(long state)
067    {
068        ((StatefulRandomness)random).setState(state);
069    }
070
071    @Override
072    public String toString() {
073        return "StatefulRNG{" + Long.toHexString(((StatefulRandomness)random).getState()) + "}";
074    }
075}