001package squidpony.squidmath; 002 003/** 004 * An interface to indicate a {@link RandomnessSource} that is intentionally flawed to create output patterns where a 005 * truly random sequence would have none. All FlawedRandomness implementations are static inner classes inside this 006 * interface, hopefully to avoid confusion with ones that are meant for general use. This implements {@link IFlawed} as 007 * well, to mark that it isn't for general-purpose use. 008 * <br> 009 * Created by Tommy Ettinger on 11/10/2019. 010 */ 011public interface FlawedRandomness extends RandomnessSource, IFlawed { 012 /** 013 * A flawed randomness source that depends almost entirely on its starting state for any random-seeming results in 014 * its output. Simply outputs a number that starts with the initial seed and increases by {@code 0x1111111111111111} 015 * each time, or {@code 1229782938247303441}. 016 */ 017 class BigCounter implements FlawedRandomness, StatefulRandomness 018 { 019 public long state; 020 021 public BigCounter() 022 { 023 this((long) ((Math.random() - 0.5) * 0x10000000000000L) 024 ^ (long) (((Math.random() - 0.5) * 2.0) * 0x8000000000000000L)); 025 } 026 public BigCounter(long state) { 027 this.state = state; 028 } 029 030 @Override 031 public long getState() { 032 return state; 033 } 034 035 @Override 036 public void setState(long state) { 037 this.state = state; 038 } 039 040 @Override 041 public int next(int bits) { 042 return (int)((state += 0x1111111111111111L) >>> 64 - bits); 043 } 044 045 @Override 046 public long nextLong() { 047 return (state += 0x1111111111111111L); 048 } 049 050 @Override 051 public BigCounter copy() { 052 return new BigCounter(state); 053 } 054 } 055 056 /** 057 * A flawed randomness source that adds a rotation of its state, to its state, every generation. The rotation amount 058 * is also determined by state. This one's probably pretty bad; I don't really know how bad it will be to a human 059 * observer, but it also depends on what cycle it starts in. The state probably shouldn't ever be 0, since this 060 * will only produce 0 after its state becomes 0. Of course, this is flawed, so it can become 0 in the course of 061 * normal generation. 062 */ 063 class AddRotate implements FlawedRandomness, StatefulRandomness 064 { 065 public long state; 066 067 public AddRotate() 068 { 069 this((long) ((Math.random() - 0.5) * 0x10000000000000L) 070 ^ (long) (((Math.random() - 0.5) * 2.0) * 0x8000000000000000L)); 071 } 072 public AddRotate(long state) { 073 this.state = state == 0 ? 1 : state; 074 } 075 076 @Override 077 public long getState() { 078 return state; 079 } 080 081 @Override 082 public void setState(long state) { 083 this.state = state == 0 ? 1 : state; 084 } 085 086 @Override 087 public int next(int bits) { 088 return (int)((state += (state << state | state >>> -state)) >>> 64 - bits); 089 } 090 091 @Override 092 public long nextLong() { 093 return (state += (state << state | state >>> -state)); 094 } 095 096 @Override 097 public AddRotate copy() { 098 return new AddRotate(state); 099 } 100 } 101}