rubikscube
college code for finding optimal rubiks cube solutions in java
git clone https://9o.is/git/rubikscube.git
RubiksCornerState.java
(3405B)
1 import java.util.LinkedList;
2 import java.util.List;
3
4 /**
5 * Holds part of the corner state of the rubik's cube with a
6 * heuristic that measures the amount of moves away from
7 * the goal state.
8 */
9 public class RubiksCornerState extends RubiksSubState {
10
11 private final String[][] COMBINATIONS = {
12 {"WRG", "RGW", "GWR"},
13 {"WBR", "BRW", "RWB"},
14 {"RYG", "YGR", "GRY"},
15 {"RBY", "BYR", "YRB"},
16 {"YOG", "OGY", "GYO"},
17 {"YBO", "BOY", "OYB"},
18 {"OWG", "WGO", "GOW"},
19 {"OBW", "BWO", "WOB"}};
20
21 public RubiksCornerState(String state, int heuristic) throws Exception {
22 super(state, heuristic);
23 if(!isValid(state))
24 throw new Exception();
25 }
26
27 public RubiksCornerState(String state) throws Exception {
28 super(state);
29 if(!isValid(state))
30 throw new Exception();
31 }
32
33
34 @Override
35 protected boolean isValid(String str) {
36 if(str.length() == 24) {
37 List<Integer> cornersChecked = new LinkedList<Integer>();
38 for(int i=0; i<str.length(); i+=3) {
39 String corner = str.substring(i,i+3).toUpperCase();
40 int check = isValidCorner(corner);
41 if(check == -1) return false;
42 else {
43 for(int cornerUsed : cornersChecked) {
44 if(cornerUsed == check) return false;
45 }
46 cornersChecked.add(check);
47 }
48 }
49 return true;
50 }
51 return false;
52 }
53
54 @Override
55 //TODO
56 protected int hashState() {
57 int[] c = new int[8];
58 int[] o = new int[7];
59 int[] arraycounter = {0,1,2,3,4,5,6,7};
60
61 for(int i=0; i<8;i++) {
62 String str = state.substring(i*3,(i*3)+3);
63 for(int j=0; j<8;j++) {
64 for(int k=0; k< COMBINATIONS[j].length; k++) {
65 if(str.compareTo(COMBINATIONS[j][k])==0) {
66 for(int m=j+1; m<arraycounter.length; m++) {
67 arraycounter[m] = arraycounter[m] - 1;
68 }
69 c[j] = arraycounter[j];
70 if(j < 7) o[j] = k;
71 }
72 }
73 }
74 }
75
76 int f1 =
77 fac(7)*c[7]+
78 fac(6)*c[6]+
79 fac(5)*c[5]+
80 fac(4)*c[4]+
81 fac(3)*c[3]+
82 fac(2)*c[2]+
83 fac(1)*c[1]+
84 fac(0)*c[0];
85 int f2 =
86 (int)(o[6]*Math.pow(3,6) +
87 o[5]*Math.pow(3,5) +
88 o[4]*Math.pow(3,4) +
89 o[3]*Math.pow(3,3) +
90 o[2]*Math.pow(3,2) +
91 o[1]*Math.pow(3,1) +
92 o[0]*Math.pow(3,0));
93
94 return 2187*f1 + f2;
95 }
96
97 /*
98 * Returns which corner out of all combinations is the string
99 * or -1 if it didn't match any.
100 */
101 private int isValidCorner(String corner) {
102 for(int i=0; i<COMBINATIONS.length; i++)
103 for(int j=0; j<COMBINATIONS[i].length; j++) {
104 if(COMBINATIONS[i][j].equals(corner))
105 return i;
106 }
107 return -1;
108 }
109 }