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;
}
}