2

I've made a small algo which allows me to resolve a rubik's cube on the paper.

I now want to implement it, but I can't found an object representation which satisfied me.

I easily can see a rubiksCube object, and a "cube" object, which can be implemented by a face, a corner or an edge.

But I need some objects between, to specify on which place is which cube.

The final goal is that I can easily make some rotation on it.

Do you have an idea about how to represent this?

Thank you very much

J4N
  • 19,480
  • 39
  • 187
  • 340

3 Answers3

4

This CodeProject's article looks exactly what you need. It has all the movements and solvers funcs as well.

David Elizondo
  • 1,123
  • 1
  • 7
  • 16
2

Represent Rubik's cube by a 5 x 5 x 5 matrix of colors where only the 3 x 3 center matrix positions of each of the 6 matrix surfaces are used to represent the colors.

enter image description here

In order to rotate a border slice of Rubic's cube, you will have to rotate two border slices of the matrix. The center slices can be rotated by rotating the one matrix slice only. The advantage of this approach is that you can perform simple matrix rotations and that you can do everthing in 3D. You don't have to reconstruct the 3D appearance from some flat 2D projection.


Note: This "exaggerated" size is required, since you can only store one color per matrix cell. Taking two matrix-slices together, allows you to store two colors for the edges and three colors for the corners.

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
2

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 ;)

Marcel B
  • 3,624
  • 2
  • 27
  • 39
  • I think that with this structure, it's pretty hard to make rotation(and this isn't object oriented) – J4N Jul 31 '11 at 06:55
  • but I don't understand how the orientation is modeled. You have only x-y-z position so we will now that we have the piece A in the position W, but how do which face has which orientation? – J4N Aug 01 '11 at 06:19
  • I hope my last edit helps you to understand my idea… I don't model faces, I model only tiles(and a face consists of 9 tiles). – Marcel B Aug 01 '11 at 13:33
  • I understand that you want to modelize only one face of each "cube", but I'm just not familiar enough with the matrix notation/operation to understand, like : Why the top layer has elements which Y=1 and Y=2 in your example? What is the size of one dimension? Definitely not object oriented – J4N Aug 03 '11 at 13:12