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 }