# Random numbers in VB.net not random...weird?

on
This is related to the last question I wrote about generating random numbers in VB.NET, but I'll repost the details, here, too.

I need to generate six unique random numbers between 7 and 20 for a dart board application that I'm writing.  It's to simulate wildcard cricket, for those that are familiar.

The code that I have seemingly generates random numbers, but something I've done or some aspect of the random number generator is making the results pretty far from random.  The following code results in the exact same sequence of numbers every time my sub is called.  Each time I re-run the sub, it generates new numbers, but it's always the same numbers, for example:

first refresh results 9,15,16,17,10,7
second refresh results 18,13,12,15,8,7
third refresh results 11,18,19,13,10,8
fourth refresh results 12,9,7,13,16,11
...and so on

It's like this every single time I run the app, the same numbers in the same sequence.  I tried it with one rnd and with one for each intSlot var (as in the sample code), but the results are exactly the same either way.

My guess, since I'm not a very good coder, is that it has to do with my logic that tries to pick unique numbers, but it's so weird that it does the same numbers each time that I just can't tell for sure.

So, any guidance would be much appreciated.  EE has been awesome with this...couldn't have gotten this far without it!

Here's the code:

``````Public Sub GenWildCard()

'initialize random number generator
Static rnd1 As New Random(20)
Static rnd2 As New Random(20)
Static rnd3 As New Random(20)
Static rnd4 As New Random(20)
Static rnd5 As New Random(20)
Static rnd6 As New Random(20)

If Not intSlot1Lock = 1 Then

intSlot1 = rnd1.Next(7, 20)
If intSlot1 = intSlot5 Or intSlot1 = intSlot4 Or intSlot1 = intSlot3 Or intSlot1 = intSlot6 Or intSlot1 = intSlot2 Then
Do Until intSlot1 <> intSlot5 And intSlot1 <> intSlot4 And intSlot1 <> intSlot3 And intSlot1 <> intSlot6 And intSlot1 <> intSlot2

intSlot1 = rnd1.Next(7, 20)
Loop
End If
lblSlot1.Text = intSlot1
End If

If Not intSlot2Lock = 1 Then
intSlot2 = rnd2.Next(7, 20)
If intSlot2 = intSlot5 Or intSlot2 = intSlot4 Or intSlot2 = intSlot3 Or intSlot2 = intSlot6 Or intSlot2 = intSlot1 Then
Do Until intSlot2 <> intSlot5 And intSlot2 <> intSlot4 And intSlot2 <> intSlot3 And intSlot2 <> intSlot6 And intSlot2 <> intSlot1

intSlot2 = rnd2.Next(7, 20)
Loop
End If
lblSlot2.Text = intSlot2
End If

If Not intSlot3Lock = 1 Then
intSlot3 = rnd3.Next(7, 20)
If intSlot3 = intSlot5 Or intSlot3 = intSlot4 Or intSlot3 = intSlot6 Or intSlot3 = intSlot2 Or intSlot3 = intSlot1 Then
Do Until intSlot3 <> intSlot5 And intSlot3 <> intSlot4 And intSlot3 <> intSlot6 And intSlot3 <> intSlot2 And intSlot3 <> intSlot1

intSlot3 = rnd3.Next(7, 20)
Loop
End If
lblSlot3.Text = intSlot3
End If

If Not intSlot4Lock = 1 Then
intSlot4 = rnd4.Next(7, 20)
If intSlot4 = intSlot5 Or intSlot4 = intSlot6 Or intSlot4 = intSlot3 Or intSlot4 = intSlot2 Or intSlot4 = intSlot1 Then
Do Until intSlot4 <> intSlot5 And intSlot4 <> intSlot6 And intSlot4 <> intSlot3 And intSlot4 <> intSlot2 And intSlot4 <> intSlot1

intSlot4 = rnd4.Next(7, 20)
Loop
End If
lblSlot4.Text = intSlot4
End If

If Not intSlot5Lock = 1 Then
intSlot5 = rnd5.Next(7, 20)
If intSlot5 = intSlot6 Or intSlot5 = intSlot4 Or intSlot5 = intSlot3 Or intSlot5 = intSlot2 Or intSlot5 = intSlot1 Then
Do Until intSlot5 <> intSlot6 And intSlot5 <> intSlot4 And intSlot5 <> intSlot3 And intSlot5 <> intSlot2 And intSlot5 <> intSlot1
intSlot5 = rnd5.Next(7, 20)
Loop
End If
lblSlot5.Text = intSlot5
End If

If Not intSlot6Lock = 1 Then
intSlot6 = rnd6.Next(7, 20)
If intSlot6 = intSlot5 Or intSlot6 = intSlot4 Or intSlot6 = intSlot3 Or intSlot6 = intSlot2 Or intSlot6 = intSlot1 Then
Do Until intSlot6 <> intSlot5 And intSlot6 <> intSlot4 And intSlot6 <> intSlot3 And intSlot6 <> intSlot2 And intSlot6 <> intSlot1
intSlot6 = rnd6.Next(7, 20)
Loop
End If
lblSlot6.Text = intSlot6
End If

End Sub
``````
Comment
Watch Question

Do more with

EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Commented:
By always specifying 20 as your seed, you will always get the same sequence.  If you simply omit the 20 (ie, use Random by itself), the system will use a time-based seed.

You should also consider having a single instance of Random instead of six instances.  It will probably simplify your code quite a bit.

Commented:
So, the seed is 20 when I use:

dim rnd as new Random(20)

but I can leave it blank (which uses milliseconds by default, right?), then use rnd.next(7,20) to specify the range?

I'll give it a shot and report back.

Thanks!

Commented:
and also instead of using 6 random generators to generate random numbers define one random object and use .next method to get the next random number.

Commented:
Man, do I love this site. Thanks dude!

Commented:
If you want your first six numbers to be unique, try this function.  Because you're dealing with random numbers uniqueness cannot be guaranteed (by this algorithm) but you can increase the likelihood further by increasing kLim.  Note that your range of legal values must be large enough also.
``````Private r As Random = New Random

'   NextUniqueRNum attempts to return a sequence of unique random numbers.
'   It takes one parameter, which specifies the upper bound for the
'   number to be returned (result will be an integer >= 0 and less than
'   rMax).  If rMax is zero, a new sequence is started.
'   If rMax is not greater than the number of values already returned, it
'   will not be possible to return a unique value and the function returns
'   a duplicate.
Private Function NextUniqueRNum(ByVal rMax As Integer) As Integer
Static rNums() as Integer       ' Numbers returned in this sequence
Static nRNums as Integer = 0    ' Length of sequence
Dim i As Integer, k As Integer = 0
Const kLim as Integer = 10  ' Arbitrary value; helps ensure that While terminates

NextUniqueRNum = 0

if rMax < 1 then        ' Reset the sequence
nRNums = 0
Exit Function
Else                    ' Make room for a new value
nRNums += 1
Redim Preserve rNums(nRNums)
End If

' Keep trying until we have a unique number or must give up
While k < kLim * nRNums
k += 1
rNums(nRNums) = r.Next(rMax)    ' Next try
For i = 0 to nRNums-1           ' Check for uniqueness
If rNums(nRNums) = rNums(i) Then Continue While
Next i
Exit While
End While

NextUniqueRNum = rNums(nRNums)
End Function
``````
Retired
Distinguished Expert 2017

Commented:
Hi gknuth;

Use a seed which is a number used to calculate a starting value for the pseudo-random number sequence. The random number generator is not truely random.

Dim rnd As New Random(DateTime.Now().Second + DateTime.Now().Millisecond)

Fernando

Commented:
Do you know that Random is based on Donald E. Knuth's subtractive random number generator algorithm?

Commented:
Oh wow, that's pretty cool.

That function is great...I knew there had to be a more elegant way than the one I had :)  Thanks!

Do more with