This is likely not going to be appropriate for your homework. But, then again, I don't do homework for other people.
Instead of rotating the array several times, I create a type that gets initialized with an array and provides a way to see it rotated at several angles.
I relaxed a few of your restrictions. You asked about a 6x6 array of char
. This provides a generic solution for an MxN array of a generic type T
instead (i.e. the array can be 5x7 if you want).
Your selection of characters made it hard to test, so I used this instead:
private char[,] _theArray = new char[,]
{
{'a', 'b', 'c', 'd', 'e', 'f'},
{'A', 'B', 'C', 'D', 'E', 'F'},
{'g', 'h', 'i', 'j', 'k', 'l'},
{'G', 'H', 'I', 'J', 'K', 'L'},
{'m', 'n', 'o', 'p', 'q', 'r'},
{'M', 'N', 'O', 'P', 'Q', 'R'},
};
But I also tested it with:
private char[,] _theArray = new char[,]
{
{'a', 'b', 'c', 'd', 'e', 'f'},
{'A', 'B', 'C', 'D', 'E', 'F'},
{'g', 'h', 'i', 'j', 'k', 'l'},
{'G', 'H', 'I', 'J', 'K', 'L'},
};
and:
private char[,] _theArray = new char[,]
{
{'a', 'b', 'c', 'd',},
{'A', 'B', 'C', 'D',},
{'g', 'h', 'i', 'j',},
{'G', 'H', 'I', 'J',},
{'m', 'n', 'o', 'p',},
{'M', 'N', 'O', 'P',},
};
So, it works with 6x6, 4x6 and 6x4 arrays.
Instead of specifying the rotation with an integer (1-4), it uses an enum
:
public enum RotationAngle
{
Rotate0,
Rotate90,
Rotate180,
Rotate270,
}
It relies on a generic class named RotatableArray<T>
:
public class RotatableArray<T>
{
public int Width { get; }
public int Height { get; }
private T[,] _theArray;
public RotatableArray(T[,] array)
{
_theArray = array;
Width = array.GetLength(0);
Height = array.GetLength(1);
}
public T this[int x, int y]
{
get
{
CheckParametersPlain(x, y);
return _theArray[x, y];
}
}
public T this[RotationAngle angle, int x, int y]
{
get
{
switch (angle)
{
case RotationAngle.Rotate0:
return this[x, y];
case RotationAngle.Rotate90:
CheckParametersRotated(x, y);
return _theArray[Width - y - 1, x];
case RotationAngle.Rotate180:
CheckParametersPlain(x, y);
return _theArray[Width - x - 1, Height - y - 1];
case RotationAngle.Rotate270:
CheckParametersRotated(x, y);
return _theArray[y, Height - x - 1];
default:
throw new ArgumentOutOfRangeException($"Parameter {nameof(angle)} must be one of {string.Join(", ", Enum.GetNames<RotationAngle>())}");
}
}
}
public int AdjustedWidth(RotationAngle angle)
{
if (angle == RotationAngle.Rotate0 || angle == RotationAngle.Rotate180)
{
return Width;
}
else
{
return Height;
}
}
public int AdjustedHeight(RotationAngle angle)
{
if (angle == RotationAngle.Rotate0 || angle == RotationAngle.Rotate180)
{
return Height;
}
else
{
return Width;
}
}
private void CheckParametersPlain(int x, int y)
{
if (x >= Width)
{
throw new ArgumentOutOfRangeException(nameof(x), $"Parameter must be less than the array Width ({Width})");
}
if (y >= Height)
{
throw new ArgumentOutOfRangeException(nameof(y), $"Parameter must be less than the array Height ({Height})");
}
}
private void CheckParametersRotated(int x, int y)
{
if (y >= Width)
{
throw new ArgumentOutOfRangeException(nameof(y), $"After rotation, parameter must be less than the array Width ({Width})");
}
if (x >= Height)
{
throw new ArgumentOutOfRangeException(nameof(x), $"After rotation, parameter must be less than the array Height ({Height})");
}
}
}
An instance of a RotatableArray<T>
gets initialized (/constructed) with a two-dimension array of T
. That array is never mutated.
var rotArray = new RotatableArray<char>(_theArray);
Instead, the class relies on a three-parameter Indexed Property (also known as an Indexer https://learn.microsoft.com/en-Us/dotnet/csharp/programming-guide/indexers/) to provide a rotatable facade over the top of the non-mutable array it was initialized with.
Instead of rotating the array, you index over it (in two dimensions) passing in a RotationAngle
value to describe how you want to be presented.
I tested this in a Windows Forms app (putting the output into a multi-line text box). The key code looks like:
private void ShowRotated (RotatableArray<char> array, RotationAngle angle)
{
textBox1.Clear();
var row = new List<char>();
for (int i = 0; i < array.AdjustedWidth(angle); i++)
{
row.Clear();
for (int j = 0; j < array.AdjustedHeight(angle); j++)
{
row.Add(array[angle, i, j]);
}
textBox1.Text += (string.Join(" | ", row) + Environment.NewLine);
}
}
Note that it's basically the same as the code you provided. The difference is that rather than accessing:
array[i, j]
I'm accessing:
array[angle, i, j]
where angle
is one of Rotate0
, Rotate90
, Rotate180
, or Rotate270
.
Using this array as an example:
private char[,] _theArray = new char[,]
{
{'a', 'b', 'c', 'd', 'e', 'f'},
{'A', 'B', 'C', 'D', 'E', 'F'},
{'g', 'h', 'i', 'j', 'k', 'l'},
{'G', 'H', 'I', 'J', 'K', 'L'},
};
These are the results I get:
Just showing the original array:
a | b | c | d | e | f
A | B | C | D | E | F
g | h | i | j | k | l
G | H | I | J | K | L
Showing it at Rotate0
results in the same thing:
a | b | c | d | e | f
A | B | C | D | E | F
g | h | i | j | k | l
G | H | I | J | K | L
At 90, you get:
G | g | A | a
H | h | B | b
I | i | C | c
J | j | D | d
K | k | E | e
L | l | F | f
and at 180:
L | K | J | I | H | G
l | k | j | i | h | g
F | E | D | C | B | A
f | e | d | c | b | a
and finally at 270:
f | F | l | L
e | E | k | K
d | D | j | J
c | C | i | I
b | B | h | H
a | A | g | G
This could easily be extended to provide for transposition, as well and inverting things both vertically and horizontally.
There should be enough code in this for you to do your assignment.