Mademan
Mademan

Reputation: 1

Generate random numbers, that won't show up again, unknown number pool

Hello , I wrote a program, that shows any pictures in the folder, the .exe is in. It contains a button, which 'randomly' chooses another picture and shows that. It worked so far.

What I wanted to do next is, that the button selects a picture, that has not been chosen before. And only when every picture was shown, the program should reset and start again showing all pictures.

But when I now start the program, it shows one pic and thats it. The button doesn't do anything visible, you can't change the first pic - and I don't know why. (I saw the questions which are similiar, like the blackjack-topic. But in my case, I don't know how many pictures there are gonna be, so I can't create a fix pool of randomed numbers and remove them from that list or something like that).

So here's my code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace randompix
{
    public partial class Form1 : Form
    {

        int i = 0;
        Random rnd = new Random();
        string pfad = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
        IEnumerable<string> allebilder; // Will contain every filename of the folder
        List<int> wdhlist = new List<int>(); //will contain 'i' that was already used



        public Form1()
        {
            InitializeComponent();
            this.WindowState = FormWindowState.Maximized;
            pBox1.Anchor = (AnchorStyles.Bottom | AnchorStyles.Right | AnchorStyles.Left | AnchorStyles.Top);
            pBox1.SizeMode = PictureBoxSizeMode.Zoom;
            btn2.Anchor = (AnchorStyles.Top | AnchorStyles.Right);

            allebilder = Directory.EnumerateFiles(pfad); 
            wdhlist.Add(i);

            if (allebilder.ElementAt<string>(i).EndsWith(".jpg") || allebilder.ElementAt<string>(i).EndsWith(".jpeg") || allebilder.ElementAt<string>(i).EndsWith(".png") || allebilder.ElementAt<string>(i).EndsWith(".gif") || allebilder.ElementAt<string>(i).EndsWith(".bmp"))
            {
                pBox1.ImageLocation = allebilder.ElementAt<string>(i);
                label1.Text = allebilder.ElementAt<string>(i);
            }

            else 
            {
                if (i == 0) // because 0 is already added 
                {
                    i = rnd.Next(allebilder.Count<string>());
                }
                else
                {
                    wdhlist.Add(i);
                    i = rnd.Next(allebilder.Count<string>());
                }
            }
        }

        private void btn1_Click(object sender, EventArgs e)
        {
            i = rnd.Next(allebilder.Count<string>());
            wdhlist.Add(i);

            if (wdhlist.Count() >= allebilder.Count<string>())
            {
                wdhlist.Clear();
            }

            else
            {
                if (wdhlist.Contains(i))
                {
                    i = rnd.Next(allebilder.Count<string>());
                    wdhlist.Add(i);
                }

                else
                {
                    if (allebilder.ElementAt<string>(i).EndsWith(".jpg") || allebilder.ElementAt<string>(i).EndsWith(".jpeg") || allebilder.ElementAt<string>(i).EndsWith(".png") || allebilder.ElementAt<string>(i).EndsWith(".gif") || allebilder.ElementAt<string>(i).EndsWith(".bmp"))
                    {
                        if (allebilder.ElementAt<string>(i) == null)
                        {
                            MessageBox.Show("Nope");
                        }

                        else
                        {
                            label1.Text = allebilder.ElementAt<string>(i);
                            pBox1.ImageLocation = allebilder.ElementAt<string>(i);
                        }
                    }
                    else
                    {
                        i = rnd.Next(allebilder.Count<string>());
                        wdhlist.Add(i);
                    }
                }
            }
        }

        private void btn1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                btn1_Click(sender, e);
            }
        }

        private void btn2_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Version 0.3\n\nUse: Copy .exe in a folder with pictures\nSupports .jpg, .gif, .png and .bmp\n\nProgram by Fabian Schmidt\nIcon by Aleksandra Wolska\n(https://www.iconfinder.com/iconsets/49handdrawing)");
            btn1.Focus();
        }
    }
}

Upvotes: 0

Views: 226

Answers (2)

Rune FS
Rune FS

Reputation: 21742

You could create a sequence of the images in random order and then when the list is use in full recreate a sequence

private Random rnd = new Random();
private IEnumerable<string> GetImagesInRandomOrder(){
    return Directory.EnumerateFiles(pfad).OrderBy(x => rnd.Next());
}

private IEnumerator<string> randomImages = 
          Enumerable.Empty<string>.GetEnumerator();

private string GetNextImage(){
       if(!randomImages.MoveNext()){
          randomImages = GetImagesInRandomOrder().GetEnumerator();
          if(!randomImages.MoveNext()){ 
              throw new InvalidOperationException("No images"); 
          }   
       }
       return randomImages.Current;
}

Then you'd use it like so:

DoSomeThingWithImage(GetNextImage());

Upvotes: 0

csharp newbie
csharp newbie

Reputation: 638

You need to form a list filenames of your images. Then form a list of indexes - from 0 to amount of that images in a list.

List<int> numberList = Enumerable.Range(0, imagesList.Count).ToList();

Then you get random number from 0 to that numberList.Count

int randomValue = numberList[rnd.Next(0, numberList.Count)];

And after you use it, remove it from numberList

DoSomeThingWithImage(imagesList[randomValue]);
numberList.Remove(randomValue);

So you'll have non-repeating random images until they all don't appear. Then do this all over again. Hope that helps.

Upvotes: 1

Related Questions