1 /++ 2 Random number generation utils 3 +/ 4 module sily.random; 5 6 import std.math; 7 import std.random; 8 import std.algorithm.comparison; 9 import std.conv: to; 10 import std.datetime: Clock; 11 import std.traits: isFloatingPoint; 12 13 14 /++ 15 Random number generator 16 Example: 17 --- 18 // Creates rng with default seed 19 RNG rng = RNG(); 20 // Creates rng with custom seed 21 rng = RNG(2511244); 22 // Assigns random seed to seed 23 rng.randomize(); 24 // Returns random uint 25 rnd.random(); 26 // Returns random float in range of 0..float.max 27 randf(); 28 // Returns random float in rangle of 4..20 29 randf(4, 20); 30 // Returns random ulong in range of 0..ulong.max 31 rand!ulong(); 32 --- 33 +/ 34 struct RNG { 35 private uint _seed = defaultSeed; 36 private Random _rnd; 37 private ulong _calls; 38 39 /// Creates RNG with set seed 40 this(uint p_seed) { 41 _seed = p_seed; 42 _rnd = Random(_seed); 43 } 44 45 /// Randomizes seed 46 public void randomize() { 47 seed = randomSeed; 48 } 49 /// Ditto 50 alias randomise = randomize; 51 52 /// Sets custom seed `p_seed` 53 @property public void seed(uint p_seed) { 54 _seed = p_seed; 55 _rnd.seed(_seed); 56 } 57 58 /// Returns current seed 59 @property public uint seed() { return _seed; } 60 61 /// Alias to std.random default seed 62 public static alias defaultSeed = Random.defaultSeed; 63 /// Alias to std.random unpredictable seed 64 public static alias randomSeed = unpredictableSeed; 65 66 /// Typed alias to get random value between 0 and T.max or custom min and max 67 alias randf = rand!float; 68 /// Ditto 69 alias randr = rand!real; 70 /// Ditto 71 alias randd = rand!double; 72 /// Ditto 73 alias randi = rand!int; 74 /// Ditto 75 alias randl = rand!long; 76 77 template rand(T) { 78 static if(isFloatingPoint!T) { 79 /// Returns random value between 0 and T.max or custom min and max 80 T rand() { 81 return random / _rnd.max.to!T; 82 } 83 84 /// Ditto 85 T rand(T min, T max) { 86 return min + (rand!T * (max - min)); 87 } 88 } else { 89 /// Ditto 90 T rand() { 91 return (randr * T.max).to!T; 92 } 93 94 /// Ditto 95 T rand(T min, T max) { 96 return round(min + (randr * (max - min))).to!T; 97 } 98 } 99 } 100 101 /// Returns random uint 102 public uint random() { 103 uint r = _rnd.front; 104 skip(); 105 return r; 106 } 107 108 /// Skips current random value 109 public void skip() { 110 _rnd.popFront(); 111 _calls ++; 112 } 113 114 /// Skips N amount of random values 115 public void skipTo(size_t numCalls) { 116 while(_calls < numCalls) { 117 skip(); 118 } 119 } 120 } 121