From a4032d069ee1032e2587ee051a353ade23d960b8 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Mon, 8 Mar 2010 23:43:53 +1300 Subject: [PATCH] borrowed Mono's RNG. --- OpenRA.FileFormats/OpenRA.FileFormats.csproj | 3 +- OpenRA.FileFormats/Thirdparty/Random.cs | 139 +++++++++++++++++++ OpenRA.Game/World.cs | 6 +- 3 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 OpenRA.FileFormats/Thirdparty/Random.cs diff --git a/OpenRA.FileFormats/OpenRA.FileFormats.csproj b/OpenRA.FileFormats/OpenRA.FileFormats.csproj index 1b66837ab3..174eb124e5 100644 --- a/OpenRA.FileFormats/OpenRA.FileFormats.csproj +++ b/OpenRA.FileFormats/OpenRA.FileFormats.csproj @@ -1,4 +1,4 @@ - + Debug @@ -80,6 +80,7 @@ + diff --git a/OpenRA.FileFormats/Thirdparty/Random.cs b/OpenRA.FileFormats/Thirdparty/Random.cs new file mode 100644 index 0000000000..2f6c9dd14b --- /dev/null +++ b/OpenRA.FileFormats/Thirdparty/Random.cs @@ -0,0 +1,139 @@ +// +// System.Random.cs +// +// Authors: +// Bob Smith (bob@thestuff.net) +// Ben Maurer (bmaurer@users.sourceforge.net) +// +// (C) 2001 Bob Smith. http://www.thestuff.net +// (C) 2003 Ben Maurer +// + +// +// Copyright (C) 2004 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +namespace OpenRA.Thirdparty +{ + [Serializable] + public class Random + { + const int MBIG = int.MaxValue; + const int MSEED = 161803398; + const int MZ = 0; + + int inext, inextp; + int [] SeedArray = new int [56]; + + public Random () + : this (Environment.TickCount) + { + } + + public Random (int Seed) + { + int ii; + int mj, mk; + + // Numerical Recipes in C online @ http://www.library.cornell.edu/nr/bookcpdf/c7-1.pdf + mj = MSEED - Math.Abs (Seed); + SeedArray [55] = mj; + mk = 1; + for (int i = 1; i < 55; i++) { // [1, 55] is special (Knuth) + ii = (21 * i) % 55; + SeedArray [ii] = mk; + mk = mj - mk; + if (mk < 0) + mk += MBIG; + mj = SeedArray [ii]; + } + for (int k = 1; k < 5; k++) { + for (int i = 1; i < 56; i++) { + SeedArray [i] -= SeedArray [1 + (i + 30) % 55]; + if (SeedArray [i] < 0) + SeedArray [i] += MBIG; + } + } + inext = 0; + inextp = 31; + } + + protected virtual double Sample () + { + int retVal; + + if (++inext >= 56) inext = 1; + if (++inextp >= 56) inextp = 1; + + retVal = SeedArray [inext] - SeedArray [inextp]; + + if (retVal < 0) + retVal += MBIG; + + SeedArray [inext] = retVal; + + return retVal * (1.0 / MBIG); + } + + public virtual int Next () + { + return (int)(Sample () * int.MaxValue); + } + + public virtual int Next (int maxValue) + { + if (maxValue < 0) + throw new ArgumentOutOfRangeException("Max value is less then min value."); + + return (int)(Sample () * maxValue); + } + + public virtual int Next (int minValue, int maxValue) + { + if (minValue > maxValue) + throw new ArgumentOutOfRangeException("Min value is greater then max value."); + + uint diff = (uint)(maxValue - minValue); + if (diff == 0) + return minValue; + + int result = (int)(Sample () * diff + minValue); + return ((result != maxValue) ? result : (result - 1)); + } + + public virtual void NextBytes (byte [] buffer) + { + if (buffer == null) + throw new ArgumentNullException ("buffer"); + + for (int i = 0; i < buffer.Length; i++) { + buffer [i] = (byte)(Sample () * (byte.MaxValue + 1)); + } + } + + public virtual double NextDouble () + { + return this.Sample (); + } + } +} diff --git a/OpenRA.Game/World.cs b/OpenRA.Game/World.cs index 3adca8c670..a9711918b1 100644 --- a/OpenRA.Game/World.cs +++ b/OpenRA.Game/World.cs @@ -28,6 +28,8 @@ using OpenRA.Graphics; using OpenRA.Support; using OpenRA.Traits; +using XRandom = OpenRA.Thirdparty.Random; + namespace OpenRA { public class World @@ -36,8 +38,8 @@ namespace OpenRA List effects = new List(); List> frameEndActions = new List>(); - public Random SharedRandom = new Random(0); // synced - public Random CosmeticRandom = new Random(); // not synced + public XRandom SharedRandom = new XRandom(0); // synced + public XRandom CosmeticRandom = new XRandom(); // not synced public readonly Dictionary players = new Dictionary();