rubikscube

college code for finding optimal rubiks cube solutions in java

git clone https://9o.is/git/rubikscube.git

RubiksCube.java

(34230B)


      1 import java.io.BufferedReader;
      2 import java.io.FileReader;
      3 import java.io.IOException;
      4 import java.util.Random;
      5 
      6 /**
      7  * A 3 by 3, six sided Rubik's cube. It can rotate, print its state,
      8  * rotate to a random position, and more.
      9  */
     10 public class RubiksCube {
     11 
     12     /** The cube in goal state. */
     13     public static final RubiksCube GOAL = new RubiksCube(false);
     14 
     15     /*
     16      * Amount of sides or faces in this cube.
     17      * A cube has to be six sides.
     18      */
     19     private final int CUBE_SIDES = 6;
     20 
     21     /*
     22      * Size of the cube. (3 by 3). Might break if changed.
     23      */
     24     private final int CUBE_SIZE = 3;
     25 
     26     /*
     27      * 3-Dimensional array that stores the state of the cube.
     28      */
     29     private RubiksColor cube[][][];
     30 
     31     /**
     32      * Initiates a rubik's cube at it's goal state.
     33      */
     34     public RubiksCube() {
     35         cube = new RubiksColor[CUBE_SIDES][CUBE_SIZE][CUBE_SIZE];
     36         initGoalState();
     37     }
     38 
     39     /**
     40      * Initiates a rubik's cube at it's goal state if parameter is
     41      * false or it randomizes the state if parameter is true.
     42      * @param random If the state will be random or not.
     43      */
     44     public RubiksCube(boolean random) {
     45         cube = new RubiksColor[CUBE_SIDES][CUBE_SIZE][CUBE_SIZE];
     46         if(random) {
     47             initGoalState();
     48             initRandomState();
     49         } else initGoalState();
     50     }
     51 
     52     /**
     53      * Initiates a Rubik's cube from an existing state.
     54      * @param state The existing state.
     55      */
     56     public RubiksCube(RubiksState state) {
     57         cube = new RubiksColor[CUBE_SIDES][CUBE_SIZE][CUBE_SIZE];
     58         setState(state);
     59     }
     60 
     61     /**
     62      * Create a rubik's cube from a file.
     63      * @param file The name of the file.
     64      */
     65     public RubiksCube(FileReader file) {
     66         try {
     67             String result = "";
     68             BufferedReader in = new BufferedReader(file);
     69             String str;
     70             int n=0;
     71             String storage = "";
     72             while ((str = in.readLine()) != null) {
     73                 str = str.trim();
     74                 if(str.length() > 3) {
     75                     if(n==0) {
     76                         result += str.substring(0,3);
     77                         storage += str.substring(3);
     78                     } else if(n==1) {
     79                         result += str.substring(0,3);
     80                         storage += str.substring(3);
     81                     } else if(n==2) {
     82                         result += str.substring(0,3);
     83                         result += storage.substring(0,3) +
     84                                 storage.substring(6,9) +
     85                                 str.substring(3,6) +
     86                                 storage.substring(3,6) +
     87                                 storage.substring(9,12) +
     88                                 str.substring(6,9);
     89                     }
     90                     n++;
     91                 } else
     92                     result += str;
     93             }
     94             in.close();
     95             cube = new RubiksColor[CUBE_SIDES][CUBE_SIZE][CUBE_SIZE];
     96             setState(result);
     97             RubiksState test = new RubiksState(this);
     98             //System.out.println(result);
     99         } catch (Exception e) {
    100             e.printStackTrace();
    101         }
    102     }
    103 
    104     /**
    105      * Sets the state of this rubik's cube to a new given state.
    106      * @param state The new state to set for this rubik's cube.
    107      */
    108     public void setState(RubiksState state) {
    109         String corners = state.getCorners().toString();
    110         // corner 1
    111         cube[5][2][0] = RubiksColor.find(corners.substring(0,1));
    112         cube[0][0][0] = RubiksColor.find(corners.substring(1,2));
    113         cube[1][0][0] = RubiksColor.find(corners.substring(2,3));
    114         // corner 2
    115         cube[5][2][2] = RubiksColor.find(corners.substring(3,4));
    116         cube[3][0][2] = RubiksColor.find(corners.substring(4,5));
    117         cube[0][0][2] = RubiksColor.find(corners.substring(5,6));
    118         // corner 3
    119         cube[0][2][0] = RubiksColor.find(corners.substring(6,7));
    120         cube[2][0][0] = RubiksColor.find(corners.substring(7,8));
    121         cube[1][0][2] = RubiksColor.find(corners.substring(8,9));
    122         // corner 4
    123         cube[0][2][2] = RubiksColor.find(corners.substring(9,10));
    124         cube[3][0][0] = RubiksColor.find(corners.substring(10,11));
    125         cube[2][0][2] = RubiksColor.find(corners.substring(11,12));
    126         // corner 5
    127         cube[2][2][0] = RubiksColor.find(corners.substring(12,13));
    128         cube[4][0][0] = RubiksColor.find(corners.substring(13,14));
    129         cube[1][2][2] = RubiksColor.find(corners.substring(14,15));
    130         // corner 6
    131         cube[2][2][2] = RubiksColor.find(corners.substring(15,16));
    132         cube[3][2][0] = RubiksColor.find(corners.substring(16,17));
    133         cube[4][0][2] = RubiksColor.find(corners.substring(17,18));
    134         // corner 7
    135         cube[4][2][0] = RubiksColor.find(corners.substring(18,19));
    136         cube[5][0][0] = RubiksColor.find(corners.substring(19,20));
    137         cube[1][2][0] = RubiksColor.find(corners.substring(20,21));
    138         // corner 8
    139         cube[4][2][2] = RubiksColor.find(corners.substring(21,22));
    140         cube[3][2][2] = RubiksColor.find(corners.substring(22,23));
    141         cube[5][0][2] = RubiksColor.find(corners.substring(23,24));
    142 
    143         String halfEdges = state.getHalfEdges().toString();
    144         // edge 1
    145         cube[1][0][1] = RubiksColor.find(halfEdges.substring(0,1));
    146         cube[0][1][0] = RubiksColor.find(halfEdges.substring(1,2));
    147         // edge 2
    148         cube[5][2][1] = RubiksColor.find(halfEdges.substring(2,3));
    149         cube[0][0][1] = RubiksColor.find(halfEdges.substring(3,4));
    150         // edge 3
    151         cube[0][1][2] = RubiksColor.find(halfEdges.substring(4,5));
    152         cube[3][0][1] = RubiksColor.find(halfEdges.substring(5,6));
    153         // edge 4
    154         cube[0][2][1] = RubiksColor.find(halfEdges.substring(6,7));
    155         cube[2][0][1] = RubiksColor.find(halfEdges.substring(7,8));
    156         // edge 5
    157         cube[2][1][0] = RubiksColor.find(halfEdges.substring(8,9));
    158         cube[1][1][2] = RubiksColor.find(halfEdges.substring(9,10));
    159         // edge 6
    160         cube[3][1][0] = RubiksColor.find(halfEdges.substring(10,11));
    161         cube[2][1][2] = RubiksColor.find(halfEdges.substring(11,12));
    162 
    163         String half2Edges = state.getHalf2Edges().toString();
    164         // edge 7
    165         cube[2][2][1] = RubiksColor.find(half2Edges.substring(0,1));
    166         cube[4][0][1] = RubiksColor.find(half2Edges.substring(1,2));
    167         // edge 8
    168         cube[4][1][0] = RubiksColor.find(half2Edges.substring(2,3));
    169         cube[1][2][1] = RubiksColor.find(half2Edges.substring(3,4));
    170         // edge 9
    171         cube[3][2][1] = RubiksColor.find(half2Edges.substring(4,5));
    172         cube[4][1][2] = RubiksColor.find(half2Edges.substring(5,6));
    173         // edge 10
    174         cube[4][2][1] = RubiksColor.find(half2Edges.substring(6,7));
    175         cube[5][0][1] = RubiksColor.find(half2Edges.substring(7,8));
    176         // edge 11
    177         cube[1][1][0] = RubiksColor.find(half2Edges.substring(8,9));
    178         cube[5][1][0] = RubiksColor.find(half2Edges.substring(9,10));
    179         // edge 12
    180         cube[5][1][2] = RubiksColor.find(half2Edges.substring(10,11));
    181         cube[3][1][2] = RubiksColor.find(half2Edges.substring(11,12));
    182 
    183         fillInMiddleColors();
    184     }
    185 
    186     /**
    187      * Sets the state of this rubik's cube to a new given state.
    188      * @param state The new state to set for this rubik's cube.
    189      */
    190     public void setState(String state) {
    191         int side,row,column, count=0;
    192         for (side=0; side<CUBE_SIDES; side++)
    193             for(row=0; row<CUBE_SIZE; row++)
    194                 for (column=0; column<CUBE_SIZE; column++) {
    195                     String input = state.substring(count, ++count);
    196                     cube[side][row][column] = RubiksColor.find(input);
    197                 }
    198         fillInMiddleColors();
    199     }
    200 
    201     /**
    202      * Resets the rubik's cube at it's goal state.
    203      */
    204     public void initGoalState() {
    205         int side,row,column;
    206         for (side=0; side<CUBE_SIDES; side++)
    207             for(row=0; row<CUBE_SIZE; row++)
    208                 for (column=0; column<CUBE_SIZE; column++) {
    209                     if(side==0)
    210                         cube[side][row][column]= RubiksColor.RED;
    211                     else if(side==1)
    212                         cube[side][row][column]= RubiksColor.GREEN;
    213                     else if(side==2)
    214                         cube[side][row][column]= RubiksColor.YELLOW;
    215                     else if(side==3)
    216                         cube[side][row][column]= RubiksColor.BLUE;
    217                     else if(side==4)
    218                         cube[side][row][column]= RubiksColor.ORANGE;
    219                     else
    220                         cube[side][row][column]= RubiksColor.WHITE;
    221                 }
    222     }
    223 
    224     /**
    225      * Shuffles the rubik's cube to a random state.
    226      */
    227     public void initRandomState() {
    228         for(int i=0; i<100; i++) {
    229             rotate(new Random().nextInt(2)+1,
    230                     RubiksColor.randomColor());
    231         }
    232     }
    233 
    234     /**
    235      * Exports the current state of the rubik's cube.
    236      * @return state of the current cube.
    237      */
    238     public RubiksState getState() {
    239         try {
    240             return new RubiksState(
    241                     getCornerState(),
    242                     getHalfEdgeState(),
    243                     getHalf2EdgeState()
    244             );
    245         } catch (Exception e) {
    246             //this should never happen because the state should be
    247             // checked in the first place at all times,
    248             // but the 3d array made the cube almost impossible.
    249             e.printStackTrace();
    250             return null;
    251         }
    252     }
    253 
    254     /* Gets the state of the corner cubies. */
    255     public String getCornerState() {
    256         return
    257                 // corner 1
    258                 cube[5][2][0].toString() +              //w
    259                         cube[0][0][0].toString() +      //r
    260                         cube[1][0][0].toString() +      //g
    261 
    262                         // corner 2
    263                         cube[5][2][2].toString() +     //w
    264                         cube[3][0][2].toString() +     //b
    265                         cube[0][0][2].toString() +     //r
    266                         // corner 3
    267                         cube[0][2][0].toString() +     //r
    268                         cube[2][0][0].toString() +     //y
    269                         cube[1][0][2].toString() +     //g
    270                         // corner 4
    271                         cube[0][2][2].toString() +     //r
    272                         cube[3][0][0].toString() +     //b
    273                         cube[2][0][2].toString() +     //y
    274                         // corner 5
    275                         cube[2][2][0].toString() +     //y
    276                         cube[4][0][0].toString() +     //o
    277                         cube[1][2][2].toString() +     //g
    278                         // corner 6
    279                         cube[2][2][2].toString() +     //y
    280                         cube[3][2][0].toString() +     //b
    281                         cube[4][0][2].toString() +     //o
    282                         // corner 7
    283                         cube[4][2][0].toString() +     //o
    284                         cube[5][0][0].toString() +     //w
    285                         cube[1][2][0].toString() +     //g
    286                         // corner 8
    287                         cube[4][2][2].toString() +     //o
    288                         cube[3][2][2].toString() +     //b
    289                         cube[5][0][2].toString();      //w
    290 
    291     }
    292 
    293     /* Gets the state of the first half of the edge cubies. */
    294     public String getHalfEdgeState() {
    295         return
    296                 // edge 1
    297                 cube[1][0][1].toString() +             //g
    298                         cube[0][1][0].toString() +     //r
    299                         // edge 2
    300                         cube[5][2][1].toString() +     //w
    301                         cube[0][0][1].toString() +     //r
    302                         // edge 3
    303                         cube[0][1][2].toString() +     //r
    304                         cube[3][0][1].toString() +     //b
    305                         // edge 4
    306                         cube[0][2][1].toString() +     //r
    307                         cube[2][0][1].toString() +     //y
    308                         // edge 5
    309                         cube[2][1][0].toString() +     //y
    310                         cube[1][1][2].toString() +     //g
    311                         // edge 6
    312                         cube[3][1][0].toString() +     //b
    313                         cube[2][1][2].toString();      //y
    314     }
    315 
    316     /* Gets the state of the second half of the edge cubies. */
    317     public String getHalf2EdgeState() {
    318         return
    319                 // edge 7
    320                 cube[2][2][1].toString() +             //y
    321                         cube[4][0][1].toString() +     //o
    322                         // edge 8
    323                         cube[4][1][0].toString() +     //o
    324                         cube[1][2][1].toString() +     //g
    325                         // edge 9
    326                         cube[3][2][1].toString() +     //b
    327                         cube[4][1][2].toString() +     //o
    328                         // edge 10
    329                         cube[4][2][1].toString() +     //o
    330                         cube[5][0][1].toString() +     //w
    331                         // edge 11
    332                         cube[1][1][0].toString() +     //g
    333                         cube[5][1][0].toString() +     //w
    334                         // edge 12
    335                         cube[5][1][2].toString() +     //w
    336                         cube[3][1][2].toString();      //b
    337     }
    338 
    339     /**
    340      * The array state of this rubik's cube.
    341      * @return The state array.
    342      */
    343     public RubiksColor[][][] getCubeArray() {
    344         return cube;
    345     }
    346 
    347     /**
    348      * Rotates and returns all the possible children/neighbor states.
    349      * @return an array of all neighbor states.
    350      */
    351     public RubiksState[] getNeighborStates() {
    352         RubiksState[] states = new RubiksState[18]; //18 total states
    353         RubiksState original = getState();
    354 
    355         for(int i=0; i<3; i++) { // 3 is amount of rotations
    356             rotate(i+1, RubiksColor.RED);
    357             states[i*6] = getState();
    358             setState(original);
    359             rotate(i+1, RubiksColor.GREEN);
    360             states[i*6+1] = getState();
    361             setState(original);
    362             rotate(i+1, RubiksColor.YELLOW);
    363             states[i*6+2] = getState();
    364             setState(original);
    365             rotate(i+1, RubiksColor.BLUE);
    366             states[i*6+3] = getState();
    367             setState(original);
    368             rotate(i+1, RubiksColor.ORANGE);
    369             states[i*6+4] = getState();
    370             setState(original);
    371             rotate(i+1, RubiksColor.WHITE);
    372             states[i*6+5] = getState();
    373             setState(original);
    374         }
    375         return states;
    376     }
    377 
    378     /**
    379      * Prints the state of the cube in the console.
    380      */
    381     public void printState() {
    382 
    383         int side,row,column;
    384         for(side=0; side<CUBE_SIDES; side++)
    385             for(row=0; row<CUBE_SIZE; row++) {
    386                 for (column=0; column<CUBE_SIZE; column++ ) {
    387                     if((side==0 || side==4 || side==5) && column==0)
    388                         System.out.print("   ");
    389 
    390                     if(side==1 || side==2 || side==3) {
    391                         if(side==1) {
    392                             if(row==0)
    393                                 System.out.print(
    394                                         cube[side+row][row][column]);
    395                             else if(row==1)
    396                                 System.out.print(
    397                                         cube[side+row][row-1][column]);
    398                             else
    399                                 System.out.print(
    400                                         cube[side+row][row-2][column]);
    401                         }
    402                         if(side==2) {
    403                             if(row==0)
    404                                 System.out.print(
    405                                         cube[side-1][row+1][column]);
    406                             else if(row==1)
    407                                 System.out.print(
    408                                         cube[side][row][column]);
    409                             else
    410                                 System.out.print(
    411                                         cube[side+1][row-1][column]);
    412                         } else if(side==3) {
    413                             if(row==0)
    414                                 System.out.print(
    415                                         cube[side-2][row+2][column]);
    416                             else if(row==1)
    417                                 System.out.print(
    418                                         cube[side-1][row+1][column]);
    419                             else
    420                                 System.out.print(
    421                                         cube[side][row][column]);
    422                         }
    423                         if(row==2 && column==2) System.out.println();
    424                     } else
    425                         System.out.print(cube[side][row][column]);
    426                 }
    427                 if(side==0 || side==4 || side==5)
    428                     System.out.println();
    429             }
    430 
    431         System.out.println();
    432     }
    433 
    434     /**
    435      * Rotates a piece of the cube to change its state.
    436      * A maximum of 18 child states are available.
    437      * @param rotations Amount of 90 degrees clockwise rotation (1-3).
    438      * @param face Type of rotation
    439      */
    440     public void rotate(int rotations, RubiksColor face) {
    441         try {
    442             checkValidRotation(rotations);
    443 
    444             switch (face) {
    445                 case RED:
    446                     if(rotations==1)
    447                         rotatePieceHorizontalClockwise(0);
    448                     else if(rotations==2)
    449                         rotatePieceHorizontal180(0);
    450                     else if(rotations==3)
    451                         rotatePieceHorizontalCounterClockwise(0);
    452                     break;
    453                 case GREEN:
    454                     if(rotations==1)
    455                         rotatePieceVerticalClockwise(0);
    456                     else if(rotations==2)
    457                         rotatePieceVertical180(0);
    458                     else if(rotations==3)
    459                         rotatePieceVerticalCounterClockwise(0);
    460                     break;
    461                 case YELLOW:
    462                     if(rotations==1)
    463                         rotateSidePieceVerticalClockwise(2);
    464                     else if(rotations==2)
    465                         rotateSidePieceVertical180(2);
    466                     else if(rotations==3)
    467                         rotateSidePieceVerticalCounterClockwise(2);
    468                     break;
    469                 case BLUE:
    470                     if(rotations==1)
    471                         rotatePieceVerticalCounterClockwise(2);
    472                     else if(rotations==2)
    473                         rotatePieceVertical180(2);
    474                     else if(rotations==3)
    475                         rotatePieceVerticalClockwise(2);
    476                     break;
    477                 case ORANGE:
    478                     if(rotations==1)
    479                         rotatePieceHorizontalClockwise(2);
    480                     else if(rotations==2)
    481                         rotatePieceHorizontal180(2);
    482                     else if(rotations==3)
    483                         rotatePieceHorizontalCounterClockwise(2);
    484                     break;
    485                 case WHITE:
    486                     if(rotations==1)
    487                         rotateSidePieceVerticalClockwise(0);
    488                     else if(rotations==2)
    489                         rotateSidePieceVertical180(0);
    490                     else if(rotations==3)
    491                         rotateSidePieceVerticalCounterClockwise(0);
    492                     break;
    493                 default:
    494                     break;
    495             }
    496         } catch (Exception e) {
    497             e.printStackTrace();
    498         }
    499     }
    500 
    501     /*
    502      * Rotates a piece vertically by 90 degrees counter clockwise.
    503      * @param piece The piece to rotate.
    504      */
    505     private void rotatePieceVerticalClockwise(int piece) throws Exception {
    506         // change side 0
    507         RubiksColor side0row0 = setColor(0, 0, piece, cube[5][0][piece]);
    508         RubiksColor side0row1 = setColor(0, 1, piece, cube[5][1][piece]);
    509         RubiksColor side0row2 = setColor(0, 2, piece, cube[5][2][piece]);
    510 
    511         // change side 2
    512         RubiksColor side2row0 = setColor(2, 0, piece, side0row0);
    513         RubiksColor side2row1 = setColor(2, 1, piece, side0row1);
    514         RubiksColor side2row2 = setColor(2, 2, piece, side0row2);
    515 
    516         // change side 4
    517         RubiksColor side4row0 = setColor(4, 0, piece, side2row0);
    518         RubiksColor side4row1 = setColor(4, 1, piece, side2row1);
    519         RubiksColor side4row2 = setColor(4, 2, piece, side2row2);
    520 
    521         // change side 5
    522         RubiksColor side5row0 = setColor(5, 0, piece, side4row0);
    523         RubiksColor side5row1 = setColor(5, 1, piece, side4row1);
    524         RubiksColor side5row2 = setColor(5, 2, piece, side4row2);
    525 
    526         if(piece==0) rotateSideClockwise(1);
    527         else if(piece==2) rotateSideCounterClockwise(3);
    528     }
    529 
    530     /*
    531      * Rotates a piece vertically by 90 degrees counter clockwise.
    532      * @param piece The piece to rotate.
    533      */
    534     private void rotatePieceVerticalCounterClockwise(int piece) throws Exception {
    535         // change side 0
    536         RubiksColor side0row0 = setColor(0, 0, piece, cube[2][0][piece]);
    537         RubiksColor side0row1 = setColor(0, 1, piece, cube[2][1][piece]);
    538         RubiksColor side0row2 = setColor(0, 2, piece, cube[2][2][piece]);
    539 
    540         // change side 5
    541         RubiksColor side5row0 = setColor(5, 0, piece, side0row0);
    542         RubiksColor side5row1 = setColor(5, 1, piece, side0row1);
    543         RubiksColor side5row2 = setColor(5, 2, piece, side0row2);
    544 
    545         // change side 4
    546         RubiksColor side4row0 = setColor(4, 0, piece, side5row0);
    547         RubiksColor side4row1 = setColor(4, 1, piece, side5row1);
    548         RubiksColor side4row2 = setColor(4, 2, piece, side5row2);
    549 
    550         // change side 2
    551         RubiksColor side2row0 = setColor(2, 0, piece, side4row0);
    552         RubiksColor side2row1 = setColor(2, 1, piece, side4row1);
    553         RubiksColor side2row2 = setColor(2, 2, piece, side4row2);
    554 
    555         if(piece==0) rotateSideCounterClockwise(1);
    556         else if(piece==2) rotateSideClockwise(3);
    557     }
    558 
    559     /*
    560      * Rotates a piece vertically by 180 degrees.
    561      * @param piece The piece to rotate.
    562      */
    563     private void rotatePieceVertical180(int piece) throws Exception {
    564         // switch side 0 with side 4
    565         switchColors(0, 0, piece, 4, 0, piece);
    566         switchColors(0, 1, piece, 4, 1, piece);
    567         switchColors(0, 2, piece, 4, 2, piece);
    568 
    569         // switch side 5 with side 2
    570         switchColors(5, 0, piece, 2, 0, piece);
    571         switchColors(5, 1, piece, 2, 1, piece);
    572         switchColors(5, 2, piece, 2, 2, piece);
    573 
    574         if(piece==0) rotateSide180(1);
    575         else if(piece==2) rotateSide180(3);
    576     }
    577 
    578     /*
    579     * Rotates a side piece vertically by 90 degrees counter clockwise.
    580     * @param piece The piece to rotate.
    581     */
    582     private void rotateSidePieceVerticalClockwise(int piece) throws Exception {
    583         // change side 0
    584         RubiksColor side0col0 = setColor(0, piece, 0, cube[1][2][piece]);
    585         RubiksColor side0col1 = setColor(0, piece, 1, cube[1][1][piece]);
    586         RubiksColor side0col2 = setColor(0, piece, 2, cube[1][0][piece]);
    587 
    588         // change side 3
    589         piece = switchPiece(piece);
    590         RubiksColor side3col0 = setColor(3, 0, piece, side0col0);
    591         RubiksColor side3col1 = setColor(3, 1, piece, side0col1);
    592         RubiksColor side3col2 = setColor(3, 2, piece, side0col2);
    593 
    594         // change side 4
    595         RubiksColor side4col0 = setColor(4, piece, 2, side3col0);
    596         RubiksColor side4col1 = setColor(4, piece, 1, side3col1);
    597         RubiksColor side4col2 = setColor(4, piece, 0, side3col2);
    598         piece = switchPiece(piece);
    599 
    600         // change side 1
    601         RubiksColor side1col0 = setColor(1, 2, piece, side4col0);
    602         RubiksColor side1col1 = setColor(1, 1, piece, side4col1);
    603         RubiksColor side1col2 = setColor(1, 0, piece, side4col2);
    604 
    605         if(piece==0) rotateSideCounterClockwise(5);
    606         else if(piece==2) rotateSideClockwise(2);
    607     }
    608 
    609     /*
    610      * Rotates a side piece vertically by 90 degrees counter clockwise.
    611      * @param piece The piece to rotate.
    612      */
    613     private void rotateSidePieceVerticalCounterClockwise(int piece) throws Exception {
    614         // change side 0
    615         RubiksColor side0col0 = setColor(0, piece, 0, cube[3][0][switchPiece(piece)]);
    616         RubiksColor side0col1 = setColor(0, piece, 1, cube[3][1][switchPiece(piece)]);
    617         RubiksColor side0col2 = setColor(0, piece, 2, cube[3][2][switchPiece(piece)]);
    618 
    619         // change side 1
    620         RubiksColor side1col0 = setColor(1, 2, piece, side0col0);
    621         RubiksColor side1col1 = setColor(1, 1, piece, side0col1);
    622         RubiksColor side1col2 = setColor(1, 0, piece, side0col2);
    623 
    624         // change side 4
    625         piece = switchPiece(piece);
    626         RubiksColor side4col0 = setColor(4, piece, 2, side1col0);
    627         RubiksColor side4col1 = setColor(4, piece, 1, side1col1);
    628         RubiksColor side4col2 = setColor(4, piece, 0, side1col2);
    629 
    630         // change side 3
    631         RubiksColor side3col0 = setColor(3, 0, piece, side4col0);
    632         RubiksColor side3col1 = setColor(3, 1, piece, side4col1);
    633         RubiksColor side3col2 = setColor(3, 2, piece, side4col2);
    634         piece = switchPiece(piece);
    635 
    636         if(piece==0) rotateSideClockwise(5);
    637         else if(piece==2) rotateSideCounterClockwise(2);
    638     }
    639 
    640     /*
    641      * Rotates a side piece vertically by 180 degrees.
    642      * @param piece The piece to rotate.
    643      */
    644     private void rotateSidePieceVertical180(int piece) throws Exception {
    645         // switch side 0 with side 4
    646         switchColors(0, piece, 2, 4, switchPiece(piece), 0);
    647         switchColors(0, piece, 1, 4, switchPiece(piece), 1);
    648         switchColors(0, piece, 0, 4, switchPiece(piece), 2);
    649 
    650         // switch side 1 with side 3
    651         switchColors(1, 2, piece, 3, 0, switchPiece(piece));
    652         switchColors(1, 1, piece, 3, 1, switchPiece(piece));
    653         switchColors(1, 0, piece, 3, 2, switchPiece(piece));
    654 
    655         if(piece==0) rotateSide180(5);
    656         else if(piece==2) rotateSide180(2);
    657     }
    658 
    659     /*
    660      * Rotates a piece horizontally by 90 degrees clockwise.
    661      * @param piece The piece to rotate.
    662      */
    663     private void rotatePieceHorizontalClockwise(int piece) throws Exception {
    664         // change side 1
    665         RubiksColor side1col0 = setColor(1, piece, 0, cube[2][piece][0]);
    666         RubiksColor side1col1 = setColor(1, piece, 1, cube[2][piece][1]);
    667         RubiksColor side1col2 = setColor(1, piece, 2, cube[2][piece][2]);
    668 
    669         // change side 5
    670         piece = switchPiece(piece);
    671         RubiksColor side5col0 = setColor(5, piece, 2, side1col0);
    672         RubiksColor side5col1 = setColor(5, piece, 1, side1col1);
    673         RubiksColor side5col2 = setColor(5, piece, 0, side1col2);
    674         piece = switchPiece(piece);
    675 
    676         // change side 3
    677         RubiksColor side3col0 = setColor(3, piece, 0, side5col0);
    678         RubiksColor side3col1 = setColor(3, piece, 1, side5col1);
    679         RubiksColor side3col2 = setColor(3, piece, 2, side5col2);
    680 
    681         // change side 2
    682         RubiksColor side2col0 = setColor(2, piece, 0, side3col0);
    683         RubiksColor side2col1 = setColor(2, piece, 1, side3col1);
    684         RubiksColor side2col2 = setColor(2, piece, 2, side3col2);
    685 
    686         if(piece==0) rotateSideClockwise(0);
    687         else if(piece==2) rotateSideCounterClockwise(4);
    688     }
    689 
    690     /*
    691      * Rotates a piece horizontally by 90 degrees counter clockwise.
    692      * @param piece The piece to rotate.
    693      */
    694     private void rotatePieceHorizontalCounterClockwise(int piece) throws Exception {
    695         // change side 3
    696         RubiksColor side3col0 = setColor(3, piece, 0, cube[2][piece][0]);
    697         RubiksColor side3col1 = setColor(3, piece, 1, cube[2][piece][1]);
    698         RubiksColor side3col2 = setColor(3, piece, 2, cube[2][piece][2]);
    699 
    700         // change side 5
    701         piece = switchPiece(piece);
    702         RubiksColor side5col0 = setColor(5, piece, 2, side3col0);
    703         RubiksColor side5col1 = setColor(5, piece, 1, side3col1);
    704         RubiksColor side5col2 = setColor(5, piece, 0, side3col2);
    705         piece = switchPiece(piece);
    706 
    707         // change side 1
    708         RubiksColor side1col0 = setColor(1, piece, 0, side5col0);
    709         RubiksColor side1col1 = setColor(1, piece, 1, side5col1);
    710         RubiksColor side1col2 = setColor(1, piece, 2, side5col2);
    711 
    712         // change side 2
    713         RubiksColor side2col0 = setColor(2, piece, 0, side1col0);
    714         RubiksColor side2col1 = setColor(2, piece, 1, side1col1);
    715         RubiksColor side2col2 = setColor(2, piece, 2, side1col2);
    716 
    717         if(piece==0) rotateSideCounterClockwise(0);
    718         else if(piece==2) rotateSideClockwise(4);
    719     }
    720 
    721     /*
    722      * Rotates a piece horizontally by 180 degrees.
    723      * @param piece The piece to rotate.
    724      */
    725     private void rotatePieceHorizontal180(int piece) throws Exception {
    726         // switch side 2 with side 5
    727         switchColors(2, piece, 0, 5, switchPiece(piece), 2);
    728         switchColors(2, piece, 1, 5, switchPiece(piece), 1);
    729         switchColors(2, piece, 2, 5, switchPiece(piece), 0);
    730 
    731         // switch side 1 with side 3
    732         switchColors(1, piece, 0, 3, piece, 0);
    733         switchColors(1, piece, 1, 3, piece, 1);
    734         switchColors(1, piece, 2, 3, piece, 2);
    735 
    736         if(piece==0) rotateSide180(0);
    737         else if(piece==2) rotateSide180(4);
    738     }
    739 
    740     /*
    741      * Rotates the color values of one side by 90 degrees clockwise.
    742      * @param side The side to rotate.
    743      */
    744     private void rotateSideClockwise(int side) throws Exception {
    745         checkValidSide(side);
    746 
    747         // side corners
    748         RubiksColor row0col0 = setColor(side, 0, 0, cube[side][2][0]);
    749         RubiksColor row0col2 = setColor(side, 0, 2, row0col0);
    750         RubiksColor row2col2 = setColor(side, 2, 2, row0col2);
    751         RubiksColor row2col0 = setColor(side, 2, 0, row2col2);
    752 
    753         // side edges
    754         RubiksColor row0col1 = setColor(side, 0, 1, cube[side][1][0]);
    755         RubiksColor row1col2 = setColor(side, 1, 2, row0col1);
    756         RubiksColor row2col1 = setColor(side, 2, 1, row1col2);
    757         RubiksColor row1col0 = setColor(side, 1, 0, row2col1);
    758     }
    759 
    760     /*
    761      * Rotates the color values of one side by 90 degrees counter clockwise.
    762      * @param side The side to rotate.
    763      */
    764     private void rotateSideCounterClockwise(int side) throws Exception {
    765         checkValidSide(side);
    766 
    767         // side corners
    768         RubiksColor row0col0 = setColor(side, 0, 0, cube[side][0][2]);
    769         RubiksColor row2col0 = setColor(side, 2, 0, row0col0);
    770         RubiksColor row2col2 = setColor(side, 2, 2, row2col0);
    771         RubiksColor row0col2 = setColor(side, 0, 2, row2col2);
    772 
    773         // side edges
    774         RubiksColor row0col1 = setColor(side, 0, 1, cube[side][1][2]);
    775         RubiksColor row1col0 = setColor(side, 1, 0, row0col1);
    776         RubiksColor row2col1 = setColor(side, 2, 1, row1col0);
    777         RubiksColor row1col2 = setColor(side, 1, 2, row2col1);
    778     }
    779 
    780     /*
    781      * Rotates the color values of one side by 180 degrees.
    782      * @param side The side to rotate.
    783      */
    784     private void rotateSide180(int side) throws Exception {
    785         checkValidSide(side);
    786 
    787         // side corners
    788         switchColors(side, 0, 0, side, 2, 2);
    789         switchColors(side, 2, 0, side, 0, 2);
    790 
    791         // side edges
    792         switchColors(side, 0, 1, side, 2, 1);
    793         switchColors(side, 1, 0, side, 1, 2);
    794     }
    795 
    796 
    797     /*
    798      * Sets the color in a side-row-col coordinate of the cube with a new color.
    799      * @param side The side of the cube.
    800      * @param row The row of the cube.
    801      * @param col The column of the cube.
    802      * @param color The new color for the side-row-col.
    803      */
    804     private RubiksColor setColor(int side, int row, int col, RubiksColor color) {
    805         RubiksColor oldValue = cube[side][row][col];
    806         cube[side][row][col] = color;
    807         return oldValue;
    808     }
    809 
    810     /*
    811      * Switches the values of one side-row-column coordinate with another.
    812      */
    813     private void switchColors(
    814             int _side, int _row, int _col,
    815             int side, int row, int col) {
    816         RubiksColor oldValue = cube[_side][_row][_col];
    817         cube[_side][_row][_col] = cube[side][row][col];
    818         cube[side][row][col] = oldValue;
    819     }
    820 
    821     /*
    822      * Assures the parameter is in range of the amount of sides the cube has.
    823      * @param side The number to be checked.
    824      */
    825     private void checkValidSide(int side) throws Exception {
    826         if(side >= CUBE_SIDES || side < 0)
    827             throw new Exception();
    828     }
    829 
    830     /*
    831      * Checks if piece is in range 0 to 1, only outer pieces can be rotated.
    832      * @param piece The piece number.
    833      */
    834     private void checkValidRotation(int rotations) throws Exception {
    835         if(rotations > 3 || rotations < 1)
    836             throw new Exception();
    837     }
    838 
    839     /*
    840      * Since cube display is a flatten cube, some rotations require the
    841      * piece value to switch.
    842      * @param piece The piece to switch values.
    843      * @return The opposite piece value.
    844      */
    845     private int switchPiece(int piece) {
    846         if(piece==2) return 0; else return 2;
    847     }
    848 
    849     private void fillInMiddleColors() {
    850         cube[0][1][1] = RubiksColor.RED;
    851         cube[1][1][1] = RubiksColor.GREEN;
    852         cube[2][1][1] = RubiksColor.YELLOW;
    853         cube[3][1][1] = RubiksColor.BLUE;
    854         cube[4][1][1] = RubiksColor.ORANGE;
    855         cube[5][1][1] = RubiksColor.WHITE;
    856     }
    857 
    858     /**
    859      * Checks if this cube has same state as another cube.
    860      * @param otherCube The cube to compare with this.
    861      * @return If it's the same or not.
    862      */
    863     public boolean isEqualTo(RubiksCube otherCube) {
    864         RubiksColor[][][] otherColors = otherCube.getCubeArray();
    865         int side,row,column;
    866         for (side=0; side<CUBE_SIDES; side++)
    867             for(row=0; row<CUBE_SIZE; row++)
    868                 for (column=0; column<CUBE_SIZE; column++) {
    869                     if(!cube[side][row][column].
    870                             equals(otherColors[side][row][column]))
    871                         return false;
    872                 }
    873         return true;
    874     }
    875 }