This is an implementation of the Mersenne Twister random number generator, written in VB.NET. (I had a C# version laying around at one point, but I may have deleted it. This one works exactly the same, and implements the same algorithm.)

This is what I use in Heroic Adventure! (HA!) and have recently added it to my Cellular Automata project as well. It's a nice fast substitute for System.Random, with a much longer period before predictable repeating patterns.

'

' An implementation of the Mersenne Twister algorithm (MT19937), developed

' with reference to the C code written by Takuji Nishimura and Makoto Matsumoto

' (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html).

'

' This code is free to use for any pupose.

'

Option Strict On

'''

''' A random number generator with a uniform distribution using the Mersenne

''' Twister algorithm.

'''

Public Class MersenneTwister

Private Const N As Integer = 624

Private Const M As Integer = 397

Private Const MATRIX_A As UInteger = &H9908B0DFUI

Private Const UPPER_MASK As UInteger = &H80000000UI

Private Const LOWER_MASK As UInteger = &H7FFFFFFFUI

Private mt(N - 1) As UInteger

Private mti As Integer = N + 1

''' <summary>

''' Create a new Mersenne Twister random number generator.

''' </summary>

Public Sub New()

Me.New(CUInt(Date.Now.Millisecond))

End Sub

''' <summary>

''' Create a new Mersenne Twister random number generator with a

''' particular seed.

''' </summary>

''' <param name="seed">The seed for the generator.</param>

<CLSCompliant(False)> _

Public Sub New(ByVal seed As UInteger)

mt(0) = seed

For mti = 1 To N - 1

mt(mti) = CUInt((1812433253UL * (mt(mti - 1) Xor (mt(mti - 1) >> 30)) + CUInt(mti)) And &HFFFFFFFFUL)

Next

End Sub

''' <summary>

''' Create a new Mersenne Twister random number generator with a

''' particular initial key.

''' </summary>

''' <param name="initialKey">The initial key.</param>

<CLSCompliant(False)> _

Public Sub New(ByVal initialKey() As UInteger)

Me.New(19650218UI)

Dim i, j, k As Integer

i = 1 : j = 0

k = CInt(IIf(N > initialKey.Length, N, initialKey.Length))

For k = k To 1 Step -1

mt(i) = CUInt(((mt(i) Xor ((mt(i - 1) Xor (mt(i - 1) >> 30)) * 1664525UL)) + initialKey(j) + CUInt(j)) And &HFFFFFFFFUI)

i += 1 : j += 1

If i >= N Then mt(0) = mt(N - 1) : i = 1

If j >= initialKey.Length Then j = 0

Next

For k = N - 1 To 1 Step -1

mt(i) = CUInt(((mt(i) Xor ((mt(i - 1) Xor (mt(i - 1) >> 30)) * 1566083941UL)) - CUInt(i)) And &HFFFFFFFFUI)

i += 1

If i >= N Then mt(0) = mt(N - 1) : i = 1

Next

mt(0) = &H80000000UI

End Sub

''' <summary>

''' Generates a random number between 0 and System.UInt32.MaxValue.

''' </summary>

<CLSCompliant(False)> _

Public Function NextUInt32() As UInteger

Dim y As UInteger

Static mag01() As UInteger = {&H0UI, MATRIX_A}

If mti >= N Then

Dim kk As Integer

Debug.Assert(mti <> N + 1, "Failed initialization")

For kk = 0 To N - M - 1

y = (mt(kk) And UPPER_MASK) Or (mt(kk + 1) And LOWER_MASK)

mt(kk) = mt(kk + M) Xor (y >> 1) Xor mag01(CInt(y And &H1))

Next

For kk = kk To N - 2

y = (mt(kk) And UPPER_MASK) Or (mt(kk + 1) And LOWER_MASK)

mt(kk) = mt(kk + (M - N)) Xor (y >> 1) Xor mag01(CInt(y And &H1))

Next

y = (mt(N - 1) And UPPER_MASK) Or (mt(0) And LOWER_MASK)

mt(N - 1) = mt(M - 1) Xor (y >> 1) Xor mag01(CInt(y And &H1))

mti = 0

End If

y = mt(mti)

mti += 1

' Tempering

y = y Xor (y >> 11)

y = y Xor ((y << 7) And &H9D2C5680UI)

y = y Xor ((y << 15) And &HEFC60000UI)

y = y Xor (y >> 18)

Return y

End Function

''' <summary>

''' Generates a random integer between 0 and System.Int32.MaxValue.

''' </summary>

Public Function [Next]() As Integer

Return CInt(NextUInt32() >> 1)

End Function

''' <summary>

''' Generates a random integer between 0 and maxValue.

''' </summary>

''' <param name="maxValue">The maximum value. Must be greater than zero.</param>

Public Function [Next](ByVal maxValue As Integer) As Integer

Return [Next](0, maxValue)

End Function

''' <summary>

''' Generates a random integer between minValue and maxValue.

''' </summary>

''' <param name="maxValue">The lower bound.</param>

''' <param name="minValue">The upper bound.</param>

Public Function [Next](ByVal minValue As Integer, ByVal maxValue As Integer) As Integer

Return CInt(Math.Floor((maxValue - minValue + 1) * NextDouble() + minValue))

End Function

''' <summary>

''' Generates a random floating point number between 0 and 1.

''' </summary>

Public Function NextDouble() As Double

Return NextUInt32() * (1.0 / 4294967295.0)

End Function

End Class