Results 1 to 20 of 20

Thread: Tutorial - Random Numbers [VB6 and earlier]

  1. #1

    Thread Starter
    Super Moderator manavo11's Avatar
    Join Date
    Nov 2002
    Location
    Around the corner from si_the_geek
    Posts
    7,171

    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:
    1. Private Sub Form_Load()
    2.     Dim i As Integer
    3.     For i = 1 To 10
    4.         Debug.Print Rnd
    5.     Next
    6. 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.

  2. #2

    Thread Starter
    Super Moderator manavo11's Avatar
    Join Date
    Nov 2002
    Location
    Around the corner from si_the_geek
    Posts
    7,171
    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:
    1. Private Sub Form_Load()
    2.     Randomize
    3.     Dim i As Integer
    4.     For i = 1 To 10
    5.         Debug.Print Rnd
    6.     Next
    7. 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:
    1. Private Sub Form_Load()
    2.     Randomize 8
    3.     Dim i As Integer
    4.     For i = 1 To 10
    5.         Debug.Print Rnd
    6.     Next
    7. 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.

  3. #3

    Thread Starter
    Super Moderator manavo11's Avatar
    Join Date
    Nov 2002
    Location
    Around the corner from si_the_geek
    Posts
    7,171
    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:
    1. Int((upperbound - lowerbound + 1) * Rnd + lowerbound)

    Which can easily be put into a function :

    VB Code:
    1. Private Function RandomInteger(Lowerbound As Integer, Upperbound As Integer) As Integer
    2.     RandomInteger = Int((Upperbound - Lowerbound + 1) * Rnd + Lowerbound)
    3. End Function

    and an example of using it is :

    VB Code:
    1. Private Function RandomInteger(Lowerbound As Integer, Upperbound As Integer) As Integer
    2.     RandomInteger = Int((Upperbound - Lowerbound + 1) * Rnd + Lowerbound)
    3. End Function
    4.  
    5. Private Sub Form_Load()
    6.     Randomize 'Just once to start getting random numbers
    7.     MsgBox RandomInteger(1, 52)
    8. 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.

  4. #4

    Thread Starter
    Super Moderator manavo11's Avatar
    Join Date
    Nov 2002
    Location
    Around the corner from si_the_geek
    Posts
    7,171
    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:
    1. Option Explicit 'Force variable declaration
    2.  
    3. Private Sub Form_Load()
    4.     Dim Ar(1 To 100) As Integer 'The array to store it in
    5.     Dim i, j As Integer 'Counters for loops
    6.     Dim X As Integer 'Variable to store the random generated number
    7.     Dim bFound As Boolean 'Boolean to check if the value has been generated before
    8.    
    9.     Randomize 'Just once to ensure that we get random values
    10.    
    11.     For i = 1 To 100
    12.         Do 'Start the loop that generates a random number and checks if it has already been generated
    13.             X = RandomInteger(1, 100) 'Generate a random number
    14.             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
    15.             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)
    16.                 If Ar(j) = X Then 'If an item of the arrray is the same as the last generated number
    17.                     bFound = True 'Set the boolean to true (it already exists)
    18.                     DoEvents 'To not freeze until the looping is done
    19.                     Exit For 'Since we found it there is no need to check the rest
    20.                 End If
    21.             Next
    22.         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
    23.         Ar(i) = X 'Add it to the array
    24.     Next
    25.    
    26.     ShowInTextBox Text1, Ar 'Just to print the data and see it
    27. End Sub
    28.  
    29. Private Function RandomInteger(Lowerbound As Integer, Upperbound As Integer) As Integer 'The random number generator code
    30.     RandomInteger = Int((Upperbound - Lowerbound + 1) * Rnd + Lowerbound)
    31. End Function
    32.  
    33. Private Sub ShowInTextBox(TB As TextBox, A() As Integer) 'Just a sub to show the data in a textbox
    34.     Dim i As Integer
    35.    
    36.     TB.Text = ""
    37.    
    38.     For i = 1 To UBound(A)
    39.         TB.Text = TB.Text & CStr(A(i)) & vbCrLf
    40.     Next
    41.    
    42.     TB.Text = Left$(TB.Text, Len(TB.Text) - 2)
    43. 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:
    1. Option Explicit 'Force variable declaration
    2.  
    3. Private Sub Form_Load()
    4.     Dim Col As Collection 'The collection we will use to store the numbers
    5.     Dim Ar(1 To 100) As Integer 'The array to store the values from the collection
    6.     Dim i As Integer 'Counter for loops
    7.     Dim X As Integer 'Variable to store the random generated number
    8.    
    9.     Randomize 'Just once to ensure that we get random values
    10.    
    11.     Set Col = New Collection 'Get the collection ready to use
    12.    
    13.     For i = 1 To 100 'The possible numbers that we can have as a result is all the numbers from 1 to 100 so
    14.         Col.Add i 'add all the possible numbers to the collection
    15.     Next
    16.    
    17.     For i = 1 To 100 'Now to get the 100 numbers we added in the previous loop
    18.         X = RandomInteger(1, Col.Count) 'Get a random item from the collection (that exists for sure)
    19.         Ar(i) = Col.Item(X) 'Add it to the array
    20.         Col.Remove X 'Remove it so we don't add it again
    21.     Next
    22.    
    23.     ShowInTextBox Text1, Ar 'Just to print the data and see it
    24. End Sub
    25.  
    26. Private Function RandomInteger(Lowerbound As Integer, Upperbound As Integer) As Integer 'The random number generator code
    27.     RandomInteger = Int((Upperbound - Lowerbound + 1) * Rnd + Lowerbound)
    28. End Function
    29.  
    30. Private Sub ShowInTextBox(TB As TextBox, A() As Integer) 'Just a sub to show the data in a textbox
    31.     Dim i As Integer
    32.    
    33.     TB.Text = ""
    34.    
    35.     For i = 1 To UBound(A)
    36.         TB.Text = TB.Text & CStr(A(i)) & vbCrLf
    37.     Next
    38.    
    39.     TB.Text = Left$(TB.Text, Len(TB.Text) - 2)
    40. End Sub


    Has someone helped you? Then you can Rate their helpful post.

  5. #5

    Thread Starter
    Super Moderator manavo11's Avatar
    Join Date
    Nov 2002
    Location
    Around the corner from si_the_geek
    Posts
    7,171
    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:
    1. Option Explicit 'Force variable declaration
    2.  
    3. Private Declare Function GetTickCount Lib "kernel32" () As Long 'The GetTickCount
    4.                                                                 'function retrieves
    5.                                                                 'the number of
    6.                                                                 'milliseconds that
    7.                                                                 'have elapsed since
    8.                                                                 'Windows was started.
    9.  
    10. Private Sub Form_Load()
    11.     Dim Ar(1 To 10000) As Integer 'The array to store it in
    12.     Dim i, j As Integer 'Counters for loops
    13.     Dim X As Integer 'Variable to store the random generated number
    14.     Dim bFound As Boolean 'Boolean to check if the value has been generated before
    15.     Dim S As Long 'Variable to store the number of milliseconds that have elapsed since
    16.                   'Windows was started when we begin the task
    17.    
    18.     Randomize 'Just once to ensure that we get random values
    19.    
    20.     S = GetTickCount 'Store the number of milliseconds that have elapsed since Windows was started when we begin the task
    21.    
    22.     For i = 1 To 10000
    23.         Do 'Start the loop that generates a random number and checks if it has already been generated
    24.             X = RandomInteger(1, 10000) 'Generate a random number
    25.             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
    26.             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)
    27.                 If Ar(j) = X Then 'If an item of the arrray is the same as the last generated number
    28.                     bFound = True 'Set the boolean to true (it already exists)
    29.                     DoEvents 'To not freeze until the looping is done
    30.                     Exit For 'Since we found it there is no need to check the rest
    31.                 End If
    32.             Next
    33.         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
    34.         Ar(i) = X 'Add it to the array
    35.     Next
    36.    
    37.     'At the end we will subtract the number of milliseconds that had elapsed
    38.     'when the task started from the number of milliseconds that have elapsed
    39.     'when the task is complete and show it in the form's caption
    40.     Me.Caption = GetTickCount - S
    41.    
    42.     ShowInTextBox Text1, Ar 'Just to print the data and see it
    43. End Sub
    44.  
    45. Private Function RandomInteger(Lowerbound As Integer, Upperbound As Integer) As Integer 'The random number generator code
    46.     RandomInteger = Int((Upperbound - Lowerbound + 1) * Rnd + Lowerbound)
    47. End Function
    48.  
    49. Private Sub ShowInTextBox(TB As TextBox, A() As Integer) 'Just a sub to show the data in a textbox
    50.     Dim i As Integer
    51.    
    52.     TB.Text = ""
    53.    
    54.     For i = 1 To UBound(A)
    55.         TB.Text = TB.Text & CStr(A(i)) & vbCrLf
    56.         DoEvents
    57.     Next
    58.    
    59.     TB.Text = Left$(TB.Text, Len(TB.Text) - 2)
    60. End Sub

    And the collection code :

    VB Code:
    1. Option Explicit 'Force variable declaration
    2.  
    3. Private Declare Function GetTickCount Lib "kernel32" () As Long 'The GetTickCount
    4.                                                                 'function retrieves
    5.                                                                 'the number of
    6.                                                                 'milliseconds that
    7.                                                                 'have elapsed since
    8.                                                                 'Windows was started.
    9.  
    10. Private Sub Form_Load()
    11.     Dim Col As Collection 'The collection we will use to store the numbers
    12.     Dim Ar(1 To 10000) As Integer 'The array to store the values from the collection
    13.     Dim i As Integer 'Counter for loops
    14.     Dim X As Integer 'Variable to store the random generated number
    15.     Dim S As Long 'Variable to store the number of milliseconds that have elapsed since
    16.                   'Windows was started when we begin the task
    17.    
    18.     Randomize 'Just once to ensure that we get random values
    19.    
    20.     Set Col = New Collection 'Get the collection ready to use
    21.    
    22.     S = GetTickCount 'Store the number of milliseconds that have elapsed since Windows was started when we begin the task
    23.    
    24.     For i = 1 To 10000 'The possible numbers that we can have as a result is all the numbers from 1 to 100 so
    25.         Col.Add i 'add all the possible numbers to the collection
    26.     Next
    27.    
    28.     For i = 1 To 10000 'Now to get the 100 numbers we added in the previous loop
    29.         X = RandomInteger(1, Col.Count) 'Get a random item from the collection (that exists for sure)
    30.         Ar(i) = Col.Item(X) 'Add it to the array
    31.         Col.Remove X 'Remove it so we don't add it again
    32.     Next
    33.        
    34.     'At the end we will subtract the number of milliseconds that had elapsed
    35.     'when the task started from the number of milliseconds that have elapsed
    36.     'when the task is complete and show it in the form's caption
    37.     Me.Caption = GetTickCount - S
    38.    
    39.     ShowInTextBox Text1, Ar 'Just to print the data and see it
    40. End Sub
    41.  
    42. Private Function RandomInteger(Lowerbound As Integer, Upperbound As Integer) As Integer 'The random number generator code
    43.     RandomInteger = Int((Upperbound - Lowerbound + 1) * Rnd + Lowerbound)
    44. End Function
    45.  
    46. Private Sub ShowInTextBox(TB As TextBox, A() As Integer) 'Just a sub to show the data in a textbox
    47.     Dim i As Integer
    48.    
    49.     TB.Text = ""
    50.    
    51.     For i = 1 To UBound(A)
    52.         TB.Text = TB.Text & CStr(A(i)) & vbCrLf
    53.         DoEvents
    54.     Next
    55.    
    56.     TB.Text = Left$(TB.Text, Len(TB.Text) - 2)
    57. 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.

  6. #6

    Thread Starter
    Super Moderator manavo11's Avatar
    Join Date
    Nov 2002
    Location
    Around the corner from si_the_geek
    Posts
    7,171
    The End

    Well, that's all folks!
    This is the end of this tutorial about random numbers. I hope you found it useful and helpful so your programming days from now on will be easier.

    If you have any questions regarding this tutorial, don't be shy, drop me an e-mail and I'll gladly help you.

    Thanks,
    manavo
    Last edited by manavo11; Oct 12th, 2008 at 09:55 AM.


    Has someone helped you? Then you can Rate their helpful post.

  7. #7
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,927
    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.

  8. #8
    New Member
    Join Date
    Sep 2007
    Posts
    4

    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.

  9. #9
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,927

    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.

  10. #10
    New Member
    Join Date
    Sep 2007
    Posts
    4

    Re: Tutorial - Random Numbers

    Thank you,

    I will post it on the VB.Net forum, as you suggested.

  11. #11
    New Member
    Join Date
    Nov 2008
    Posts
    1

    Re: Tutorial - Random Numbers

    Pls Anyone Help Me Here, I Dont Get The Resultz On The Explanation Above


  12. #12
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,927

    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.

  13. #13
    New Member
    Join Date
    Jan 2010
    Posts
    3

    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

  14. #14
    New Member
    Join Date
    Feb 2010
    Posts
    1

    Smile Re: Tutorial - Random Numbers

    Hi,

    This is really very useful for the new vb programmers.

  15. #15
    New Member
    Join Date
    Mar 2010
    Posts
    5

    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))

  16. #16
    Frenzied Member TheBigB's Avatar
    Join Date
    Mar 2006
    Location
    *Stack Trace*
    Posts
    1,511

    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.

  17. #17
    PowerPoster Nightwalker83's Avatar
    Join Date
    Dec 2001
    Location
    Adelaide, Australia
    Posts
    13,344

    Re: Tutorial - Random Numbers

    Quote Originally Posted by TheBigB View Post
    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

  18. #18
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,927

    Re: Tutorial - Random Numbers [VB6 and earlier]

    I've added VB6 to the thread title to save that kind of confusion in future.

  19. #19
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,897

    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?
    VB6 2D Sprite control

    To live is difficult, but we do it.

  20. #20
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,927

    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
  •  



Click Here to Expand Forum to Full Width