Arianule
Arianule

Reputation: 9043

Trying to avoid displaying same image twice

I am displaying images using a picture box and am timing it in one second intervals. I am trying to avoid displaying the same image twice in succession and am using an arraylist to do this to avoid the same random image following on the other.

This is what I have done. Not working quite as well as I expected and eventually get an exception. How can I improve on this to avoid displaying the same image twice in succession?

Random random = new Random();
        ArrayList imagesList = new ArrayList();
        Image[] images = { imageOne, imageTwo, imageThree, imageFour, imageFive, imageSix, imageSeven };

        do
        {
            try
            {
                for (int i = 0; i < images.Length; i++)
                {

                    imagesList.Add(images[random.Next(0, 7)]);

                    while (imagesList.Contains(images[i]))
                    {
                        imagesList.Clear();
                        imagesList.Add(images[random.Next(0, 7)]);     

                    }
                    picImage.Image = (Image)imagesList[0];

                }

                Thread.Sleep(1000);
            }
            catch (IndexOutOfRangeException ind)
            {
                MessageBox.Show(ind.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (Exception exe)
            {
                MessageBox.Show(exe.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }


        } while (true);
    }

Upvotes: 2

Views: 540

Answers (2)

Mike Zboray
Mike Zboray

Reputation: 40818

Just reorder the images:

Image[] randomOrder = images.OrderBy(i => Guid.NewGuid()).ToArray();

and iterate through that array.

You also need to use a timer to change the image because you are currently blocking the UI thread. System.Windows.Forms.Timer would be appropriate. Your Tick event handler for the timer would look something like this:

private int index = 0;

private void Timer_Tick(Object sender, EventArgs args) 
{
  picImage.Image = randomOrder[index % randomOrder.Length];
  index++;
}

The MSDN sample code for this Timer class is also helpful. Note that there are several Timer classes available in the framework and this one would probably be the best here.

Upvotes: 2

Laurence
Laurence

Reputation: 1875

You could do a shuffle in stead of getting random numbers. Then you don't need to checking every time if an image is already used. Look here to see how you can shuffle an array: http://www.dotnetperls.com/shuffle. Now you can loop through the array, it is now randomized and you don't get duplicates.

I guess you use the sleep to avoid that you get the same random value every time? You could delete that now. Besides that, it will block the UI.

Upvotes: 5

Related Questions