using System; using System.Collections.Generic; namespace Chernobyl { /// /// A type that produces deterministic values. This is useful for testing /// code that uses randomness. /// public class NotRandom : Random { /// /// Constructor. /// /// The list of values to return when asked to produce random numbers. /// This list will be iterated through to produce the values. public NotRandom(IReadOnlyList values) { _values = values; } /// public override int Next() { var value = _values[Increment()]; return (int)value; } /// public override int Next(int maxValue) { // Search our list an appropriate value. for (int i = 0; i < _values.Count; i++) { var value = _values[Increment()]; if (value < maxValue) return (int)value; } throw new ArgumentOutOfRangeException(nameof(maxValue), maxValue, "Unable to locate a value less than the max value provided."); } /// public override int Next(int minValue, int maxValue) { minValue.Throw(nameof(minValue)).IfGreaterThanOrEqualTo(maxValue, nameof(maxValue)); // Search our list an appropriate value. for (int i = 0; i < _values.Count; i++) { var value = _values[Increment()]; if (minValue <= value && value < maxValue) return (int)value; } throw new ArgumentOutOfRangeException(nameof(maxValue), maxValue, "Unable to locate a value greater than or equal to the min value and less than the " + "max value provided."); } /// public override void NextBytes(byte[] buffer) { // TODO: implement this when needed. throw new NotImplementedException(); } /// public override double NextDouble() { return Next() / 1.0; } /// protected override double Sample() { // TODO: implement this when needed. throw new NotImplementedException(); } /// /// Returns and increments the current value. /// /// The current value before being incremented. int Increment() { int current = _currentIndex; _currentIndex++; if (_values.Count <= _currentIndex) _currentIndex = 0; return current; } readonly IReadOnlyList _values; int _currentIndex; } }