Random listbox item selection with no "repeat"

K

kimiraikkonen

Hi,
I'd asked similiar question before but couldn't get help. I have a
listbox and and items (eg: 10 items, or more or less,depends). I want
to create a shuffle (random) list with NO "repeat".

I mean, think about media player's playlists, like them, i want my
playlist item to be selected for only "once" with no repeat.

I used this simple code block but it didn't help because it may
frequently repeats the same item in next selection which isn't the
thing i want to have:

Dim shuffle as new Random
listBox1.SelectedIndex = shuffle.Next ( 0, listBox1.Items.Count - 1 )



Then tried some system.collections namespace work with no solid
change.

So, shortly my intention is to select listbox items for "once" with
random order (shuffle) like media player's playlists, and when all the
items have been selected, i want to display "no item left unselected"
msgbox.

That's all i want to implement.

Any help will be greatly appreciated.

Thanks!
 
J

Jan Hyde (VB MVP)

kimiraikkonen <[email protected]>'s wild thoughts
were released on Mon, 31 Dec 2007 03:10:58 -0800 (PST)
bearing the following fruit:
Hi,
I'd asked similiar question before but couldn't get help. I have a
listbox and and items (eg: 10 items, or more or less,depends). I want
to create a shuffle (random) list with NO "repeat".

What you are not doing is any actual shuffling. Think of a
pack of cards you are about to deal.

You don't take one at random from the pack, then then next
one at random; you shuffle the order of the cards (randomly)
then select the top card, remove it from the pack, then take
the top card again.

So, shuffle your list then select each item in turn; how you
display the list to the user is up to you.

J
 
C

Cor Ligthert[MVP]

Kimi,

Although Jan's answer is of cource completely correct would I in your case
everytime remove the played item from the Listbox Items.

To try this it is just 2 listboxes dragged on your form and 1 button
\\\
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Me.ListBox1.Items.Clear()
Me.ListBox1.Items.AddRange(New Object() _
{"Bach", "Beethoven", "Brahms", "Debussy", "Handel", "Mozart",
"Ravel", "Strauss", "Wagner"})
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles
Button1.Click
If ListBox1.Items.Count > 0 Then
Dim shuffle As New Random(Now.Millisecond)
ListBox1.SelectedIndex = shuffle.Next(0, ListBox1.Items.Count)
ListBox2.Items.Add(ListBox1.SelectedItem)
ListBox1.Items.RemoveAt(ListBox1.SelectedIndex)
ListBox1.SelectedIndex = -1
End If
End Sub
End Class
///

In this sample is the randomizing as well done better than in your sample
which did not give real random results.
However an even better way for this is here.

http://www.vb-tips.com/RandomNumbers.aspx

Be aware that the Wagner here is meant Richard, not Herfried,

Cor
 
K

kimiraikkonen

Kimi,

Although Jan's answer is of cource completely correct would I in your case
everytime remove the played item from the Listbox Items.

To try this it is just 2 listboxes dragged on your form and 1 button
\\\
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Me.ListBox1.Items.Clear()
Me.ListBox1.Items.AddRange(New Object() _
{"Bach", "Beethoven", "Brahms", "Debussy", "Handel", "Mozart",
"Ravel", "Strauss", "Wagner"})
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles
Button1.Click
If ListBox1.Items.Count > 0 Then
Dim shuffle As New Random(Now.Millisecond)
ListBox1.SelectedIndex = shuffle.Next(0, ListBox1.Items.Count)
ListBox2.Items.Add(ListBox1.SelectedItem)
ListBox1.Items.RemoveAt(ListBox1.SelectedIndex)
ListBox1.SelectedIndex = -1
End If
End Sub
End Class
///

In this sample is the randomizing as well done better than in your sample
which did not give real random results.
However an even better way for this is here.

http://www.vb-tips.com/RandomNumbers.aspx

Be aware that the Wagner here is meant Richard, not Herfried,

Cor

Cor,
I've done this before your post and tested, yes removing selected item
prevents that item from to be selected in next selection, but the
exact thing i wanted to do is to "leave" all the items there and
select them randomly each one for once like Windows Media Player.

If i remove selected item from listbox, yes it's avoided to be
selected for twice or more "but" the user won't be able to play/select
"same/this" list's items randomly again till it re-creates a list.

Regards.
 
C

Cor Ligthert[MVP]

Kimi,

I've done this before your post and tested, yes removing selected item
prevents that item from to be selected in next selection, but the
exact thing i wanted to do is to "leave" all the items there and
select them randomly each one for once like Windows Media Player.

If i remove selected item from listbox, yes it's avoided to be
selected for twice or more "but" the user won't be able to play/select
"same/this" list's items randomly again till it re-creates a list.
Be aware that your randomizing is on 2 places wrong, your randomizing will
without that milliseconds forever give the same results while the use you do
will keep the latest always as last. However have a look at that method on
our website if you want it truly randomized.

(It is not from me, it is from Ken)

Cor
 
K

kimiraikkonen

Kimi,





Be aware that your randomizing is on 2 places wrong, your randomizing will
without that milliseconds forever give the same results while the use you do
will keep the latest always as last. However have a look at that method on
our website if you want it truly randomized.

Cor,
Sorry, i couldn't make out what you meant.(maybe about English)
However, where's the link of website that you mentioned?

Thanks.
 
K

kimiraikkonen

" list's items randomly again till it re-creates a list.



Simple your Randomize method is 2 times wrong.

The link was in the previous message

http://www.vb-tips.com/RandomNumbers.aspx

Cir

Thanks for the link, however the first idea (removing selected item)
does a very good job for avoiding the same item to be selected more
than once by being removed in random order.

Regards.
 
T

Tom Shelton

Kimi,





Be aware that your randomizing is on 2 places wrong, your randomizing will
without that milliseconds forever give the same results while the use you do
will keep the latest always as last. However have a look at that method on
our website if you want it truly randomized.

(It is not from me, it is from Ken)

Cor

Cor,

I respectfully have to correct you here... Unless the OP is creating
his random class using the constructor that takes and integer
argument, and passing in a constant value, he will NOT get the same
list. The default constructor of the Random class is essentially
equivalent to what your doing - it generates a time based seed value.
 
T

Tom Shelton

Cor,
I've done this before your post and tested, yes removing selected item
prevents that item from to be selected in next selection, but the
exact thing i wanted to do is to "leave" all the items there and
select them randomly each one for once like Windows Media Player.

If i remove selected item from listbox, yes it's avoided to be
selected for twice or more "but" the user won't be able to play/select
"same/this" list's items randomly again till it re-creates a list.

Regards.

You have a few choices depending on the behavior you want... You can
pre-generate the list - which would essentially be create a string
array the size of you list, and then randomly insert strings into
it... something like:

foreach song as string in songs
index = rnd.next(0, listsize)

' you need to make sure you don't over-write another item
while (not string.isnullorempty(list(index))
index = rnd.next(0, listsize)
end while
list(index) = song
next
' play the songs
playlist (list)


You could also keep a list of integers that tell contains all the
selected random numbers. You could also make your listitems objects
that know if they have been selected, so you can ask them.

In other words, there are lots of ways to do this. My inclination
would be to create a playlist class that had a list of items, the
items would then have a property that the list could check to see if
it has already been played in the current session.
 
C

Cor Ligthert[MVP]

Tom,

It was not only the randomizer, he has selected as well forever the last row
as the latest in his own code.
(I was only seeing it while I made my sample)

:)

Cor
 
C

Cor Ligthert[MVP]

Tom,
I respectfully have to correct you here... Unless the OP is creating
his random class using the constructor that takes and integer
argument, and passing in a constant value, he will NOT get the same
list. The default constructor of the Random class is essentially
equivalent to what your doing - it generates a time based seed value.

I was thinking it over. You are most probably right, I had that idea too,
however I got everytime the same result when I tested my sample. However it
can be (I did not try it again) I had that idea, probably was only Wagner
wrong in this (not our Wagner).

Cor
 
K

kimiraikkonen

Tom,


I was thinking it over. You are most probably right, I had that idea too,
however I got everytime the same result when I tested my sample. However it
can be (I did not try it again) I had that idea, probably was only Wagner
wrong in this (not our Wagner).

Cor

I agree Tom, I tried mine(not Cor's) with different random selection
results, and as i stated previously, removing selected item avoids re-
selection when random selection is being used.

In my code, i used "remove current selected item" before a new random
selection occurs in order to eliminate re-selection of the same item
using with only one listbox as follows:

ListBox1.Items.Remove(ListBox1.SelectedItem)
Dim shuffle As New Random
ListBox1.SelectedIndex = shuffle.Next(0, ListBox1.Items.Count)

Interesting algorithm, but works.

Works OK but i wish i solved the issue without being forced to remove
previously selected item.

Regards.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top