using System.Diagnostics; namespace skyscraper8.UI.MonoGame.Bridge; public class ZigguratStream : Stream { public ZigguratStream() { _ziggurat = new Ziggurat(); } public ZigguratStream(int seed) { _ziggurat = new Ziggurat(seed); } public ZigguratStream(Random random) { _ziggurat = new Ziggurat(random); } private Ziggurat _ziggurat; private double minZig, maxZig; private byte getNextByte() { double sample = _ziggurat.Sample(); double oldMin = minZig; double oldMax = maxZig; minZig = System.Math.Min(minZig, sample); maxZig = System.Math.Max(maxZig, sample); if (oldMin != minZig || oldMax != maxZig) { return getNextByte(); } sample += (minZig / -1.0); double span = (minZig / -1.0) + maxZig; double sampleScaled = sample / span; Debug.Assert(sampleScaled <= 1.0); sampleScaled *= 255.0; byte scaledByte = (byte)sampleScaled; return scaledByte; } public override void Flush() { throw new NotSupportedException(); } private long internalPosition; public override int Read(byte[] buffer, int offset, int count) { for (int i = 0; i < count; i++) { buffer[offset + i] = getNextByte(); internalPosition++; } return count; } public override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); } public override void SetLength(long value) { throw new NotSupportedException(); } public override void Write(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } public override bool CanRead => true; public override bool CanSeek => false; public override bool CanWrite => false; public override long Length => throw new NotSupportedException(); public override long Position { get => internalPosition; set => throw new NotSupportedException(); } }