J. Doe
J. Doe

Reputation: 13

How To Get A Certain Number of Random Colours To Fill A Grid - C#

I have a list of 7 colors : Red, Blue, Green, Maroon, Brown, Aqua and Black.

In my program I have it so you click on a box, and then the box gets filled with a colour. I want it to be a random colour (from my list of 7 colours) for every box, which I have managed to do below:

    Random random = new Random();
        int randomColour = random.Next(0,6);

        if (e.Button == MouseButtons.Left)
        {
            //got the y values of the grid

            //got the x values of the grid

            //Randomize The Colours
            if (randomColour == 0)
            {
                Form.GetTile(x, y).FrontColour = Color.Red;
                Score = Score + 1;
            }
            else if (randomColour == 1)
            {
                Form.GetTile(x, y).FrontColour = Color.Blue;
                Score = Score + 2;
            }
            else if (randomColour == 2)
            {
                Form.GetTile(x, y).FrontColour = Color.Maroon;
                Score = Score + 5;
            }
            else if (randomColour == 3)
            {
                Form.GetTile(x, y).FrontColour = Color.Aqua;
                Score = Score + 10;
            }
            else if (randomColour == 4)
            {
                Form.GetTile(x, y).FrontColour = Color.Black;
                Score = Score - 3;
            }
            else if (randomColour == 5)
            {
                Form.GetTile(x, y).FrontColour = Color.Brown;
                Score = Score - 1;
            }
            else if (randomColour == 6)
            {
                Form.GetTile(x, y).FrontColour = Color.Green;
                Score = Score + 3;
            }

However, I want to set up my code so there can only be a maximum of 20 red boxes, 20 blue boxes, 5 green, 5 brown, 4 aqua, 5 maroon, and 5 black.

This should be the output, except more shuffled.

The Form.GetTile(x,y).FrontColour is a property that I am accessing from another class that changes the colours of the box

Upvotes: 0

Views: 446

Answers (2)

Dave
Dave

Reputation: 987

Create a dictionary containing your own colors and then keep track of the number of times you have selected a color

Dictionary<string, int> dictionary = new Dictionary<string, int>();
dictionary.Add("Red", 20);
dictionary.Add("Blue", 20);
dictionary.Add("Green", 5);

Then randomly select an item from the dictionary and subtract the occurrence

bool colourSelected = false;
    do
    {
        var rnd = new Random();
        var randomEntry = dictionary.ElementAt(rnd.Next(0, dictionary.Count));
        String randomKey = randomEntry.Key;
        String randomValue = randomEntry.Value;
        if(randomvalue > 0)
        {
            // Take color
            // could also add in logic to remove a color once it reaches 0, 
            // this way we don't select colors that are unavailable 
            dictionary[randomKey] = randomValue - 1;
            colourSelected = true;
        }
    }
    while(colourSelected == false);

The code might need a little work, I haven't run it at all so there might be a few thing you will need to fix.

Upvotes: 0

Sten Petrov
Sten Petrov

Reputation: 11040

You can pre-shuffle a list of the numbers you want to apply

public class ShuffledChoices<T>{
   private readonly List<T> Choices;
   private Random rng = new Random();
   public ShuffledChoices(IEnumerable<T> choices){
     Choices = new List<T>(choices);
   }
   public T PickNext(){
     var i = rng.Next(Choices.Count); // lock may not be a bad idea
     var pick = Choices[i];
     Choices.RemoveAt(i);
     return i;
   }
}

Using it:

var baseChoices = Enumerable.Repeat(Colors.Red, 20)
  .Union(Enumerable.Repeat(Colors.Blue, 20))
  .Union(Enumerable.Repeat(Colors.Green, 5))...;

var shuffledColors = new SuffledChoices<Color>(baseChoices);

...
if (e.Button == MouseButtons.Left){
   Form.GetTile(x, y).FrontColour = shuffledColors.PickNext();
}

Upvotes: 3

Related Questions