-
Mar 3rd, 2004, 09:40 AM
#1
Tutorial - Random Numbers [VB6 and earlier]
Many questions in VB are regarding random numbers. In this tutorial I will try and explain the basic ideas regarding random numbers so it'll be easier for you to create your applications.
Intro - The Rnd Function
The first thing you need to know is the function that generates a random number. The function is called : Rnd. Here is how you use it :
1) Open a new project in VB.
2) In the load event of your form add the following code :
VB Code:
Private Sub Form_Load()
Dim i As Integer
For i = 1 To 10
Debug.Print Rnd
Next
End Sub
3) Run the project. In the Immediate window you will notice that 10 numbers have been printed.
Has someone helped you? Then you can Rate their helpful post.
-
Mar 3rd, 2004, 09:41 AM
#2
Truly Randomizing - The Randomize Statement
After you run the program once you have the values in the Immediate window. Run the program again and compare the first 10 numbers with the last 10 numbers. Notice a similarity? The Rnd function has a predetermined set of numbers that it shows every time call the rnd function. So every time you start your app, it starts from the beginning showing the same numbers again. How do you avoid this? The Randomize statement makes the Rnd function generate truly random numbers.
TIP : Don't keep using the randomize statement because then it loses it's meaning... Use it only once, right before you start creating random numbers the first time.
TIP : You also have the optional number after in the randomize statement. That number will cause the numbers to be generated randomly but based on that number. So Randomize 2 will always return the same numbers. This can be used in encryption algorithms
Comment from VB help :
Randomize uses number to initialize the Rnd function's random-number generator, giving it a new seed value. If you omit number, the value returned by the system timer is used as the new seed value.
If Randomize is not used, the Rnd function (with no arguments) uses the same number as a seed the first time it is called, and thereafter uses the last generated number as a seed value.
Note : To repeat sequences of random numbers, call Rnd with a negative argument immediately before using Randomize with a numeric argument. Using Randomize with the same value for number does not repeat the previous sequence.
VB Code:
Private Sub Form_Load()
Randomize
Dim i As Integer
For i = 1 To 10
Debug.Print Rnd
Next
End Sub
Now that we added the Randomize statement you can see that every time you run the application, different numbers are produced. If on the other hand you do this :
VB Code:
Private Sub Form_Load()
Randomize 8
Dim i As Integer
For i = 1 To 10
Debug.Print Rnd
Next
End Sub
you'll notice that the same numbers are generated (the encryption I was saying)...
Has someone helped you? Then you can Rate their helpful post.
-
Mar 3rd, 2004, 09:42 AM
#3
The million dollar question...
... or the most commonly asked question is : "How can I generate a number between 2 other numbers?"
The main problem with this is that many people haven't realised that the Rnd function returns a value less than 1 BUT greater than or equal to zero (0<=Rnd<1). So since most people think that the Rnd function can generate the number 1, the algorithms they use are incorrect. The correct way is this :
VB Code:
Int((upperbound - lowerbound + 1) * Rnd + lowerbound)
Which can easily be put into a function :
VB Code:
Private Function RandomInteger(Lowerbound As Integer, Upperbound As Integer) As Integer
RandomInteger = Int((Upperbound - Lowerbound + 1) * Rnd + Lowerbound)
End Function
and an example of using it is :
VB Code:
Private Function RandomInteger(Lowerbound As Integer, Upperbound As Integer) As Integer
RandomInteger = Int((Upperbound - Lowerbound + 1) * Rnd + Lowerbound)
End Function
Private Sub Form_Load()
Randomize 'Just once to start getting random numbers
MsgBox RandomInteger(1, 52)
End Sub
The code above would be used most of the times for a card game, to draw a card at random. If we set Lowerbound=1 and Upperbound=6 then we would have ourselves dice rolling code
Has someone helped you? Then you can Rate their helpful post.
-
Mar 3rd, 2004, 09:44 AM
#4
Series Of Unique Random Numbers
The next most popular question is "How to create unique series of random numbers (doesn't have duplicates). Usually this is used for card games or dice rolling games. There are two ways of doing it. In theory both will work, but there is a major advantage of one way as you will see soon
1st option (most common) :
Follow these steps :
1) Generate a random number
2) Store it in an array
3) Generate another random number
4) Compare it with the other elements of the array
5) If it exists then generate another random number and goto step 4, if it doesn't exist add it to the array
6) Repeat as many times as needed steps 3-5
An example code would be this :
VB Code:
Option Explicit 'Force variable declaration
Private Sub Form_Load()
Dim Ar(1 To 100) As Integer 'The array to store it in
Dim i, j As Integer 'Counters for loops
Dim X As Integer 'Variable to store the random generated number
Dim bFound As Boolean 'Boolean to check if the value has been generated before
Randomize 'Just once to ensure that we get random values
For i = 1 To 100
Do 'Start the loop that generates a random number and checks if it has already been generated
X = RandomInteger(1, 100) 'Generate a random number
bFound = False 'Set the boolean to false, if we find the number while searching the array, we'll set it to true which means that we already have that number
For j = 1 To i 'We only need to check up to i (since we haven't put any values in the rest of the array)
If Ar(j) = X Then 'If an item of the arrray is the same as the last generated number
bFound = True 'Set the boolean to true (it already exists)
DoEvents 'To not freeze until the looping is done
Exit For 'Since we found it there is no need to check the rest
End If
Next
Loop Until bFound = False 'If it wasn't found then we'll add it, if it was found then we go back to generating a new number and comparing it with all the items of the array
Ar(i) = X 'Add it to the array
Next
ShowInTextBox Text1, Ar 'Just to print the data and see it
End Sub
Private Function RandomInteger(Lowerbound As Integer, Upperbound As Integer) As Integer 'The random number generator code
RandomInteger = Int((Upperbound - Lowerbound + 1) * Rnd + Lowerbound)
End Function
Private Sub ShowInTextBox(TB As TextBox, A() As Integer) 'Just a sub to show the data in a textbox
Dim i As Integer
TB.Text = ""
For i = 1 To UBound(A)
TB.Text = TB.Text & CStr(A(i)) & vbCrLf
Next
TB.Text = Left$(TB.Text, Len(TB.Text) - 2)
End Sub
Unfortunatelly, there is a serious drawback with this method. It all seems fine, but since you are generating a small amount of random numbers then you'll be OK. But if you are trying to generate a large amount of random numbers then theoretically some number might never be generated or at least it could take a while for the number to be generated. This could clearly create an unwanted delay in your program.
I know, the chance is very very small but it will at least delay the process which could cause problems. So here is another option :
2nd option (better) :
You do follow these steps :
1) You create all the numbers you need and store them in a collection
2) Generate a random number
3) Get the element of the collection that has the index of the randomly generated number (Here is the main advantage. You will always get an element since you are generating a number that will always be the index for an element of the array. Since you remove it later, you don't need the time consuming checking )
4) Add that number to the random number array that you want
5) Remove that number from the collection with the list of numbers
6) Repeat 2-5 until the array with the list of numbers is empty
An example code would be this :
VB Code:
Option Explicit 'Force variable declaration
Private Sub Form_Load()
Dim Col As Collection 'The collection we will use to store the numbers
Dim Ar(1 To 100) As Integer 'The array to store the values from the collection
Dim i As Integer 'Counter for loops
Dim X As Integer 'Variable to store the random generated number
Randomize 'Just once to ensure that we get random values
Set Col = New Collection 'Get the collection ready to use
For i = 1 To 100 'The possible numbers that we can have as a result is all the numbers from 1 to 100 so
Col.Add i 'add all the possible numbers to the collection
Next
For i = 1 To 100 'Now to get the 100 numbers we added in the previous loop
X = RandomInteger(1, Col.Count) 'Get a random item from the collection (that exists for sure)
Ar(i) = Col.Item(X) 'Add it to the array
Col.Remove X 'Remove it so we don't add it again
Next
ShowInTextBox Text1, Ar 'Just to print the data and see it
End Sub
Private Function RandomInteger(Lowerbound As Integer, Upperbound As Integer) As Integer 'The random number generator code
RandomInteger = Int((Upperbound - Lowerbound + 1) * Rnd + Lowerbound)
End Function
Private Sub ShowInTextBox(TB As TextBox, A() As Integer) 'Just a sub to show the data in a textbox
Dim i As Integer
TB.Text = ""
For i = 1 To UBound(A)
TB.Text = TB.Text & CStr(A(i)) & vbCrLf
Next
TB.Text = Left$(TB.Text, Len(TB.Text) - 2)
End Sub
Has someone helped you? Then you can Rate their helpful post.
-
Mar 3rd, 2004, 09:45 AM
#5
Proof
Now, with the above example it is hard to realise that the second option is better and faster since it's just 100 numbers. In the first case (array) it takes an average of 31-47 milliseconds to complete the task. In the second case it takes 0 milliseconds to complete the task.
So to explain myself better, here is an example with 10000 numbers and a way to track how long was needed to create the list completely :
Array code :
VB Code:
Option Explicit 'Force variable declaration
Private Declare Function GetTickCount Lib "kernel32" () As Long 'The GetTickCount
'function retrieves
'the number of
'milliseconds that
'have elapsed since
'Windows was started.
Private Sub Form_Load()
Dim Ar(1 To 10000) As Integer 'The array to store it in
Dim i, j As Integer 'Counters for loops
Dim X As Integer 'Variable to store the random generated number
Dim bFound As Boolean 'Boolean to check if the value has been generated before
Dim S As Long 'Variable to store the number of milliseconds that have elapsed since
'Windows was started when we begin the task
Randomize 'Just once to ensure that we get random values
S = GetTickCount 'Store the number of milliseconds that have elapsed since Windows was started when we begin the task
For i = 1 To 10000
Do 'Start the loop that generates a random number and checks if it has already been generated
X = RandomInteger(1, 10000) 'Generate a random number
bFound = False 'Set the boolean to false, if we find the number while searching the array, we'll set it to true which means that we already have that number
For j = 1 To i 'We only need to check up to i (since we haven't put any values in the rest of the array)
If Ar(j) = X Then 'If an item of the arrray is the same as the last generated number
bFound = True 'Set the boolean to true (it already exists)
DoEvents 'To not freeze until the looping is done
Exit For 'Since we found it there is no need to check the rest
End If
Next
Loop Until bFound = False 'If it wasn't found then we'll add it, if it was found then we go back to generating a new number and comparing it with all the items of the array
Ar(i) = X 'Add it to the array
Next
'At the end we will subtract the number of milliseconds that had elapsed
'when the task started from the number of milliseconds that have elapsed
'when the task is complete and show it in the form's caption
Me.Caption = GetTickCount - S
ShowInTextBox Text1, Ar 'Just to print the data and see it
End Sub
Private Function RandomInteger(Lowerbound As Integer, Upperbound As Integer) As Integer 'The random number generator code
RandomInteger = Int((Upperbound - Lowerbound + 1) * Rnd + Lowerbound)
End Function
Private Sub ShowInTextBox(TB As TextBox, A() As Integer) 'Just a sub to show the data in a textbox
Dim i As Integer
TB.Text = ""
For i = 1 To UBound(A)
TB.Text = TB.Text & CStr(A(i)) & vbCrLf
DoEvents
Next
TB.Text = Left$(TB.Text, Len(TB.Text) - 2)
End Sub
And the collection code :
VB Code:
Option Explicit 'Force variable declaration
Private Declare Function GetTickCount Lib "kernel32" () As Long 'The GetTickCount
'function retrieves
'the number of
'milliseconds that
'have elapsed since
'Windows was started.
Private Sub Form_Load()
Dim Col As Collection 'The collection we will use to store the numbers
Dim Ar(1 To 10000) As Integer 'The array to store the values from the collection
Dim i As Integer 'Counter for loops
Dim X As Integer 'Variable to store the random generated number
Dim S As Long 'Variable to store the number of milliseconds that have elapsed since
'Windows was started when we begin the task
Randomize 'Just once to ensure that we get random values
Set Col = New Collection 'Get the collection ready to use
S = GetTickCount 'Store the number of milliseconds that have elapsed since Windows was started when we begin the task
For i = 1 To 10000 'The possible numbers that we can have as a result is all the numbers from 1 to 100 so
Col.Add i 'add all the possible numbers to the collection
Next
For i = 1 To 10000 'Now to get the 100 numbers we added in the previous loop
X = RandomInteger(1, Col.Count) 'Get a random item from the collection (that exists for sure)
Ar(i) = Col.Item(X) 'Add it to the array
Col.Remove X 'Remove it so we don't add it again
Next
'At the end we will subtract the number of milliseconds that had elapsed
'when the task started from the number of milliseconds that have elapsed
'when the task is complete and show it in the form's caption
Me.Caption = GetTickCount - S
ShowInTextBox Text1, Ar 'Just to print the data and see it
End Sub
Private Function RandomInteger(Lowerbound As Integer, Upperbound As Integer) As Integer 'The random number generator code
RandomInteger = Int((Upperbound - Lowerbound + 1) * Rnd + Lowerbound)
End Function
Private Sub ShowInTextBox(TB As TextBox, A() As Integer) 'Just a sub to show the data in a textbox
Dim i As Integer
TB.Text = ""
For i = 1 To UBound(A)
TB.Text = TB.Text & CStr(A(i)) & vbCrLf
DoEvents
Next
TB.Text = Left$(TB.Text, Len(TB.Text) - 2)
End Sub
On my PC, the array code needed 116328 milliseconds which means about 116 seconds which is almost 2 minutes!
The collection code needed 13219 milliseconds which is about 13 seconds!
Last edited by manavo11; Mar 3rd, 2004 at 09:50 AM.
Has someone helped you? Then you can Rate their helpful post.
-
Mar 3rd, 2004, 09:47 AM
#6
-
Mar 3rd, 2004, 12:36 PM
#7
The code/files within this thread (submitted: 03-03-2004) have been checked for malware by a moderator.
Disclaimer: This does not necessarily mean that any compiled files (DLL/EXE/OCX etc) are completely safe, but any supplied code does not contain any obvious malware. It also does not imply that code is error free, or that it performs exactly as described.
It is recommended that you manually check any code before running it, and/or use an automated tool such as Source Search by Minnow (available here or here).
If you find any serious issues (ie: the code causes damage or some sort), please contact a moderator of this forum.
Usage of any code/software posted on this forum is at your own risk.
-
Sep 21st, 2007, 09:13 PM
#8
New Member
Re: Tutorial - Random Numbers
Hi all,
I am new, to this forum and also to VB.Net and I encountered a problem. I need an array that contains 100 random numbers, between 1 and 100. More specifically, the array must contain all the numbers between 1 and 100, but in random order, and I don't know how to do that. Any help would be appreciated.
Thank you.
-
Sep 22nd, 2007, 12:36 PM
#9
Re: Tutorial - Random Numbers
Welcome to VBForums
This tutorial is actually for Classic VB, not VB.Net.
You should ask in our VB.Net forum, as the methods are different.
-
Sep 22nd, 2007, 05:50 PM
#10
New Member
Re: Tutorial - Random Numbers
Thank you,
I will post it on the VB.Net forum, as you suggested.
-
Nov 24th, 2008, 01:48 AM
#11
New Member
Re: Tutorial - Random Numbers
Pls Anyone Help Me Here, I Dont Get The Resultz On The Explanation Above
-
Nov 24th, 2008, 06:55 AM
#12
Re: Tutorial - Random Numbers
Welcome to VBForums
As the code uses Debug.Print, the numbers will be printed to the Immediate window - if it isn't visible, select it on the View menu.
-
Jan 12th, 2010, 05:08 AM
#13
New Member
Re: Tutorial - Random Numbers
Your Random Number tutorial is extremly helpful so firstly id like to thank you for posting it.
Would it be possible to change the above code (1st option) so that you could call a list of random numbers one at a time using a command button?
Thanks again
Robert Stevenson
-
Feb 17th, 2010, 09:40 AM
#14
New Member
Re: Tutorial - Random Numbers
Hi,
This is really very useful for the new vb programmers.
-
Jun 8th, 2010, 04:02 PM
#15
New Member
Re: Tutorial - Random Numbers
Dim randomnumber As New Random
MessageBox.Show(randomnumber.Next())
only number between 1 and 9
Dim randomnumber As New Random
MessageBox.Show(randomnumber.Next(1,9))
-
Jun 8th, 2010, 05:54 PM
#16
Re: Tutorial - Random Numbers
I don't think that is VB6.
Visual Basic.NET and Classic Visual Basic are separated on this forum.
Take a look at the forum index and learn about all the different categories.
Delete it. They just clutter threads anyway.
-
Jun 9th, 2010, 01:11 AM
#17
Re: Tutorial - Random Numbers
Originally Posted by TheBigB
I don't think that is VB6.
Visual Basic.NET and Classic Visual Basic are separated on this forum.
Take a look at the forum index and learn about all the different categories.
It's not it's vb.net! ruipedromachado should have said so in his post. Although, seeing as there is no specification in the original post or the thread title regarding which Visual Basic version is being talked about I can see why he got confused.
when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
https://get.cryptobrowser.site/30/4111672
-
Jun 9th, 2010, 04:24 AM
#18
Re: Tutorial - Random Numbers [VB6 and earlier]
I've added VB6 to the thread title to save that kind of confusion in future.
-
Nov 1st, 2010, 10:44 AM
#19
PowerPoster
Re: Tutorial - Random Numbers [VB6 and earlier]
how is these possible?
the pc can random, always, the same number... in diferent executions... can anyone explain to me why?
-
Nov 1st, 2010, 11:19 AM
#20
Re: Tutorial - Random Numbers [VB6 and earlier]
You need to use the Randomize statement as shown in post #2.
If you want different numbers each time, call Randomize just once at the start of your program (eg: in Form_Load).
If you want to be able to repeat the same set of numbers, call Rnd with a negative argument first, and then Randomize with whatever number you want, eg:
Code:
Rnd -1
Randomize 2345
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|