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 }