Reputation: 13
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
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
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