I would build something like this:
class Cube
{
List<Tile> Tiles = new List<Tile>(){
// Front Face
new Tile(Color.blue, -1, 1, 2), //top left corner tile
new Tile(Color.blue, 0, 1, 2), //top middle tile
new Tile(Color.blue, 1, 1, 2), //top right corner tile
new Tile(Color.blue, -1, 0, 2), //middle left tile
new Tile(Color.blue, 0, 0, 2), //center tile of this face
new Tile(Color.blue, 0, 1, 2), //…
new Tile(Color.blue, -1,-1, 2),
new Tile(Color.blue, 0,-1, 2),
new Tile(Color.blue, 1,-1, 2), //bottom right corner tile
…
};
The center of the cube would be (0, 0, 0) and you could imagine these points floating over the actual cube. The little tiles are abstracted to points and therefor need no orientation. This way all front face tiles have a z-coordinate of 2, all top face tiles have a y-coordinate of 2, all left face tiles have a x-coordinate of -2 and so on.
IEnumerable<Tile> TopLayer
{
get
{
return Tiles.Where(f => f.Position.Y == 2 || f.Position.Y == 1);
}
}
IEnumerable<Tile> BottomLayer {…}
Color getTileColor(int x,int y,int z)
{
return Tiles.Single(t => t.Position.X == x && t.Position.Y == y && t.Position.Z == z).Color;
}
Take a look at rotation matrices. The beauty of rotation matrices is that they always rotate about the center of the coordinate system (0, 0, 0) and when you have a bunch of points(like here) the rotation is more like a circular movement.
If you set θ to 90°(in Rx) you get
1 0 0
0 0 -1
0 1 0
Which could be translated to the following Method:
static void rotateLayerX(IEnumerable<Tile> layer)
{
foreach (var tile in layer)
{
var x = tile.Position.X;
var y = tile.Position.Y;
var z = tile.Position.Z;
tile.Position = new Point3D(x, -z, y);
}
}
Than you only have to call Cube.rotateLayerX(cube.LeftLayer)
.
} // class cube
class Tile
{
public Tile (Color c, int x, int y, int z)
{
Color = c;
Position = new Point3D(x,y,z);
}
Color Color { get; private set; } // enum Color {...}
Point3D Position { get; set; }
}
It's just a simple colored point cloud.
And you're right this thing is not strictly typed and it's possible call Cube.rotateLayerX(Cube.TopLayer)
(or an other arbitrary collection of tiles), which makes no sense. But doing this would be stupid… so don't do it ;)