6

I'm new to C# and working on a snake project. I'm trying to make it rainbow coloured, is there a better way to switch between six colours and then repeat?

public Brush Colour(int i)
{
    Brush snakeColour;
    switch (i)
    {
        case 0:
        case 6:
        case 12: 
        case 18: 
        case 24:
            snakeColour = Brushes.HotPink;
            break;

        case 1: 
        case 7: 
        case 13: 
        case 19: 
        case 25:
            snakeColour = Brushes.Orange;
            break;

        case 2: 
        case 8: 
        case 14: 
        case 20: 
        case 26:
            snakeColour = Brushes.PeachPuff;
            break;

        etc.

        default:
            snakeColour = Brushes.White;
            break;
    }

    return snakeColour;
}

Any suggestions?

PTD
  • 1,028
  • 1
  • 16
  • 23
Sarasaurus
  • 63
  • 5

3 Answers3

20

If you use the remainder operator (and you assume non-negative input) you know you'll always have a value in the range 0 to 5 inclusive, so you don't need a switch at all - just use an array:

private static readonly Brush[] brushes =
{
    Brushes.HotPink,
    Brushes.Orange,
    Brushes.PeachPuff,
    ...
    Brushes.White
};

// TODO: Potentially rename from using "position" to something else,
// based on what the parameter is really meant to represent.
public Brush GetBrushForPosition(int position) => brushes[position % 6];

If the input might be negative, you can use the slightly more long-winded expression of ((position % 6) + 6) % 6 for the array index, which will still cycle appropriately. (There are other approaches of course, but that's reasonably simple.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
5

You could reduce the number of case labels using the modulus operator:

public Brush Colour(int i)
{
    Brush snakeColour;
    switch (i % 6)
    {
        case 0:
            snakeColour = Brushes.HotPink;
            break;

        case 1:
            snakeColour = Brushes.Orange;
            break;

        case 2:
            snakeColour = Brushes.PeachPuff;
            break;

//      etc.

        default:
            snakeColour = Brushes.White;
            break;

    }

    return snakeColour;
}

But note: this would most likely remove the need for your default case (assuming you have all cases from 0 thru 5 taken care of). That may be contrary to what you intend, if the actual i value is outside a specific range!

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
2

By using % operator, you can make your code much more simpler. Here is what @Adrian Mole suggested...

 public Brush Colour(int i)
        {
            Brush snakeColour;
            i %= 6;
            switch (i)
            {
                case 0:
                    snakeColour = Brushes.HotPink;
                    break;

                case 1:
                    snakeColour = Brushes.Orange;
                    break;

                case 2:
                    snakeColour = Brushes.PeachPuff;
                    break;

                default:
                    snakeColour = Brushes.White;
                    break;

            }
            return snakeColour;
        }
vlada
  • 167
  • 15