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}