2

Ok, I have been working on this all day.. I am stuck. Am I just missing something that won't allow me to force the random function to make sure it goes through the list before cycling the list again? The issue is it shows the same item sometimes in a row. So my goal is to get an "itunes" like function that it makes sure when it shuffles, it does NOT hit an already "shown" item.

My current code:

Dim rng As New System.Random()
    Dim RAND(16) As String
    RAND(0) = "A"
    RAND(1) = "B"
    RAND(2) = "C"
    RAND(3) = "D"
    RAND(4) = "E"
    RAND(5) = "F"
    RAND(6) = "G"
    RAND(7) = "H"
    RAND(8) = "I"
    RAND(9) = "J"
    RAND(10) = "K"
    RAND(11) = "L"
    RAND(12) = "M"
    RAND(13) = "N"
    RAND(14) = "O"
    RAND(15) = "P"
    RAND(16) = "Q"
    If TextBox1.Text = 'Current Text
    Then
    TextBox1.Text = ("""" & RAND(rng.Next(RAND.Count())) & """")
    End If
CJSoldier
  • 541
  • 1
  • 7
  • 12

4 Answers4

3

Random numbers don't work that way. A truly random sequence has repeating numbers in it. The Random class will return duplicate numbers sometimes.

To meet your requirements, you will have to keep track of what has already been used, and not use those again.

Or better yet, instead of removing items from a list, just choose any two items at random and swap them. Do this a certain number of times -- say, 100 times. Then build a string by calling String.Join("", RAND). Like this (untested, but this should give you the right idea):

Dim rng As New System.Random()
Dim RAND(16) As String

' Initialize your array -- this is shorter than your code, 
' but does the same thing
For i As Integer = 0 to RAND.Length-1
    RAND(i) = Chr(i+65) 
Next

' Pick two random characters and swap them. Do this 100 times.
For i As Integer = 1 to 100
    Dim first As Integer = rng.Next(RAND.Length)
    Dim second As Integer = rng.Next(RAND.Length)
    Dim temp = RAND(first)
    RAND(first) = RAND(second)
    RAND(second) = temp
Next

TextBox1.Text = String.Join("", RAND)
Katie Kilian
  • 6,815
  • 5
  • 41
  • 64
1

Try a different approach. Make your RAND work like a list. When a letter is grabbed, actually remove it from the list. That involves removing it, filling the new empty space, and adjusting the count.

mcsilvio
  • 1,098
  • 1
  • 11
  • 20
0

Instead of Array you can use list of strings. After you use an item from the list - remove it. This way it is guaranteed not to be used again. E.g.:

Dim iRand As Integer    
Dim RAND As New List(of String)

RAND.Add("A")
RAND.Add("B")
RAND.Add("C")
RAND.Add("D")
RAND.Add("E")
RAND.Add("F")
RAND.Add("G")
RAND.Add("H")
RAND.Add("I")
RAND.Add("J")
RAND.Add("K")
RAND.Add("L")
RAND.Add("M")
RAND.Add("N")
RAND.Add("O")
RAND.Add("P")
RAND.Add("Q")

Randomize

Do While RAND.Count > 0
    iRand = Math.Floor(Rnd(1)*RAND.Count)
    Console.writeline(RAND(iRand))
    RAND.RemoveAt(iRand)
Loop

DEMO: http://dotnetfiddle.net/5SN3Bu

If you need to reuse the list again - simple reinitialize it to original values after you detect that it is empty and start removing items all over again.

Yuriy Galanter
  • 38,833
  • 15
  • 69
  • 136
0

Assuming this is declared first:

Dim RAND(16) As String
RAND(0) = "A"
'[...]
RAND(16) = "Q"

Here is a quick way to shuffle your letters (also works for any string):

Dim oRandom As New System.Random
Dim asShuffled As String() = RAND.OrderBy(Function() oRandom.Next).ToArray

Also see this:

Community
  • 1
  • 1
Victor Zakharov
  • 25,801
  • 18
  • 85
  • 151