1

using:

Image[] icons = { image12, image9, image11, image12, image10, image9, image11, image1,  image12, image9, image11, image10, image12, image9, image10, image11, image9, image10, image12, image11 };
    for (int i = 0; i < 20; i++)
    {
        newicon[i] = icons[rnd.Next(0, 19)];
    }

I am attempting to take the list of "icons" and scramble them without repeating them

basically I need 1 image1, 5 image9, 4 image10, 5 image11, and 5 image12's to output, But no more than that amount of each. Everything I have tried ends up with more other images and no image1 or multiple image1's.

I have done this with numbers, which tends not to be a problem, but I can not figure out the images. Also I cant find anything on shuffling images in a list without repeating.

user2296611
  • 61
  • 2
  • 9

2 Answers2

5

Why not just shuffle the array and then iterate through it? It's quite simple; here's an implementation of the Fisher-Yates shuffle, which shuffles the array with just one pass:

void Shuffle(Images[] images) {
   for (int i = 0; i < images.Length - 1; i++) {
      int j = rnd.Next(i, images.Length);
      Image temp = images[j];
      images[j] = images[i];
      images[i] = temp;
   }
}

Then just call Shuffle and go through the array

Images[] icons = { ... };
Shuffle(icons);
for (int i = 0; i < 20; i++)
   newicon[i] = icons[i];
Zong
  • 6,160
  • 5
  • 32
  • 46
  • I read up on that but i am fairly new to C# still and I don't know how to take that out put and use it on the next step createboard(newicon[0], newicon[1], newicon[2], newicon[3], newicon[4], newicon[5], newicon[6], newicon[7], newicon[8], newicon[9], newicon[10], newicon[11], newicon[12], newicon[13], newicon[14], newicon[15], newicon[16], newicon[17], newicon[18], newicon[19]); createboard basically takes 20 images and puts them in their place, I use a function with that many arguments? because I have to createboards for many different outcomes – user2296611 May 30 '13 at 04:48
  • What you would do is shuffle the list then just take the first 20 items from the list. – Scott Chamberlain May 30 '13 at 04:50
  • @user2296611 Well, I don't know what you mean by all those newicons, and it's outside the scope of this question. If you need more help and it's appropriate according to the guidelines, post a new question. – Zong May 30 '13 at 04:51
  • Why wouldn't you just have the `createboard` method take an array as an input? Instead of having to send every single element individually. – Snixtor May 30 '13 at 04:54
  • It still repeats but I get what your saying by out of the scope of the question so ill keep looking it still puts me in the right direction thanks – user2296611 May 30 '13 at 04:59
  • What do you mean it still repeats, if you did it correctly no two items in the array should show up twice unless you put it in there twice. – Scott Chamberlain May 30 '13 at 05:00
  • @Snixtor good point after I typed copied all that earlier and added the comment i started to change it to take the array instead of one at a time – user2296611 May 30 '13 at 05:00
  • @scott after I chanaged it to take an array instead of individual images I ran it 3 times for some reason what im getting is like this: firsttime: 10 image10, 1 image9, 2 image11, 5 image12, 2 image1 secondtime: 8 image10, 6 image9, 5image11, 1 image1, no image12 thirdtime: 10 image9, 7 image11, 2 image10, and 1 image5, no image1 – user2296611 May 30 '13 at 05:19
  • I have no clue what you are typing means. You will need to post a new question and give details of what is going wrong. – Scott Chamberlain May 30 '13 at 05:20
2

Using LINQ you can make it even easier than a Fisher-Yates shuffle to shuffle an IEnumerable (which an array is). It is as simple as

var shuffledList = sourceList.OrderBy(_ => rng.Next());

where rng is a random number generator (be sure to implment Random correctly).

Your code would look something like this

private void Foo()
{
    Image[] icons = { image12, image9, image11, image12, image10, image9, image11, image1,  image12, image9, image11, image10, image12, image9, image10, image11, image9, image10, image12, image11 };
    var shuffeledIcons = icons.OrderBy(_ => rng.Next()).ToArray();

    createBoard(shuffeledIcons);
}

private void createBoard(Image[] icons)
{
    //...
}
Community
  • 1
  • 1
Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
  • The caveat is that it requires `O(n ln n)` running time because it relies on sorting. Fisher-Yates is `O(n)`. It might not matter for 20 items, but it's good to know the difference. – Mike Zboray May 30 '13 at 04:58
  • This is what I needed. I didnt even notice this while I was trying the first response. Every time I run it it does exactly what I wanted, no repeating. I dont know what I did wrong on the other one but I couldnt get it to stop repeating this one doesnt. – user2296611 May 30 '13 at 15:13