diff --git a/VERSION b/VERSION
index 2003b63..5712157 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.9.2
+0.10.1
diff --git a/src/nexus/math/LehmerGenerator.as b/src/nexus/math/LehmerGenerator.as
index 8503c35..b8ad168 100644
--- a/src/nexus/math/LehmerGenerator.as
+++ b/src/nexus/math/LehmerGenerator.as
@@ -18,34 +18,24 @@ public final class LehmerGenerator implements ISeededPRNG
private var m_currentState:uint;
private var m_numbersGenerated:int;
- public function LehmerGenerator(seed:int=1)
+ public function LehmerGenerator(seed:uint=1)
{
this.seed = seed;
}
- [Inline]
public final function get seed():uint { return m_seed; }
public final function set seed(value:uint):void
{
- //if(value > 0 && value < 2147483647)
- //{
m_seed = value;
m_currentState = m_seed;
m_numbersGenerated = 0;
- //}
- //else
- //{
- //throw new ArgumentError("Seed must be between 0 and 2147483647");
- //}
}
- [Inline]
public final function get currentState():uint { return m_currentState; }
[Inline]
public function get period():uint { return 2147483647 /*int.MAX_VALUE*/; }
- [Inline]
public final function get numbersGenerated():int { return m_numbersGenerated; }
public function next():uint
diff --git a/src/nexus/math/NativeRandomGenerator.as b/src/nexus/math/NativeRandomGenerator.as
index 1c6804b..33579c1 100644
--- a/src/nexus/math/NativeRandomGenerator.as
+++ b/src/nexus/math/NativeRandomGenerator.as
@@ -23,7 +23,6 @@ public final class NativeRandomGenerator implements IPRNG
[Inline]
public function get period():uint { return 2147483647 /*int.MAX_VALUE*/; }
- [Inline]
public final function get currentState():uint { return m_currentState; }
public function next():uint
diff --git a/src/nexus/math/Random.as b/src/nexus/math/Random.as
index c35a09f..b96f080 100644
--- a/src/nexus/math/Random.as
+++ b/src/nexus/math/Random.as
@@ -18,7 +18,8 @@ public class Random
// CLASS CONSTANTS
//--------------------------------------
- private static const s_random : Random = new Random(new NativeRandomGenerator());
+ private static const s_random:Random = new Random(new NativeRandomGenerator());
+
public static function get instance():Random
{
return s_random;
@@ -28,7 +29,7 @@ public class Random
// INSTANCE VARIABLES
//--------------------------------------
- private var m_generator : IPRNG;
+ private var m_generator:IPRNG;
//--------------------------------------
// CONSTRUCTOR
@@ -48,37 +49,51 @@ public class Random
//--------------------------------------
/**
- * Generates a random floating point in the range [min, max).
+ * Generates a random floating point in the range [min, max) which is [0, 1) if neither
+ * argument is given.
+ *
* If max is NaN, Infinity, or -Infinity, a number in the range [min, 1) is returned
* If min is NaN, Infinity, or -Infinity, a number in the range [0, max) is returned
* @param min The lowest value to return, inclusive
* @param max The highest value to return, exclusive
* @return A number in the range [min, max)
*/
- public function float( min : Number = NaN, max : Number = NaN ) : Number
+ public function float(min:Number = NaN, max:Number = NaN):Number
{
min = isNaN(min) || !isFinite(min) ? 0 : min;
max = isNaN(max) || !isFinite(max) ? 1 : max;
- return ((m_generator.next() / m_generator.period) * (max - min)) + min;
+ var p:Number = m_generator.next() / m_generator.period;
+ return (p * (max - min)) + min;
}
/**
- * Generates a random integer in the range [min, max]
+ * Generates a random integer in the range [min, max)
* @param min The lowest value to return, inclusive
- * @param max The highest value to return, inclusive
- * @return A number in the range [min, max]
+ * @param max The highest value to return, exclusive
+ * @return An int in the range [min, max)
+ */
+ public function integer(min:uint = 0, max:int = int.MAX_VALUE):int
+ {
+ return m_generator.next() % (max - min) + min;
+ }
+
+ /**
+ * Generates a random unsigned integer in the range [min, max)
+ * @param min The lowest value to return, inclusive
+ * @param max The highest value to return, exclusive
+ * @return A uint in the range [min, max)
*/
- public function integer( min : int = 1, max : int = int.MAX_VALUE ) : int
+ public function unsignedInteger(min:uint = 0, max:uint = uint.MAX_VALUE):uint
{
- return Math.floor((m_generator.next() / m_generator.period) * (max - min + 1)) + min;
+ return m_generator.next() % (max - min) + min;
}
/**
* Returns a random true/false value, with a 50% chance of either
*/
- public function boolean() : Boolean
+ public function boolean():Boolean
{
- return (m_generator.next() / m_generator.period) < 0.5;
+ return(m_generator.next() / m_generator.period) < 0.5;
}
/**
@@ -88,10 +103,10 @@ public class Random
* @example randomRound(4.3)
should return 4 70% of the time
* and 5 30% of the time.
*/
- public function weightedRound( value : Number ) : int
+ public function weightedRound(value:Number):int
{
- var floor : int = Math.floor(value);
- return (m_generator.next() / m_generator.period) > (value - floor) ? floor : floor + 1;
+ var floor:int = Math.floor(value);
+ return(m_generator.next() / m_generator.period) > (value - floor) ? floor : floor + 1;
}
/**
@@ -100,9 +115,9 @@ public class Random
* is assumed to be a Vector or Array (or otherwise have a length
property and
* be able to be accessed with the index operators).
*/
- public function choice(...items):Object
+ public function choice(... items):Object
{
- var choice : int;
+ var choice:int;
if(items.length == 1)
{
choice = integer(0, items[0].length - 1);
@@ -115,11 +130,25 @@ public class Random
}
}
- public function toString(verbose:Boolean=false):String
+ /**
+ * Destructively shuffles the container using the Fisher-Yates algorithm.
+ */
+ public function shuffle(container:Object):void
{
- return "[Random" + m_generator + "]";
+ for(var x:int = container.length - 1; x > 0; x--)
+ {
+ var j:int = integer(0, x + 1);
+ var tmp:* = container[x];
+ container[x] = container[j];
+ container[j] = tmp;
+ }
}
+ public function toString(verbose:Boolean = false):String
+ {
+ return "[Random" + m_generator + "]";
+ }
+
//--------------------------------------
// PRIVATE & PROTECTED INSTANCE METHODS
//--------------------------------------
diff --git a/src/nexus/math/TinyMersenneTwisterGenerator.as b/src/nexus/math/TinyMersenneTwisterGenerator.as
new file mode 100644
index 0000000..9f2c73f
--- /dev/null
+++ b/src/nexus/math/TinyMersenneTwisterGenerator.as
@@ -0,0 +1,130 @@
+// Copyright (c) 2013 Robert Zubek and SomaSim LLC
+//
+// 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.
+package nexus.math
+{
+
+import flash.utils.*;
+
+/**
+ * Actionscript port of the TinyMT random number generator, a small-footprint
+ * variant of the Mersenne Twister.
+ *
+ *
Original algorithm by Mutsuo Saito and Makoto Matsumoto.
+ * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/TINYMT/index.html
+ */
+public class TinyMersenneTwisterGenerator implements ISeededPRNG
+{
+ // initialization constants (in the MT reference implementation
+ // they're specified by the user during initialization, but they don't change)
+ private static const MAT1:uint = 0x70707070;
+ private static const MAT2:uint = 0x07070707;
+ private static const TMAT:uint = 0x55555555;
+
+ protected static const MIN_LOOP:int = 8;
+ protected static const PRE_LOOP:int = 8;
+
+ private var m_seed:uint;
+ private var m_currentState:uint;
+ private var m_numbersGenerated:int;
+
+ public function TinyMersenneTwisterGenerator(seed:uint = 1)
+ {
+ this.seed = seed;
+ }
+
+ public final function get seed():uint { return m_seed; }
+ public final function set seed(value:uint):void
+ {
+ m_seed = value;
+ m_currentState = m_seed;
+ m_numbersGenerated = 0;
+
+ stateVars[0] = m_seed;
+ stateVars[1] = MAT1;
+ stateVars[2] = MAT2;
+ stateVars[3] = TMAT;
+
+ for(var i:int = 1; i < MIN_LOOP; i++)
+ {
+ stateVars[i & 3] ^= i + 1812433253 * (stateVars[(i - 1) & 3] ^ (stateVars[(i - 1) & 3] >>> 30));
+ }
+
+ for(var j:int = 0; j < PRE_LOOP; j++)
+ {
+ nextState();
+ }
+ }
+
+ public final function get currentState():uint { return m_currentState; }
+
+ [Inline]
+ public function get period():uint { return 4294967295; }
+
+ public final function get numbersGenerated():int
+ {
+ return m_numbersGenerated;
+ }
+
+ public function next():uint
+ {
+ nextState();
+ return temper();
+ }
+
+ // state variables
+ private const stateVars:Vector.