locked
Random Lottery Number Generator RRS feed

  • Question

  • I need some beginner Visual Basic help.  I have to write a code that displays in a label, 6 unique random numbers from 1 to 54.  When I run the program it only displays 1 number (6).  What am I doing wrong?

     

    Private Sub xDisplayButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles xDisplayButton.Click

    Dim RandomGen As New Random

    Dim LottoPick(5) As Double

    Dim LottoNum As Integer

     

    For LottoNum = 1 To 5

    LottoPick(LottoNum) = RandomGen.Next(1, 55)

    Next LottoNum

    Me.xLotteryLabel.Text = Me.xLotteryLabel.Text & LottoNum.ToString("N0")

    End Sub

    Friday, November 23, 2007 10:10 PM

Answers

  • There are several issues with your code:

     

    1.  You are only picking 5 numbers.  To do 6 your loop should run from 0 to 5

     

    2.  You are updating the label outside the loop so it will only get one value.  You should move the label update to inside the loop.

     

    3.  The value you are putting in the label is the counter value where it should be the randomly generated number.

     

    4.  Your label update code doesn't separate the numbers.  You need to add spaces, or commas or something to distinguish the numbers.

     

    If you fix all that then you should finish up with 6 numbers in your label.  However there is no guarantee that they will all be different.

     

    To fix that you have several options.

     

    One would be to put the number generation into a Do Until loop, checking whether or not the number selected is already included in the list.

     

    Another would be to create a list of all the possible numbers (1 to 54), pick one at random and remove it from the list before picking another one (with acknowledgement to JohnWein for the method)

     

    I suggest you get the first 4 issues sorted first.  Then post again if you have trouble making them unique.

    Friday, November 23, 2007 11:12 PM
  • For LottoNum = 0 To 5

     

    John, there are statistical differences and Solitaires method is not the correct method in this case. Solitaire's method excludes drawing the same number. I keep saying over and over again that real random sequences repeat. Decks are card do not. That is not random.

     

    A statistical way of saying this is that a random distribution will have predictable properities that will be statistically different from the number series produced by solitaire's shuffle.

     

    "I think the Solitaire shuffle is a better method of selecting unique numbers."

     

    Random does not equal "unique".

    Saturday, November 24, 2007 2:14 AM
  •  

    Using the Shuffle Sort and extracting the first 6 results is the preferred way. 

     

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1028588&SiteID=1

     

    But with only 6 unique numbers to select, you can also do it using two nested For-Next loops.  Here is how:

     

    First declare an array to hold 6 elements.

     

    The outer For loop will repeat 6 times.  The inner loop will repeat one less than the current iteration of the outer loop.

     

    The outer loop will select a random number between 1 and 54, saving it to the current array element.

     

    The inner loop will test each of the array elements up to the one before the current one to see if it's the same as the selected number.  If it's the same, it will decrement the control variable of the outer loop, exit the inner loop, and select a different random number in the outer loop, replacing the number in the current array element.

     

    Saturday, November 24, 2007 6:43 PM
  • or with just a single loop (well a visible one anyway)

     

    Dim Rnd As New Random

    Dim RndNumber As Integer

    Dim Numbers As New List(Of Integer)

    For X As Integer = 0 To 5

    Do

    RndNumber = Rnd.Next(1, 55)

    Loop While Numbers.Contains(RndNumber)

    Numbers.Add(RndNumber)

    Next

     

    Saturday, November 24, 2007 7:08 PM

All replies

  • There are several issues with your code:

     

    1.  You are only picking 5 numbers.  To do 6 your loop should run from 0 to 5

     

    2.  You are updating the label outside the loop so it will only get one value.  You should move the label update to inside the loop.

     

    3.  The value you are putting in the label is the counter value where it should be the randomly generated number.

     

    4.  Your label update code doesn't separate the numbers.  You need to add spaces, or commas or something to distinguish the numbers.

     

    If you fix all that then you should finish up with 6 numbers in your label.  However there is no guarantee that they will all be different.

     

    To fix that you have several options.

     

    One would be to put the number generation into a Do Until loop, checking whether or not the number selected is already included in the list.

     

    Another would be to create a list of all the possible numbers (1 to 54), pick one at random and remove it from the list before picking another one (with acknowledgement to JohnWein for the method)

     

    I suggest you get the first 4 issues sorted first.  Then post again if you have trouble making them unique.

    Friday, November 23, 2007 11:12 PM
  • Dave299:

    I think the Solitaire shuffle is a better method of selecting unique numbers.  Shuffle the list or array and then take the number of numbers you want from it.  This mimics the drawing of cards or the drawing of lotto numbers from a container.

    Friday, November 23, 2007 11:27 PM
  • John

     

    Maybe - I can't really see a lot of difference between that and your way.

     

    I tend to use the first method I suggested.  If you only want to draw a small selection from a large number of options it is probably the most efficient and simpler to code.

    Saturday, November 24, 2007 1:45 AM
  • Thanks for the help!

    I got it to display a random number, now how can I code it to display all 6?

    Saturday, November 24, 2007 1:58 AM
  • For LottoNum = 0 To 5

     

    John, there are statistical differences and Solitaires method is not the correct method in this case. Solitaire's method excludes drawing the same number. I keep saying over and over again that real random sequences repeat. Decks are card do not. That is not random.

     

    A statistical way of saying this is that a random distribution will have predictable properities that will be statistically different from the number series produced by solitaire's shuffle.

     

    "I think the Solitaire shuffle is a better method of selecting unique numbers."

     

    Random does not equal "unique".

    Saturday, November 24, 2007 2:14 AM
  • Renee:

    You are confusing the Random distribution with Random variables.  Different animals.  We are using a Random distribution to model real world situations.

    Saturday, November 24, 2007 10:22 AM
  • bangib

     

    That was my point no: 2.  As you have your code currently the label is updated only after the loop has exited.  To update it with all the numbers you need to have that line inside the loop.

     

    Alternatively you could create another loop to update the label with all the numbers you have entered into the array.

    Saturday, November 24, 2007 10:41 AM
  •  

    No, I'm not confusing them John. Using a shuffle you are not getting truly random numbers. You are getting randomly selected numbers which are mutually exclusive. With your method, you'll never see a number like 664 or  464. Random number have repeats. Pulling the numbers from a shuffle you won't get repeats.
    Saturday, November 24, 2007 2:06 PM
  •  

    Using the Shuffle Sort and extracting the first 6 results is the preferred way. 

     

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1028588&SiteID=1

     

    But with only 6 unique numbers to select, you can also do it using two nested For-Next loops.  Here is how:

     

    First declare an array to hold 6 elements.

     

    The outer For loop will repeat 6 times.  The inner loop will repeat one less than the current iteration of the outer loop.

     

    The outer loop will select a random number between 1 and 54, saving it to the current array element.

     

    The inner loop will test each of the array elements up to the one before the current one to see if it's the same as the selected number.  If it's the same, it will decrement the control variable of the outer loop, exit the inner loop, and select a different random number in the outer loop, replacing the number in the current array element.

     

    Saturday, November 24, 2007 6:43 PM
  •  

    Whose preference is it and for what specific application is it "the preferred way".

     

    I like your method for mutually exclusive aplications. But calling your way in nested do loops? Is that not redunctant and slower functionality that using the random class itself? Has anyone evey done any histograms and looked at the resulting distributions and found in deficiencies in the random class?

    Saturday, November 24, 2007 7:04 PM
  • or with just a single loop (well a visible one anyway)

     

    Dim Rnd As New Random

    Dim RndNumber As Integer

    Dim Numbers As New List(Of Integer)

    For X As Integer = 0 To 5

    Do

    RndNumber = Rnd.Next(1, 55)

    Loop While Numbers.Contains(RndNumber)

    Numbers.Add(RndNumber)

    Next

     

    Saturday, November 24, 2007 7:08 PM
  •  

    exactly what i had in mind, dave.......
    Saturday, November 24, 2007 7:22 PM
  • Renee:  I introduced the Nested solution as an exercise in logic for a student to work out, if they haven't yet learned how to use the Shuffle Sort.  I will be presenting that as a challenge for my own students.  It's not meant to be more or less efficient than any other technique, just a mental exercise.  Obviously, the OP posted the problem as a homework assignment.

     

    Dave's solution is interesting.  But the student should not attempt to use code that was not yet learned in class, since it's an obvious tip-off that he/she didn't work out the solution on his/her own.

     

     

    Saturday, November 24, 2007 7:22 PM
  •  

    You are indeed a great teacher, Solitaire!
    Saturday, November 24, 2007 7:25 PM
  • I don't know what made me think it was only a single loop as there are clearly two and probably three if you take the .Contains into account.  Still it's easier to code.

     

    I had guessed it was a homework assignment which is why I was avoiding posting code up until that point.

     

    Saturday, November 24, 2007 7:46 PM
  •  

    What's wrong with this?

     

    Dim Foo as integer = rnd.next(0,9)

    For i as integer = 1 to 4

          Foo = foo *10 + rnd.next(0,9)

    Next

     

    or even

     

    Dim Foo = rnd.next(0,999999)

    Saturday, November 24, 2007 7:50 PM
  • Thank you, Renee.  I do put a lot of time and effort into my lesson plans.  I create my own syllabus and demo programs, more than enough to write my own textbook.  Each lesson builds on the previous one, making use only of the concepts which have been learned to date.  At the end of every class lecture, I present a problem based on the latest concepts learned during the lecture for students to solve during the lab session.  I work out the problem and solution beforehand to make sure the students will be able to manage it within the alloted time, although we do end up running overtime more often than not.  Watching the students work gives me a good indication of their skill levels.  Slower students will need to be given hints along the way.  I also prepare more challenging options for faster students.

     

     

     

     

     

    Saturday, November 24, 2007 8:03 PM
  • I have no doubt Solitaire. I don't think there can be enough applause for you.....

    Saturday, November 24, 2007 8:15 PM