Randomize 3 Colors

2019-08-05 09:56发布

问题:

I'm making a Breakout Game and I want the bricks to get a random BackColor. Right now I have the bricks getting filled with all type of colors: red, green, blue, yellow, pink and all others.

What I want to do though is only get the random to randomize three colors only : blue, yellow and green.

This is what I have now:

private Random rnd = new Random();

Color randomColor = Color.FromArgb(rnd.Next(256), rnd.Next(256), rnd.Next(256));

bricks[x, y].BackColor = randomColor;

I've searched and tried many different things and nothing has worked! I feel like this might be simple to do but somehow can't really get to it. I thought about making a list of the 3 colors and try randomizing the list but it didn't work out!

回答1:

About the comments:
The use of Thread.Sleep() is just an example to test the results of a local instance of the Random class when used in a close loop.
You will, probably, get series of the same result. Or all identical values.

Here, as a test, I'm inserting a small pause (1ms) when returning the random color, so the colors will be selected using a different seed (almost) every time. Test it without the pause.

The default implementation, using a single instance of the Random class, can yield similar results.

private Color[] Colors = { Color.Red, Color.Yellow, Color.Green};

private Color GetColor()
{
    Random random = new Random(DateTime.Now.Millisecond);
    Thread.Sleep(1);
    return Colors[random.Next(0,3)];
}

Test it without the Thread.Sleep() pause:

for (int i = 0; i < 100; i++)
{
    Console.WriteLine(GetColor().Name);
}

Or, using a single instance:

private Random random = new Random();

private Color GetColor()
{
    return Colors[random.Next(0,3)];
}

A slightly different method to get different shades of Red, Green and Yellow for each element:
(It should probably be tweaked a little to avoid semi-gray color).

private Color GetColor2()
{
    Color color = Colors[random.Next(0, 3)];
    switch (color.Name)
    {
        case "Yellow":
            color = Color.FromArgb((160 + random.Next(0, 96)), (160 + random.Next(0, 96)), 0);
            break;
        case "Red":
            color = Color.FromArgb((160 + random.Next(0, 96)), 0, 0);
            break;
        case "Green":
            color = Color.FromArgb(0, (160 + random.Next(0, 96)), 0);
            break;
    }
    return color;
}

This is a random palette this method generates:




回答2:

Disclaimer: I'm a newbie (to C#).

private Random rnd = new Random();
Color[] colorArr = {Color.FromArgb(0, 0, 255), Color.FromArgb(255, 255, 0), Color.FromArgb(0, 255, 0)};
bricks[x, y].BackColor = colorArr[rnd.Next(colorArr.Length)];

(colorArr.Length edit suggested by Corak)

Uses an array to store all the colors from which one will be picked. Next, a random element is called from the array.



回答3:

Write your own method and call that instead. Generate a random number e.g 0,1,2 and using a switch return the correct colour. E.g:

Color randomColor;
int random = rnd.Next(3)
  switch (random)
  {
      //red
      case 1:
          randomColor = Color.FromArgb(255, 0, 0);
          break;
      //green
      case 2:
          randomColor = Color.FromArgb(0, 255, 0);
          break;
      //blue
      default:
          randomColor = Color.FromArgb(0, 0, 255);
          break;
  }


回答4:

why not map the 3 colors of your choice to numbers {0,1,2} and then make a simple switch statement?

int color;
color = rnd.Next(3);
switch(color) {
case 0:
    // do something here for the first color
    break;
case 1:
    // do something.. you get the idea
    break;
case 2:
    break;
}

and then just hope that the randomness of Random in C# is good enough for your game ;)

EDIT: damn it, too late :D



回答5:

You could write it as an extension to Color

public static class ColorExtensions
{
    private static Color[] rgb = 
        {Color.FromArgb(0, 0, 255), Color.FromArgb(255, 255, 0), Color.FromArgb(0, 255, 0)};
    private static Random random = new Random();
    public static Color GetRandomRgb(this Color color)
    {
        return rgb[random.Next(rgb.Length)];
    }
}

However, since you can't yet extend a class by adding static methods, meaning you have to call that using an instance of Color, eg

var colour = new Color().GetRandomRgb();

and Color is a sealed class (meaning we can't inherit from it), you might like to do

public static Color GetRandomRgb()
{
    return rgb[random.Next(rgb.Length)];
}

Which you can call with

var colour = ColorExtensions.GetRandomRgb();