Example #1
0
        public void AverageDecimals(Decimal low, Decimal high, UInt64 seed)
        {
            const Int32   iterations = 10_000;
            const Decimal sqr3       = 1.7320508075688772935274463415m;

            var populationMean = high / 2 + low / 2;
            var popStdDev      = 1.0m / sqr3 * (high / 2 - low / 2);

            var exclusiveDist = Uniform.New(low, high);
            var inclusiveDist = Uniform.NewInclusive(low, high);
            var rng           = Pcg32.Create(789 + seed, 11634580027462260723ul);

            Decimal exclusiveMean = 0;
            Decimal inclusiveMean = 0;

            for (var i = 0; i < iterations; i++)
            {
                var exclusive      = exclusiveDist.Sample(rng);
                var exclusiveDelta = exclusive - exclusiveMean;
                exclusiveMean += exclusiveDelta / (i + 1);
                Assert.True(low <= exclusive);
                Assert.True(exclusive < high);

                var inclusive      = inclusiveDist.Sample(rng);
                var inclusiveDelta = inclusive - inclusiveMean;
                inclusiveMean += inclusiveDelta / (i + 1);
                Assert.True(low <= inclusive);
                Assert.True(inclusive < high);
            }

            Assert.True(Statistics.WithinConfidence(populationMean, popStdDev, exclusiveMean, iterations));
            Assert.True(Statistics.WithinConfidence(populationMean, popStdDev, inclusiveMean, iterations));
        }
Example #2
0
        public void AverageDoubles(Double low, Double high, UInt64 seed)
        {
            const Int32 iterations = 10_000;

            var populationMean = high / 2 + low / 2;
            var popStdDev      = 1.0 / Math.Sqrt(3) * (high / 2 - low / 2);

            var exclusiveDist = Uniform.New(low, high);
            var inclusiveDist = Uniform.NewInclusive(low, high);
            var rng           = Pcg32.Create(789 + seed, 11634580027462260723ul);

            Double exclusiveMean = 0;
            Double inclusiveMean = 0;

            for (var i = 0; i < iterations; i++)
            {
                var exclusive      = exclusiveDist.Sample(rng);
                var exclusiveDelta = exclusive - exclusiveMean;
                exclusiveMean += exclusiveDelta / (i + 1);
                Assert.True(low <= exclusive);
                Assert.True(exclusive < high);

                var inclusive      = inclusiveDist.Sample(rng);
                var inclusiveDelta = inclusive - inclusiveMean;
                inclusiveMean += inclusiveDelta / (i + 1);
                Assert.True(low <= inclusive);
                Assert.True(inclusive < high);
            }

            Assert.True(Statistics.WithinConfidence(populationMean, popStdDev, exclusiveMean, iterations));
            Assert.True(Statistics.WithinConfidence(populationMean, popStdDev, inclusiveMean, iterations));
        }
Example #3
0
        public void SingleAverage(IDistribution <Single> dist, UInt64 seed)
        {
            const Int32 iterations = 10_000;
            var         rng        = Pcg32.Create(seed, 11634580027462260723ul);

            Double mean = 0;

            for (var i = 0; i < iterations; i++)
            {
                var result = dist.Sample(rng);
                var delta  = result - mean;
                mean += delta / (i + 1);
                Assert.True(0 <= result);
                Assert.True(result <= 1);
            }

            Assert.True(Statistics.WithinConfidence(popMean: 0.5, popStdDev: 0.5, mean, iterations));

            Double mean2 = 0;

            for (var i = 0; i < iterations; i++)
            {
                Assert.True(dist.TrySample(rng, out var result));
                var delta = result - mean2;
                mean2 += delta / (i + 1);
                Assert.True(0 <= result);
                Assert.True(result <= 1);
            }

            Assert.True(Statistics.WithinConfidence(popMean: 0.5, popStdDev: 0.5, mean2, iterations));
        }
Example #4
0
        public void TrySampleDouble()
        {
            var rng  = Pcg32.Create(789, 11634580027462260723ul);
            var dist = Uniform.New((Double)0, (Double)100);

            for (Int32 i = 0; i < 10_000; i++)
            {
                Assert.True(dist.TrySample(rng, out _));
            }
        }
Example #5
0
        public void SampleExclusiveInt64(Int64 low, Int64 high)
        {
            var dist = Uniform.New(low, high);
            var rng  = Pcg32.Create(252, 11634580027462260723ul);

            for (var i = 0; i < 10000; i++)
            {
                var result = dist.Sample(rng);
                Assert.True(low <= result);
                Assert.True(result < high);
            }
        }
Example #6
0
        public void SampleInclusiveSByte(SByte low, SByte high)
        {
            var dist = Uniform.NewInclusive(low, high);
            var rng  = Pcg32.Create(252, 11634580027462260723ul);

            for (var i = 0; i < 10000; i++)
            {
                var result = dist.Sample(rng);
                Assert.True(low <= result);
                Assert.True(result <= high);
            }
        }
Example #7
0
        public Level Generate(SimulationParameters parameters, Int32 rngSeed)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            IRng rng = Pcg32.Create((UInt64)rngSeed, 0);

            // Generate the terrain and ensure that the starting square isn't completely blocked in
            TerrainType[,] terrain = Generate(parameters, rng);
            return(new Level(terrain, new ProtoLevel(parameters, this, rngSeed)));
        }
Example #8
0
        /// <summary>
        /// Generate the XOR key for a specific PRNG seed.
        /// </summary>
        /// <param name="seed">Seed</param>
        /// <param name="outputLength">Output length</param>
        /// <returns>XOR key</returns>
        static byte[] GenerateXorKey(ulong seed, int outputLength)
        {
            var buffer    = new byte[256];
            var key       = new byte[outputLength];
            var component = new byte[outputLength];

            // Initialize random generator
            var prng = new Pcg32(seed, 0);

            // Each key is generated over 16 iterations
            for (int i = 0; i < 16; ++i)
            {
                // Generate base array
                for (int j = 0; j < buffer.Length; ++j)
                {
                    buffer[j] = (byte)j;
                }

                // Shuffle array
                for (int j = buffer.Length - 1; j >= 1; --j)
                {
                    var index = prng.GenerateNext((uint)j + 1);
                    var old   = buffer[index];
                    buffer[index] = buffer[j];
                    buffer[j]     = old;
                }

                // We only need the first N elements
                Array.Copy(buffer, 0, component, 0, component.Length);

                // Generate limit
                var   part1 = prng.GenerateNext();
                var   part2 = prng.GenerateNext();
                ulong limit = ((ulong)part2 << 32) | part1;

                // Sort
                FastShittySort(component, limit);

                // XOR with current candidate
                for (int j = 0; j < key.Length; ++j)
                {
                    key[j] ^= component[j];
                }

                // Reverse candidate
                Array.Reverse(key);
            }

            // Return key
            return(key);
        }
Example #9
0
        public RngUInt32()
        {
            _chaCha8         = ChaCha.GetChaCha8Factory().Create(new ChaCha.Seed());
            _chaCha12        = ChaCha.GetChaCha12Factory().Create(new ChaCha.Seed());
            _chaCha20        = ChaCha.GetChaCha20Factory().Create(new ChaCha.Seed());
            _pcg32           = Rngs.Pcg32.Create(0, 0);
            _mt1993764       = Rngs.Mt1993764.Create(0);
            _xorShift        = Rngs.XorShift.Create(1, 1, 1, 1);
            _systemCryptoRng = Rngs.SystemCryptoRng.Create();
#pragma warning disable CS0618
            _cryptoServiceProvider = Rngs.CryptoServiceProvider.Create();
#pragma warning restore CS0618
            _random = new Random(42);
        }
Example #10
0
        public void SampleExclusive(Int64 lowInt, Int64 highInt)
        {
            var low  = TimeSpan.FromTicks(lowInt);
            var high = TimeSpan.FromTicks(highInt);
            var dist = Uniform.New(low, high);
            var rng  = Pcg32.Create(252, 11634580027462260723ul);

            for (var i = 0; i < 10000; i++)
            {
                var result = dist.Sample(rng);
                Assert.True(low <= result);
                Assert.True(result < high);
            }
        }
Example #11
0
        public void DoubleRange(Double low, Double high)
        {
            var rng     = Pcg32.Create(252, 11634580027462260723ul);
            var zeroRng = new StepRng(0)
            {
                Increment = 0
            };
            var maxRng = new StepRng(0xFFFF_FFFF_FFFF_FFFF)
            {
                Increment = 0
            };

            var uniform          = Uniform.New(low, high);
            var inclusiveUniform = Uniform.NewInclusive(low, high);

            for (var i = 0; i < 100; i++)
            {
                var exclusive = uniform.Sample(rng);
                Assert.True(low <= exclusive && exclusive < high, $"Exclusive sampling of RNG failed; low: {low}, high: {high}, actual: {exclusive}");
                var inclusive = uniform.Sample(rng);
                Assert.True(low <= inclusive && inclusive <= high, $"Inclusive sampling of RNG failed; low: {low}, high: {high}, actual: {inclusive}");
            }

            Assert.Equal(low, Uniform.NewInclusive(low, low).Sample(rng));

            Assert.Equal(low, uniform.Sample(zeroRng));
            Assert.Equal(low, inclusiveUniform.Sample(zeroRng));
            Assert.True(uniform.Sample(maxRng) < high, $"Exclusive sampling of Max RNG failed; low: {low}, high: {high}, actual: {uniform.Sample(maxRng)}");
            Assert.True(inclusiveUniform.Sample(maxRng) <= high, $"Inclusive sampling of Max RNG failed; low: {low}, high: {high}, actual: {inclusiveUniform.Sample(maxRng):G19}");

            // Don't run this test for really tiny differences between high and low
            // since for those rounding might result in selecting high for a very
            // long time.
            if (high - low <= 0.0001)
            {
                return;
            }

            var loweringMaxRng = new StepRng(0xFFFF_FFFF_FFFF_FFFF)
            {
                Increment = unchecked ((UInt64)(-1L << 12))
            };

            Assert.True(uniform.Sample(loweringMaxRng) < high);
            Assert.True(uniform.Sample(loweringMaxRng) < high);
        }
Example #12
0
        public void FloatTest(Decimal low, Decimal high)
        {
            var rng     = Pcg32.Create(252, 11634580027462260723ul);
            var zeroRng = new StepRng(0)
            {
                Increment = 0
            };
            var maxRng = new StepRng(0xFFFF_FFFF_FFFF_FFFF)
            {
                Increment = 0
            };

            var exclusiveUniform = Uniform.New(low, high);
            var inclusiveUniform = Uniform.NewInclusive(low, high);

            for (var i = 0; i < 100; i++)
            {
                var exclusive = exclusiveUniform.Sample(rng);
                Assert.True(low <= exclusive && exclusive < high);
                var inclusive = exclusiveUniform.Sample(rng);
                Assert.True(low <= inclusive && inclusive <= high);
            }

            Assert.Equal(low, Uniform.NewInclusive(low, low).Sample(rng));

            Assert.Equal(low, exclusiveUniform.Sample(zeroRng));
            Assert.Equal(low, inclusiveUniform.Sample(zeroRng));
            Assert.True(exclusiveUniform.Sample(maxRng) < high);
            Assert.True(inclusiveUniform.Sample(maxRng) <= high);

            var loweringMaxRng = new StepRng(0xFFFF_FFFF_FFFF_FFFF)
            {
                Increment = unchecked ((UInt64)(-1L << 12))
            };

            Assert.True(exclusiveUniform.Sample(loweringMaxRng) < high);
            Assert.True(exclusiveUniform.Sample(loweringMaxRng) < high);

            var maxDoubleInclusive = Uniform.NewInclusive(Decimal.MaxValue, Decimal.MaxValue);

            Assert.Equal(Decimal.MaxValue, maxDoubleInclusive.Sample(rng));
            var minDoubleInclusive = Uniform.NewInclusive(-Decimal.MaxValue, -Decimal.MaxValue);

            Assert.Equal(-Decimal.MaxValue, minDoubleInclusive.Sample(rng));
        }
Example #13
0
        public void MinMax()
        {
            var rng = Pcg32.Create(252, 11634580027462260723ul);

            var maxSingleInclusive = Uniform.NewInclusive(Single.MaxValue, Single.MaxValue);

            Assert.Equal(Single.MaxValue, maxSingleInclusive.Sample(rng));
            var minSingleInclusive = Uniform.NewInclusive(-Single.MaxValue, -Single.MaxValue);

            Assert.Equal(-Single.MaxValue, minSingleInclusive.Sample(rng));

            var maxDoubleInclusive = Uniform.NewInclusive(Double.MaxValue, Double.MaxValue);

            Assert.Equal(Double.MaxValue, maxDoubleInclusive.Sample(rng));
            var minDoubleInclusive = Uniform.NewInclusive(-Double.MaxValue, -Double.MaxValue);

            Assert.Equal(-Double.MaxValue, minDoubleInclusive.Sample(rng));
        }
Example #14
0
        public void Test()
        {
            var rng = new Pcg32(42, 54);

            foreach (var round in Pcg32Rounds)
            {
                foreach (var expected in round.RandomNumbers)
                {
                    Assert.Equal(expected, rng.GenerateNext());
                }

                rng.Advance((ulong)-round.RandomNumbers.Length);

                foreach (var expected in round.RandomNumbers)
                {
                    Assert.Equal(expected, rng.GenerateNext());
                }

                foreach (var coin in round.Coins)
                {
                    Assert.Equal(coin, (int)rng.GenerateNext(2));
                }

                foreach (var roll in round.Rolls)
                {
                    Assert.Equal(roll, (int)rng.GenerateNext(6) + 1);
                }

                var cards = Enumerable.Range(0, 52).ToArray();
                for (var i = cards.Length; i > 1; i--)
                {
                    var chosen = rng.GenerateNext((uint)i);
                    var card   = cards[chosen];
                    cards[chosen] = cards[i - 1];
                    cards[i - 1]  = card;
                }

                string actual = string.Join(" ", cards.Select(x => $"{"A23456789TJQK"[x / 4]}{"hcds"[x % 4]}"));
                Assert.Equal(round.Cards, actual);
            }
        }
Example #15
0
 private SmallRng(Pcg32 wrapped) => _wrapped = wrapped;
Example #16
0
 public IntelligentRandomAi(Int32 seed)
 {
     _seed = seed;
     _rng  = Pcg32.Create((UInt64)seed, 0);
 }
Example #17
0
        private static readonly Bernoulli _wallClearChance   = Bernoulli.FromRatio(1, 5); // 20% chance of clearing a wall

        public Level Generate(SimulationParameters parameters, Int32 rngSeed)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            Pcg32 rng = Pcg32.Create((UInt64)rngSeed, 0);

            Int32 width  = parameters.BottomRight.X + 1;
            Int32 height = parameters.BottomRight.Y + 1;

            TerrainType[,] terrain = new TerrainType[width, height];

            Position start = parameters.InitialPosition;
            Stack <CoordinatePair>   stack   = new Stack <CoordinatePair>();
            HashSet <CoordinatePair> visited = new HashSet <CoordinatePair>();

            stack.Push(start);
            visited.Add(start);
            terrain[start.X, start.Y] = TerrainType.Smooth;

            while (stack.Count > 0)
            {
                var current = stack.Peek();

                Int32   offset          = _directionDist.Sample(rng);
                Boolean anyNewNeighbors = false;
                for (Int32 i = 0; i < Direction.DirectionCount; i++)
                {
                    Direction direction = (Direction)((i + offset) % Direction.DirectionCount);

                    var passage       = current + direction;
                    var neighbor      = passage + direction;
                    var boundaryCheck = neighbor + direction;
                    if (!parameters.BottomRight.Contains(boundaryCheck) || visited.Contains(neighbor))
                    {
                        continue;
                    }

                    anyNewNeighbors = true;
                    terrain[passage.X, passage.Y]   = TerrainType.Smooth;
                    terrain[neighbor.X, neighbor.Y] = TerrainType.Smooth;
                    visited.Add(neighbor);
                    stack.Push(neighbor);
                }

                if (!anyNewNeighbors)
                {
                    if (_wallClearChance.Sample(rng))
                    {
                        Direction direction     = (Direction)_directionDist.Sample(rng);
                        var       passage       = current + direction;
                        var       boundaryCheck = passage + direction;
                        if (parameters.BottomRight.Contains(boundaryCheck) && terrain[passage.X, passage.Y] == TerrainType.Impassable)
                        {
                            terrain[passage.X, passage.Y] = TerrainType.Rough;
                        }
                    }

                    stack.Pop();
                }
            }

            return(new Level(terrain, new ProtoLevel(parameters, this, rngSeed)));
        }