User Tools

Site Tools


java:2by2rubikcube

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
java:2by2rubikcube [2014/04/13 12:47]
rlunaro created
java:2by2rubikcube [2014/12/24 10:42] (current)
Line 1: Line 1:
 ====== The Rubik'​s cube 2 by 2 ====== ====== The Rubik'​s cube 2 by 2 ======
  
 +
 +{{ :​java:​cubo_rubik_2x2.jpg?​direct&​100 |}}
 +
 +Because I'm not good at all at solving this puzzle, I've decided to give Java an opportunity to solve it for me. 
 +
 +So, I've made a program to solve the rubik'​s cube. If you want to simply run the program, here it is:
 +
 +{{:​java:​rubik.zip|}}
 +
 +Just uncompress the contents of this zip file and you will find a file called ''​rubik.jar''​. Run it using the following command: ​
 +
 +<code bash>
 +java -jar rubik.jar
 +</​code>​
 +
 +And you the program will start. ​
 +
 +Remember that the faces of the cube must be read as if you were reading a text: from left to right, topmost to bottom. ​
 +
 +And the source code of the project: ​
 +
 +{{:​java:​rubik_src.zip|}}
 +
 +===== My comments =====
 +
 +The data structure I've choose for the cube is in fact a 4x4 matrix of colors:
 +
 +<code java>
 +
 +public class Cube22 implements Cube {
 +
 + private static final int SIDE_SIZE = 2;
 + private static final String nl = System.getProperty("​line.separator"​);​
 + private Color[][][] cube = new Color[SIDE_SIZE+2][SIDE_SIZE+2][SIDE_SIZE+2];​
 +
 +
 + // default constructor:​ a cube 
 + // with all the colors correct
 + public Cube22()
 + {
 +     /*
 +      ​* ​       TOP OF THE CUBE
 +      ​* ​ +-+-+-+-+
 +         ​* ​ | | | | |
 +         ​* ​ +-+-+-+-+
 +         ​* ​ | |b|b| |
 +         ​* ​ +-+-+-+-+
 +         ​* ​ | |b|b| |
 +         ​* ​ +-+-+-+-+
 +         ​* ​ | | | | |
 +         ​* ​ +-+-+-+-+
 +      */
 +        cube[0][0][0] = Color.NOCOLOR;​ cube[1][0][0] = Color.NOCOLOR;​ cube[2][0][0] = Color.NOCOLOR;​ cube[3][0][0] = Color.NOCOLOR;​
 +        cube[0][1][0] = Color.NOCOLOR;​ cube[1][1][0] = Color.BLUE; ​   cube[2][1][0] = Color.BLUE; ​   cube[3][1][0] = Color.NOCOLOR;​
 +        cube[0][2][0] = Color.NOCOLOR;​ cube[1][2][0] = Color.BLUE; ​   cube[2][2][0] = Color.BLUE; ​   cube[3][2][0] = Color.NOCOLOR;​
 +        cube[0][3][0] = Color.NOCOLOR;​ cube[1][3][0] = Color.NOCOLOR;​ cube[2][3][0] = Color.NOCOLOR;​ cube[3][3][0] = Color.NOCOLOR;​
 +        /*
 +         ​* ​       VERTICAL COLORS, 1
 +         ​* ​ +-+-+-+-+
 +         ​* ​ | |V|V| |
 +         ​* ​ +-+-+-+-+
 +         ​* ​ |W| | |Y|
 +         ​* ​ +-+-+-+-+
 +         ​* ​ |W| | |Y|
 +         ​* ​ +-+-+-+-+
 +         ​* ​ | |R|R| |
 +         ​* ​ +-+-+-+-+
 +         */
 +        cube[0][0][1] = Color.NOCOLOR;​ cube[1][0][1] = Color.VIOLET; ​ cube[2][0][1] = Color.VIOLET; ​ cube[3][0][1] = Color.NOCOLOR;​
 +        cube[0][1][1] = Color.WHITE; ​  ​cube[1][1][1] = Color.NOCOLOR;​ cube[2][1][1] = Color.NOCOLOR;​ cube[3][1][1] = Color.YELLOW;​
 +        cube[0][2][1] = Color.WHITE; ​  ​cube[1][2][1] = Color.NOCOLOR;​ cube[2][2][1] = Color.NOCOLOR;​ cube[3][2][1] = Color.YELLOW;​
 +        cube[0][3][1] = Color.NOCOLOR;​ cube[1][3][1] = Color.RED; ​    ​cube[2][3][1] = Color.RED; ​    ​cube[3][3][1] = Color.NOCOLOR;​
 +        /*
 +         ​* ​       VERTICAL COLORS, 2
 +         ​* ​ +-+-+-+-+
 +         ​* ​ | |V|V| |
 +         ​* ​ +-+-+-+-+
 +         ​* ​ |W| | |Y|
 +         ​* ​ +-+-+-+-+
 +         ​* ​ |W| | |Y|
 +         ​* ​ +-+-+-+-+
 +         ​* ​ | |R|R| |
 +         ​* ​ +-+-+-+-+
 +         */
 +        cube[0][0][2] = Color.NOCOLOR;​ cube[1][0][2] = Color.VIOLET; ​ cube[2][0][2] = Color.VIOLET; ​ cube[3][0][2] = Color.NOCOLOR;​
 +        cube[0][1][2] = Color.WHITE; ​  ​cube[1][1][2] = Color.NOCOLOR;​ cube[2][1][2] = Color.NOCOLOR;​ cube[3][1][2] = Color.YELLOW;​
 +        cube[0][2][2] = Color.WHITE; ​  ​cube[1][2][2] = Color.NOCOLOR;​ cube[2][2][2] = Color.NOCOLOR;​ cube[3][2][2] = Color.YELLOW;​
 +        cube[0][3][2] = Color.NOCOLOR;​ cube[1][3][2] = Color.RED; ​    ​cube[2][3][2] = Color.RED; ​    ​cube[3][3][2] = Color.NOCOLOR;​
 +        /*
 +         ​* ​       BOTTOM OF THE CUBE
 +         ​* ​ +-+-+-+-+
 +         ​* ​ | | | | |
 +         ​* ​ +-+-+-+-+
 +         ​* ​ | |G|G| |
 +         ​* ​ +-+-+-+-+
 +         ​* ​ | |G|G| |
 +         ​* ​ +-+-+-+-+
 +         ​* ​ | | | | |
 +         ​* ​ +-+-+-+-+
 +         */
 +        cube[0][0][3] = Color.NOCOLOR;​ cube[1][0][3] = Color.NOCOLOR;​ cube[2][0][3] = Color.NOCOLOR;​ cube[3][0][3] = Color.NOCOLOR;​
 +        cube[0][1][3] = Color.NOCOLOR;​ cube[1][1][3] = Color.GREEN; ​  ​cube[2][1][3] = Color.GREEN; ​  ​cube[3][1][3] = Color.NOCOLOR;​
 +        cube[0][2][3] = Color.NOCOLOR;​ cube[1][2][3] = Color.GREEN; ​  ​cube[2][2][3] = Color.GREEN; ​  ​cube[3][2][3] = Color.NOCOLOR;​
 +        cube[0][3][3] = Color.NOCOLOR;​ cube[1][3][3] = Color.NOCOLOR;​ cube[2][3][3] = Color.NOCOLOR;​ cube[3][3][3] = Color.NOCOLOR;​
 +     ​
 + } // Cube22
 +
 +    @Override
 +    public Color getColor( int x, int y, int z )
 +    {
 +        return cube[x][y][z];​
 +    }
 +    @Override
 +    public void setColor( int x, int y, int z, Color color )
 +    {
 +        cube[x][y][z] = color;
 +    }
 +
 +    @Override
 +    public Cube getCopy()
 +    {
 +        Cube22 result = new Cube22();
 +        ​
 +        for( int x = 0; x < 4; x++ )
 +            for( int y = 0; y < 4; y++ )
 +                for( int z = 0; z < 4; z++ )
 +                {
 +                    result.setColor(x,​ y, z, getColor(x, y, z));
 +                }
 +        ​
 +        return result;
 +        ​
 +    } // getCopy ​
 +    ​
 + @Override
 + public String toString()
 + {
 +     StringBuilder out = new StringBuilder();​
 +     ​
 +     out.append( " ​       ____________ " ); out.append( nl );
 +     out.append( " ​      / ​    / ​    /​|"​ ); out.append( nl ); 
 +     out.append( " ​     /  "​+Color.toString(cube[1][1][0])+" ​ /   "​+Color.toString(cube[2][1][0])+"​ / |" ); out.append( nl );
 +     out.append( " ​    /​_____/​_____/​ "​+Color.toString(cube[3][1][1])+"​|"​ ); out.append( nl );
 +     out.append( " ​   /     / ​    /​| ​ ," ); out.append( nl );
 +     out.append( " ​  / ​ "​+Color.toString(cube[1][2][0])+" ​ /   "​+Color.toString(cube[2][2][0])+"​ / | /|" ); out.append( nl );
 +     out.append( " ​ /​_____/​_____/ ​ |/ |" ); out.append( nl );
 +     out.append( " ​ |     ​| ​    ​|"​+Color.toString(cube[3][2][1])+"​ / "​+Color.toString(cube[3][1][2])+","​ ); out.append( nl ); 
 +     out.append( " ​ |  "​+Color.toString(cube[1][3][1])+" ​ |  "​+Color.toString(cube[2][3][1])+" ​ | /| / " ); out.append( nl );
 +     out.append( " ​ |_____|_____|/​ |/  " ); out.append( nl );
 +     out.append( " ​ |     ​| ​    ​|"​+Color.toString(cube[3][2][2])+"​ /   "​ ); out.append( nl );
 +     out.append( " ​ |  "​+Color.toString(cube[1][3][2])+" ​ |  "​+Color.toString(cube[2][3][2])+" ​ | /    " ); out.append( nl );
 +     out.append( " ​ |_____|_____|/ ​    "​ ); out.append( nl );
 +     ​
 +     return out.toString();​
 +
 + } // toString
 +
 + /**
 + * Return true if the cube is solved, in other words, all the colors ​
 + * are grouped in the same face of the cube.
 +
 + * @return
 + */
 + @Override
 + public boolean isSolved()
 + {
 +        boolean facade1;
 +        boolean facade2;
 +        boolean facade3;
 +        boolean facade4;
 +        boolean facade5;
 +        boolean facade6;
 +        ​
 +     facade1 = cube[1][1][0] == cube[2][1][0] && cube[2][1][0] == cube[1][2][0] && cube[1][2][0] == cube[2][2][0];​
 +        facade2 = cube[3][2][1] == cube[3][1][1] && cube[3][1][1] == cube[3][1][2] && cube[3][1][2] == cube[3][2][2];​
 +        facade3 = cube[1][3][1] == cube[2][3][1] && cube[2][3][1] == cube[1][3][2] && cube[1][3][2] == cube[2][3][2];​
 +        facade4 = cube[1][1][3] == cube[2][1][3] && cube[2][1][3] == cube[1][2][3] && cube[1][2][3] == cube[2][2][3];​
 +        facade5 = cube[0][2][1] == cube[0][1][1] && cube[0][1][1] == cube[0][1][2] && cube[0][1][2] == cube[0][2][2];​
 +        facade6 = cube[1][0][1] == cube[2][0][1] && cube[2][0][1] == cube[1][0][2] && cube[1][0][2] == cube[2][0][2];​
 +        ​
 +        return facade1 && facade2 && facade3 && facade4 && facade5 && facade6;
 + }
 +
 +
 + /**
 + * Determine if two cubes are equal regardless of their orientation.
 + * This is important because this, applied to the search algorithm
 + * prevents to explore branches that in fact are the seame than a 
 + * previous one but with the colors rotated. ​
 +
 + */
 + @Override
 + public boolean equals( Object comp )
 + {
 +     if( this == comp )
 +         return true; 
 +     if( comp instanceof Cube22 )
 +     {
 +         Cube22 compCube = (Cube22) comp; 
 +         return equalsXYZ(compCube);​
 +     }
 +     else
 +         return false;
 + } // equals
 +
 +
 +   ​public boolean equalsXYZ( Cube compCube )
 +    {
 +        boolean equal = true; 
 +        for( int x = 0; x < SIDE_SIZE+2 && equal; x++ )
 +            for( int y = 0; y < SIDE_SIZE+2 && equal; y++ )
 +                for( int z = 0; z < SIDE_SIZE+2 && equal; z++ )
 +                    equal = equal && (cube[x][y][z] == compCube.getColor(x,​ y, z));
 +        return equal;
 +    } // equals
 +
 +}
 +</​code>​
 +
 +After two days developing (in my spare time) I've realized that it was a wrong decision, because there is a better way to store the cube and allow the rotation operations to be more easy: is to create a ''​sticker''​ data structure and link the stickers between them. Thus, the operation of rotation of the cube is more easy and less error prone. ​
 +
 +An idea of what it would be:
 +
 +<code java>
 +class Sticker
 +{
 +   ​private Sticker north; ​
 +   ​private Sticker south; ​
 +   ​private Sticker east;
 +   ​private Sticker west; 
 +   ​private Sticker northCorner; ​
 +
 +}
 +</​code>​
 +
 +So, the cube is constructer by linking the respective north, south, east ... links between them. But I think it would be needed to keep a link in order to know the orientation of the cube (to know what is ''​up''​ and ''​down''​):​ because of this is necessary this ''​northCorner'',​ who will be set with a value only with one sticker. ​
  
  
java/2by2rubikcube.txt ยท Last modified: 2014/12/24 10:42 (external edit)