Revision d12d901a
Added by Leszek Koltunski over 2 years ago
src/main/java/org/distorted/objectlib/objects/TwistyBandaged2Bar.java | ||
---|---|---|
44 | 44 |
{ |
45 | 45 |
mStates = new ScrambleState[] |
46 | 46 |
{ |
47 |
new ScrambleState( new int[][] { {} , {0,1,1, 0,-1,1, 2,1,2, 2,-1,2}, {} }), |
|
48 |
new ScrambleState( new int[][] { {0,-1,1, 0,1,1, 0,2,1, 2,-1,1, 2,1,1, 2,2,1}, {0,2,1, 2,2,1} , {} }), |
|
49 |
new ScrambleState( new int[][] { {}, {0,2,2, 2,2,2} , {0,-1,2, 0,1,2, 0,2,2, 2,-1,2, 2,1,2, 2,2,2} }) |
|
47 |
new ScrambleState( new int[][] { {}, {0,1,1,0,-1,1,2,1,4,2,-1,4}, {} } ), |
|
48 |
new ScrambleState( new int[][] { {0,1,1,0,2,1,0,-1,1,1,1,2,1,2,1,1,-1,2,2,1,1,2,2,1,2,-1,1}, {0,2,1,1,1,1,1, 2,1,1,-1,1,2,2,1}, {}} ), |
|
49 |
new ScrambleState( new int[][] { {0,1,2,0,2,2,0,-1,2,1,1,1,1,2,2,1,-1,1,2,1,2,2,2,2,2,-1,2}, {}, {0,2,2,1,1,2,1,2,2,1,-1,2,2,2,2} } ), |
|
50 |
new ScrambleState( new int[][] { {0,2,3,1,1,3,1, 2,3,1,-1,3,2,2,3}, {}, {0,1,3,0,2,3,0,-1,3,1,1,4,1,2,3,1,-1,4,2,1,3,2,2,3,2,-1,3}} ), |
|
51 |
new ScrambleState( new int[][] { {}, {0,2,4,1,1,4,1,2,4,1,-1,4,2,2,4}, {0,1,4,0,2,4,0,-1,4,1,1,3,1,2,4,1,-1,3,2,1,4,2,2,4,2,-1,4} } ), |
|
50 | 52 |
}; |
51 | 53 |
} |
52 | 54 |
|
src/main/java/org/distorted/objectlib/objects/TwistyBandaged3Plate.java | ||
---|---|---|
44 | 44 |
{ |
45 | 45 |
mStates = new ScrambleState[] |
46 | 46 |
{ |
47 |
new ScrambleState( new int[][] {{ 2,-1, 1, 2, 1, 6 }, { 0,-1, 5, 0, 1, 3 }, { 2,-1, 2, 2, 1, 4 }} ),
|
|
48 |
new ScrambleState( new int[][] {{ 2, 1, 0 }, { }, { 2, 1,10, 2, 2, 7 }} ),
|
|
49 |
new ScrambleState( new int[][] {{ }, { 0,-1,11, 0, 2, 8 }, { 2, 1, 0 }} ),
|
|
50 |
new ScrambleState( new int[][] {{ 2, 1,12, 2, 2, 9 }, { 0,-1, 0 }, { }} ),
|
|
51 |
new ScrambleState( new int[][] {{ 2,-1,10, 2, 2,13 }, { }, { 2,-1, 0 }} ),
|
|
52 |
new ScrambleState( new int[][] {{ }, { 0, 1, 0 }, { 2,-1,11, 2, 2,14 }} ),
|
|
53 |
new ScrambleState( new int[][] {{ 2,-1, 0 }, { 0, 1,12, 0, 2,15 }, { }} ),
|
|
54 |
new ScrambleState( new int[][] {{ }, { 2,-2, 7, 2,-1, 7, 2, 1, 7, 2, 2, 7}, { 2,-1,10, 2, 2, 1 }} ),
|
|
55 |
new ScrambleState( new int[][] {{ 0,-2, 8, 0,-1, 8, 0, 1, 8, 0, 2, 8}, { 0, 1,11, 0, 2, 2 }, { }} ),
|
|
56 |
new ScrambleState( new int[][] {{ 2,-1,12, 2, 2, 3 }, { }, { 0,-2, 9, 0,-1, 9, 0, 1, 9, 0, 2, 9}} ),
|
|
57 |
new ScrambleState( new int[][] {{ 2,-1,13, 2, 1, 4 }, { 2,-2,10, 2,-1,10, 2, 1,10, 2, 2,10}, { 2,-1, 1, 2, 1, 7 }} ),
|
|
58 |
new ScrambleState( new int[][] {{ 0,-2,11, 0,-1,11, 0, 1,11, 0, 2,11}, { 0,-1, 8, 0, 1, 2 }, { 2,-1,14, 2, 1, 5 }} ),
|
|
59 |
new ScrambleState( new int[][] {{ 2,-1, 3, 2, 1, 9 }, { 0,-1, 6, 0, 1,15 }, { 0,-2,12, 0,-1,12, 0, 1,12, 0, 2,12}} ),
|
|
60 |
new ScrambleState( new int[][] {{ 2, 1,10, 2, 2, 4 }, { 2,-2,13, 2,-1,13, 2, 1,13, 2, 2,13}, { }} ),
|
|
61 |
new ScrambleState( new int[][] {{ 0,-2,14, 0,-1,14, 0, 1,14, 0, 2,14}, { }, { 2, 1,11, 2, 2, 5 }} ),
|
|
62 |
new ScrambleState( new int[][] {{ }, { 0,-1,12, 0, 2, 6 }, { 0,-2,15, 0,-1,15, 0, 1,15, 0, 2,15}} )
|
|
47 |
new ScrambleState( new int[][] { {2,-1, 1,2, 1, 2} , {0,-1, 7,0, 1, 5} , {2,-1, 10,2, 1, 11} } ),
|
|
48 |
new ScrambleState( new int[][] { {2, 2, 2,2, 1, 0} , {} , {2, 2, 14,2, 1, 12} } ),
|
|
49 |
new ScrambleState( new int[][] { {2,-1, 0,2, 2, 1} , {0, 2, 3,0, 1, 4} , {} } ),
|
|
50 |
new ScrambleState( new int[][] { {} , {0,-1, 4,0, 2, 2} , {0,-1, 3,0, 2, 3,0, 1, 3} } ),
|
|
51 |
new ScrambleState( new int[][] { {2,-1, 5,2, 1, 6} , {0,-1, 2,0, 1, 3} , {0,-1, 4,0, 2, 4,0, 1, 4} } ),
|
|
52 |
new ScrambleState( new int[][] { {2, 2, 6,2, 1, 4} , {0,-1, 0,0, 2, 7} , {} } ),
|
|
53 |
new ScrambleState( new int[][] { {2,-1, 4,2, 2, 5} , {} , {0,-1, 6,0, 2, 6,0, 1, 6} } ),
|
|
54 |
new ScrambleState( new int[][] { {} , {0, 2, 5,0, 1, 0} , {2,-1, 8,2, 2, 15} } ),
|
|
55 |
new ScrambleState( new int[][] { {0,-1, 8,0, 2, 8,0, 1, 8}, {0,-1, 9,0, 1, 10} , {2,-1, 15,2, 1, 7} } ),
|
|
56 |
new ScrambleState( new int[][] { {0,-1, 9,0, 2, 9,0, 1, 9}, {0, 2, 10,0, 1, 8} , {} } ),
|
|
57 |
new ScrambleState( new int[][] { {} , {0,-1, 8,0, 2, 9} , {2, 2, 11,2, 1, 0} } ),
|
|
58 |
new ScrambleState( new int[][] { {2,-1, 12,2, 2, 13} , {} , {2,-1, 0,2, 2, 10} } ),
|
|
59 |
new ScrambleState( new int[][] { {2,-1, 13,2, 1, 11} , {2,-1, 12,2, 2, 12,2, 1, 12}, {2,-1, 1,2, 1, 14} } ),
|
|
60 |
new ScrambleState( new int[][] { {2, 2, 11,2, 1, 12} , {2,-1, 13,2, 2, 13,2, 1, 13}, {} } ),
|
|
61 |
new ScrambleState( new int[][] { {} , {2,-1, 14,2, 2, 14,2, 1, 14}, {2,-1, 12,2, 2, 1} } ),
|
|
62 |
new ScrambleState( new int[][] { {0,-1, 15,0, 2, 15,0, 1, 15}, {} , {2, 2, 7,2, 1, 8} } ),
|
|
63 | 63 |
}; |
64 | 64 |
} |
65 | 65 |
|
src/main/java/org/distorted/objectlib/scrambling/ScrambleStateBandaged3x3.java | ||
---|---|---|
28 | 28 |
{ |
29 | 29 |
private static final long INVALID_MOVE = -1; |
30 | 30 |
private static final int NUM_MOVES = 27; |
31 |
private static final int NUM_ISOMETRIES = 24; |
|
32 | 31 |
|
33 | 32 |
private static final int AXIS_X = 0; |
34 | 33 |
private static final int AXIS_Y = 1; |
... | ... | |
39 | 38 |
private static final int LAYER_R = 2; |
40 | 39 |
|
41 | 40 |
private long mID; |
42 |
private final long[] mIsometries;
|
|
41 |
private int mDistance;
|
|
43 | 42 |
private final long[] mMoves; |
44 | 43 |
|
45 | 44 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
46 | 45 |
|
47 | 46 |
public ScrambleStateBandaged3x3(long id) |
48 | 47 |
{ |
48 |
mDistance = -1; |
|
49 | 49 |
mID = id; |
50 |
mIsometries = createIsometries(mID); |
|
51 | 50 |
mMoves = createMoves(mID); |
52 | 51 |
} |
53 | 52 |
|
... | ... | |
60 | 59 |
graph.add(bsg); |
61 | 60 |
|
62 | 61 |
insertChildren(graph,id); |
63 |
pruneGraph(graph,id); |
|
62 |
pruneGraph(graph,id,false); |
|
63 |
computeDistance(graph,id,0); |
|
64 |
removeDisconnectedParts(graph); |
|
64 | 65 |
remapGraph(graph); |
65 | 66 |
|
66 | 67 |
int num = graph.size(); |
... | ... | |
79 | 80 |
{ |
80 | 81 |
ScrambleStateBandaged3x3 bsg = findState(list,id); |
81 | 82 |
|
82 |
android.util.Log.e("D", "inserting children of "+id); |
|
83 |
|
|
84 | 83 |
if( bsg==null ) |
85 | 84 |
{ |
86 | 85 |
android.util.Log.e("D", "error: "+id+" doesn't exist"); |
... | ... | |
103 | 102 |
} |
104 | 103 |
else if( tmp.mID != move ) |
105 | 104 |
{ |
106 |
android.util.Log.e("D", "id "+id+" move: "+move+" leads to already existing "+tmp.mID); |
|
107 | 105 |
bsg.setMove(i,tmp.mID); |
108 | 106 |
} |
109 | 107 |
} |
... | ... | |
112 | 110 |
|
113 | 111 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
114 | 112 |
|
115 |
private static void pruneGraph(ArrayList<ScrambleStateBandaged3x3> list, long id) |
|
113 |
private static void pruneGraph(ArrayList<ScrambleStateBandaged3x3> list, long id, boolean startingPrunedAlready)
|
|
116 | 114 |
{ |
117 | 115 |
int num = list.size(); |
118 | 116 |
boolean pruned = false; |
... | ... | |
125 | 123 |
if( bsg.numAxis()<2 ) |
126 | 124 |
{ |
127 | 125 |
long prunedID = bsg.getID(); |
126 |
if( id!=prunedID || !startingPrunedAlready ) |
|
127 |
{ |
|
128 |
startingPrunedAlready = true; |
|
129 |
remapID(list,prunedID,INVALID_MOVE); |
|
130 |
} |
|
128 | 131 |
|
129 |
android.util.Log.e("D", "pruning id "+prunedID+" axis: "+bsg.numAxis() ); |
|
130 |
bsg.printMoves(); |
|
131 |
|
|
132 |
if( id!=prunedID ) list.remove(i); // do not remove the starting point, even if |
|
133 |
// it does have only 1 axis |
|
134 |
pruned = true; |
|
135 |
remapID(list,prunedID,INVALID_MOVE); |
|
136 |
break; |
|
132 |
// do not remove the starting point, even if it does have only 1 axis |
|
133 |
if( id!=prunedID ) |
|
134 |
{ |
|
135 |
list.remove(i); |
|
136 |
pruned = true; |
|
137 |
break; |
|
138 |
} |
|
137 | 139 |
} |
138 | 140 |
} |
139 | 141 |
|
140 |
if( pruned ) pruneGraph(list,id); |
|
141 |
} |
|
142 |
|
|
143 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
144 |
|
|
145 |
private void printMoves() |
|
146 |
{ |
|
147 |
String moves = ""; |
|
148 |
|
|
149 |
for(int i=0; i<NUM_MOVES; i++) |
|
150 |
{ |
|
151 |
moves += (" " + mMoves[i]); |
|
152 |
} |
|
153 |
|
|
154 |
android.util.Log.e("D", moves); |
|
142 |
if( pruned ) pruneGraph(list,id,startingPrunedAlready); |
|
155 | 143 |
} |
156 | 144 |
|
157 | 145 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
191 | 179 |
|
192 | 180 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
193 | 181 |
|
194 |
private static boolean isAnIsometry(ScrambleStateBandaged3x3 bsg, long id)
|
|
182 |
private static void computeDistance(ArrayList<ScrambleStateBandaged3x3> list, long id, int distance)
|
|
195 | 183 |
{ |
196 |
if( bsg.mID==id ) return true; |
|
197 |
for(int i=0; i<NUM_ISOMETRIES-1; i++) if ( bsg.mIsometries[i]==id ) return true; |
|
198 |
return false; |
|
184 |
ScrambleStateBandaged3x3 state = findState(list,id); |
|
185 |
|
|
186 |
if( state==null ) |
|
187 |
{ |
|
188 |
android.util.Log.e("D", "error: "+id+" doesn't exist"); |
|
189 |
return; |
|
190 |
} |
|
191 |
|
|
192 |
if( state.mDistance<0 ) |
|
193 |
{ |
|
194 |
state.mDistance = distance; |
|
195 |
|
|
196 |
for(int i=0; i<NUM_MOVES; i++) |
|
197 |
{ |
|
198 |
long move = state.getMove(i); |
|
199 |
|
|
200 |
if( move!=INVALID_MOVE ) |
|
201 |
{ |
|
202 |
computeDistance(list,move,distance+1); |
|
203 |
} |
|
204 |
} |
|
205 |
} |
|
206 |
} |
|
207 |
|
|
208 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
209 |
|
|
210 |
private static void removeDisconnectedParts(ArrayList<ScrambleStateBandaged3x3> list) |
|
211 |
{ |
|
212 |
int num = list.size(); |
|
213 |
ScrambleStateBandaged3x3 bsg; |
|
214 |
|
|
215 |
for(int i=0; i<num; i++) |
|
216 |
{ |
|
217 |
bsg = list.get(i); |
|
218 |
|
|
219 |
if( bsg.mDistance<0 ) |
|
220 |
{ |
|
221 |
list.remove(i); |
|
222 |
i--; |
|
223 |
num--; |
|
224 |
} |
|
225 |
} |
|
199 | 226 |
} |
200 | 227 |
|
201 | 228 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
208 | 235 |
for(int i=0; i<num; i++) |
209 | 236 |
{ |
210 | 237 |
bsg= list.get(i); |
211 |
if( isAnIsometry(bsg,id) ) return bsg;
|
|
238 |
if( bsg.mID==id ) return bsg;
|
|
212 | 239 |
} |
213 | 240 |
|
214 | 241 |
return null; |
... | ... | |
222 | 249 |
String y = getTable(bsg, 9); |
223 | 250 |
String z = getTable(bsg,18); |
224 | 251 |
|
225 |
return " new ScrambleStateGraph( new int[][] { "+x+", "+y+", "+z+" } ),";
|
|
252 |
return " new ScrambleState( new int[][] { "+x+", "+y+", "+z+" } ),"; |
|
226 | 253 |
} |
227 | 254 |
|
228 | 255 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
241 | 268 |
|
242 | 269 |
String ret = ""; |
243 | 270 |
|
244 |
if( m0!=INVALID_MOVE ) ret += formatRet(ret,0, 1,m0);
|
|
271 |
if( m0!=INVALID_MOVE ) ret += formatRet(ret,0,-1,m0);
|
|
245 | 272 |
if( m1!=INVALID_MOVE ) ret += formatRet(ret,0, 2,m1); |
246 |
if( m2!=INVALID_MOVE ) ret += formatRet(ret,0,-1,m2);
|
|
247 |
if( m3!=INVALID_MOVE ) ret += formatRet(ret,1, 1,m3);
|
|
273 |
if( m2!=INVALID_MOVE ) ret += formatRet(ret,0, 1,m2);
|
|
274 |
if( m3!=INVALID_MOVE ) ret += formatRet(ret,1,-1,m3);
|
|
248 | 275 |
if( m4!=INVALID_MOVE ) ret += formatRet(ret,1, 2,m4); |
249 |
if( m5!=INVALID_MOVE ) ret += formatRet(ret,1,-1,m5);
|
|
250 |
if( m6!=INVALID_MOVE ) ret += formatRet(ret,2, 1,m6);
|
|
276 |
if( m5!=INVALID_MOVE ) ret += formatRet(ret,1, 1,m5);
|
|
277 |
if( m6!=INVALID_MOVE ) ret += formatRet(ret,2,-1,m6);
|
|
251 | 278 |
if( m7!=INVALID_MOVE ) ret += formatRet(ret,2, 2,m7); |
252 |
if( m8!=INVALID_MOVE ) ret += formatRet(ret,2,-1,m8);
|
|
279 |
if( m8!=INVALID_MOVE ) ret += formatRet(ret,2, 1,m8);
|
|
253 | 280 |
|
254 | 281 |
return formatL("{" + ret + "}"); |
255 | 282 |
} |
... | ... | |
367 | 394 |
} |
368 | 395 |
|
369 | 396 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
370 |
|
|
371 |
private static long[] createIsometries(long id) |
|
372 |
{ |
|
373 |
long[] ret = new long[NUM_ISOMETRIES-1]; |
|
374 |
|
|
375 |
ret[ 0] = turnWhole( id,AXIS_X); |
|
376 |
ret[ 1] = turnWhole(ret[ 0],AXIS_X); |
|
377 |
ret[ 2] = turnWhole(ret[ 1],AXIS_X); |
|
378 |
ret[ 3] = turnWhole(ret[ 2],AXIS_Y); |
|
379 |
ret[ 4] = turnWhole(ret[ 3],AXIS_Y); |
|
380 |
ret[ 5] = turnWhole(ret[ 4],AXIS_Y); |
|
381 |
ret[ 6] = turnWhole(ret[ 5],AXIS_Z); |
|
382 |
ret[ 7] = turnWhole(ret[ 6],AXIS_Z); |
|
383 |
ret[ 8] = turnWhole(ret[ 7],AXIS_Z); |
|
384 |
ret[ 9] = turnWhole(ret[ 8],AXIS_X); |
|
385 |
ret[10] = turnWhole(ret[ 9],AXIS_X); |
|
386 |
ret[11] = turnWhole(ret[10],AXIS_X); |
|
387 |
ret[12] = turnWhole(ret[11],AXIS_Y); |
|
388 |
ret[13] = turnWhole(ret[12],AXIS_Y); |
|
389 |
ret[14] = turnWhole(ret[13],AXIS_Y); |
|
390 |
ret[15] = turnWhole(ret[ 5],AXIS_X); |
|
391 |
ret[16] = turnWhole(ret[15],AXIS_Y); |
|
392 |
ret[17] = turnWhole(ret[16],AXIS_Y); |
|
393 |
ret[18] = turnWhole(ret[ 4],AXIS_X); |
|
394 |
ret[19] = turnWhole(ret[18],AXIS_X); |
|
395 |
ret[20] = turnWhole(ret[19],AXIS_X); |
|
396 |
ret[21] = turnWhole(ret[ 3],AXIS_Z); |
|
397 |
ret[22] = turnWhole(ret[21],AXIS_Z); |
|
398 |
/* |
|
399 |
String iso = "isometries of "+id+" :"; |
|
400 |
|
|
401 |
for(int i=0; i<NUM_ISOMETRIES-1; i++) |
|
402 |
{ |
|
403 |
iso += (" " + ret[i]); |
|
404 |
} |
|
405 |
|
|
406 |
android.util.Log.e("D", iso); |
|
407 |
*/ |
|
408 |
/* |
|
409 |
long t = turnWhole(1,AXIS_X); |
|
410 |
|
|
411 |
android.util.Log.e("D", "1 turned along X: "+t); |
|
412 |
*/ |
|
413 |
return ret; |
|
414 |
} |
|
415 |
|
|
416 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
417 |
// 0 : DF,DRF |
|
418 |
// 1 : DF,DLF |
|
419 |
// 2 : DR,DRF |
|
420 |
// 3 : D,DF |
|
421 |
// 4 : DL,DLF |
|
422 |
// 5 : D,DR |
|
423 |
// 6 : D,DL |
|
424 |
// 7 : DR,DRB |
|
425 |
// 8 : D,DB |
|
426 |
// 9 : DL,DLB |
|
427 |
//10 : DB,DRB |
|
428 |
//11 : DB,DLB |
|
429 |
//12 : FR,DRF |
|
430 |
//13 : F,DF |
|
431 |
//14 : FL,DLF |
|
432 |
//15 : R,DR |
|
433 |
//16 : D,CORE |
|
434 |
//17 : L,DL |
|
435 |
//18 : BR,DRB |
|
436 |
//19 : B,DB |
|
437 |
//20 : BL,DLB |
|
438 |
//21 : F,FR |
|
439 |
//22 : F,FL |
|
440 |
//23 : R,FR |
|
441 |
//24 : F,CORE |
|
442 |
//25 : L,FL |
|
443 |
//26 : R,CORE |
|
444 |
//27 : L,CORE |
|
445 |
//28 : R,BR |
|
446 |
//29 : B,CORE |
|
447 |
//30 : L,BL |
|
448 |
//31 : B,BR |
|
449 |
//32 : B,BL |
|
450 |
//33 : FR,URF |
|
451 |
//34 : F,UF |
|
452 |
//35 : FL,ULF |
|
453 |
//36 : R,UR |
|
454 |
//37 : U,CORE |
|
455 |
//38 : L,UL |
|
456 |
//39 : BR,URB |
|
457 |
//40 : B,UB |
|
458 |
//41 : BL,ULB |
|
459 |
//42 : UF,URF |
|
460 |
//43 : UF,ULF |
|
461 |
//44 : UR,URF |
|
462 |
//45 : U,UF |
|
463 |
//46 : UL,ULF |
|
464 |
//47 : U,UR |
|
465 |
//48 : U,UL |
|
466 |
//49 : UR,URB |
|
467 |
//50 : U,UB |
|
468 |
//51 : UL,ULB |
|
469 |
//52 : UB,URB |
|
470 |
//53 : UB,ULB |
|
397 |
// Definition of the id: it's an 'Andreas signature' of a bandaged cube. |
|
398 |
// https://twistypuzzles.com/forum/viewtopic.php?t=24452&sid=f3b4ac0c611c4713e4d7840f1aabbb0b&start=350 |
|
471 | 399 |
|
472 | 400 |
private static long turn(long id, int axis, int layer) |
473 | 401 |
{ |
... | ... | |
567 | 495 |
return 0; |
568 | 496 |
} |
569 | 497 |
|
570 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
571 |
|
|
572 |
private static long turnWhole(long id, int axis) |
|
573 |
{ |
|
574 |
switch(axis) |
|
575 |
{ |
|
576 |
case AXIS_X: long x1 = cycle(id,9,14,46,41); // |
|
577 |
long x2 = cycle(x1,4,35,51,20); // left layer |
|
578 |
long x3 = cycle(x2,17,25,38,30);// |
|
579 |
|
|
580 |
long x4 = cycle(x3,8,13,45,40); // |
|
581 |
long x5 = cycle(x4,3,34,50,19); // mid layer |
|
582 |
long x6 = cycle(x5,16,24,37,29);// |
|
583 |
|
|
584 |
long x7 = cycle(x6,7,12,44,39); // |
|
585 |
long x8 = cycle(x7,2,33,49,18); // right layer |
|
586 |
long x9 = cycle(x8,15,23,36,28);// |
|
587 |
|
|
588 |
long x10= cycle(x9,1,43,53,11); // |
|
589 |
long x11= cycle(x10,6,22,48,32);// left lock |
|
590 |
long x12= cycle(x11,0,42,52,10);// |
|
591 |
return cycle(x12,5,21,47,31);// right lock |
|
592 |
|
|
593 |
case AXIS_Y: long y1 = cycle(id,1,9,10,2); // |
|
594 |
long y2 = cycle(y1,0,4,11,7); // bottom layer |
|
595 |
long y3 = cycle(y2,3,6,8,5); // |
|
596 |
|
|
597 |
long y4 = cycle(y3,21,25,32,28);// |
|
598 |
long y5 = cycle(y4,22,30,31,23);// mid layer |
|
599 |
long y6 = cycle(y5,24,27,29,26);// |
|
600 |
|
|
601 |
long y7 = cycle(y6,42,46,53,49);// |
|
602 |
long y8 = cycle(y7,43,51,52,44);// top layer |
|
603 |
long y9 = cycle(y8,45,48,50,47);// |
|
604 |
|
|
605 |
long y10= cycle(y9,12,14,20,18); // |
|
606 |
long y11= cycle(y10,13,17,19,15);// bottom lock |
|
607 |
long y12= cycle(y11,33,35,41,39);// |
|
608 |
return cycle(y12,34,38,40,36);// top lock |
|
609 |
|
|
610 |
case AXIS_Z: long z1 = cycle(id,10,20,53,39);// |
|
611 |
long z2 = cycle(z1,11,41,52,18);// back layer |
|
612 |
long z3 = cycle(z2,19,32,40,31);// |
|
613 |
|
|
614 |
long z4 = cycle(z3,5,17,48,36); // |
|
615 |
long z5 = cycle(z4,6,38,47,15); // mid layer |
|
616 |
long z6 = cycle(z5,16,27,37,26);// |
|
617 |
|
|
618 |
long z7 = cycle(z6,0,14,43,33); // |
|
619 |
long z8 = cycle(z7,1,35,42,12); // front layer |
|
620 |
long z9 = cycle(z8,13,22,34,21);// |
|
621 |
|
|
622 |
long z10= cycle(z9,7,9,51,49); // |
|
623 |
long z11= cycle(z10,8,30,50,28);// back lock |
|
624 |
long z12= cycle(z11,2,4,46,44); // |
|
625 |
return cycle(z12,3,25,45,23);// front lock |
|
626 |
} |
|
627 |
|
|
628 |
return 0; |
|
629 |
} |
|
630 |
|
|
631 | 498 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
632 | 499 |
// bit b1 in place of b2 etc. |
633 | 500 |
|
... | ... | |
644 | 511 |
return setBit(i3,b1,bit4); |
645 | 512 |
} |
646 | 513 |
|
647 |
|
|
648 | 514 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
649 |
// bit b1 in place of b2 etc. |
|
650 | 515 |
|
651 |
private static long cyclePriv(long id, int b1, int b2, int b3, int b4)
|
|
516 |
private static long getBit(long id, int bit)
|
|
652 | 517 |
{ |
653 |
long bit1 = getBit(id,b1); |
|
654 |
long bit2 = getBit(id,b2); |
|
655 |
long bit3 = getBit(id,b3); |
|
656 |
long bit4 = getBit(id,b4); |
|
657 |
|
|
658 |
android.util.Log.e("D", "bit1="+bit1+" bit2="+bit2+" bit3="+bit3+" bit4="+bit4); |
|
659 |
|
|
660 |
long i1 = setBitPriv(id,b2,bit1); |
|
661 |
long i2 = setBitPriv(i1,b3,bit2); |
|
662 |
long i3 = setBitPriv(i2,b4,bit3); |
|
663 |
long i4 = setBitPriv(i3,b1,bit4); |
|
664 |
|
|
665 |
|
|
666 |
android.util.Log.e("D", "i1="+i1+" i2="+i2+" i3="+i3+" i4="+i4); |
|
667 |
|
|
668 |
return i4; |
|
518 |
return (id>>bit)&0x1; |
|
669 | 519 |
} |
670 | 520 |
|
671 |
|
|
672 | 521 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
673 | 522 |
|
674 |
private static long setBitPriv(long id, int bit, long value)
|
|
523 |
private static long setBit(long id, int bit, long value) |
|
675 | 524 |
{ |
676 | 525 |
long old = getBit(id,bit); |
677 | 526 |
|
... | ... | |
681 | 530 |
id += (value==0 ? -diff : diff); |
682 | 531 |
} |
683 | 532 |
|
684 |
android.util.Log.e("D", "setBit: id: "+id+" bit="+bit+" value="+value+" old="+old+" ret="+id); |
|
685 |
|
|
686 | 533 |
return id; |
687 | 534 |
} |
688 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
689 | 535 |
|
690 |
private static long getBit(long id, int bit) |
|
536 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
537 |
/* |
|
538 |
private void printMoves() |
|
691 | 539 |
{ |
692 |
return (id>>bit)&0x1; |
|
540 |
String moves = ""; |
|
541 |
|
|
542 |
for(int i=0; i<NUM_MOVES; i++) |
|
543 |
{ |
|
544 |
moves += (" " + mMoves[i]); |
|
545 |
} |
|
546 |
|
|
547 |
android.util.Log.e("D", moves); |
|
693 | 548 |
} |
694 | 549 |
|
695 | 550 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
696 | 551 |
|
697 |
private static long setBit(long id, int bit, long value)
|
|
552 |
private static String printBits(long id)
|
|
698 | 553 |
{ |
699 |
long old = getBit(id,bit); |
|
554 |
String ret = "["; |
|
555 |
boolean first = true; |
|
700 | 556 |
|
701 |
if( old!=value )
|
|
557 |
for(int i=0; i<64; i++)
|
|
702 | 558 |
{ |
703 |
long diff = (1L<<bit); |
|
704 |
id += (value==0 ? -diff : diff); |
|
559 |
if( ( (id>>i)&0x1)==1 ) |
|
560 |
{ |
|
561 |
String num = (i<10 ? " "+i : ""+i); |
|
562 |
|
|
563 |
if( first ) { ret += num; first=false; } |
|
564 |
else ret += (","+num); |
|
565 |
} |
|
705 | 566 |
} |
706 | 567 |
|
707 |
return id;
|
|
568 |
return ret + "]";
|
|
708 | 569 |
} |
570 |
*/ |
|
709 | 571 |
} |
src/main/java/org/distorted/objectlib/scrambling/ScrambleStateBandagedEvil.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2021 Leszek Koltunski // |
|
3 |
// // |
|
4 |
// This file is part of Magic Cube. // |
|
5 |
// // |
|
6 |
// Magic Cube is free software: you can redistribute it and/or modify // |
|
7 |
// it under the terms of the GNU General Public License as published by // |
|
8 |
// the Free Software Foundation, either version 2 of the License, or // |
|
9 |
// (at your option) any later version. // |
|
10 |
// // |
|
11 |
// Magic Cube is distributed in the hope that it will be useful, // |
|
12 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of // |
|
13 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // |
|
14 |
// GNU General Public License for more details. // |
|
15 |
// // |
|
16 |
// You should have received a copy of the GNU General Public License // |
|
17 |
// along with Magic Cube. If not, see <http://www.gnu.org/licenses/>. // |
|
18 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
19 |
|
|
20 |
package org.distorted.objectlib.scrambling; |
|
21 |
|
|
22 |
import java.util.ArrayList; |
|
23 |
|
|
24 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
25 |
// producer of the ScrambleStateGraph - but only for a single Twisty Puzzle, the 'BandagedEvil'. |
|
26 |
|
|
27 |
public class ScrambleStateBandagedEvil |
|
28 |
{ |
|
29 |
private static final int INVALID_MOVE = -1; |
|
30 |
|
|
31 |
private static final int CORNER_S = 0; |
|
32 |
private static final int CORNER_X = 1; |
|
33 |
private static final int CORNER_Y = 2; |
|
34 |
private static final int CORNER_Z = 3; |
|
35 |
|
|
36 |
private static final int CENTER_0 = 0; |
|
37 |
private static final int CENTER_1 = 1; |
|
38 |
private static final int CENTER_2 = 2; |
|
39 |
private static final int CENTER_3 = 3; |
|
40 |
|
|
41 |
private int mID; |
|
42 |
private final int[] mMoves; |
|
43 |
|
|
44 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
45 |
|
|
46 |
public ScrambleStateBandagedEvil(int id) |
|
47 |
{ |
|
48 |
mID = id; |
|
49 |
mMoves = createMoves(mID); |
|
50 |
} |
|
51 |
|
|
52 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
53 |
|
|
54 |
public static void computeGraph() |
|
55 |
{ |
|
56 |
ArrayList<ScrambleStateBandagedEvil> graph; |
|
57 |
|
|
58 |
int id = 0; |
|
59 |
int id1 = setCenter(id , CENTER_2, 0); |
|
60 |
int id2 = setCenter(id1 , CENTER_2, 1); |
|
61 |
int id3 = setCenter(id2 , CENTER_3, 2); |
|
62 |
int id4 = setCenter(id3 , CENTER_2, 3); |
|
63 |
|
|
64 |
int id5 = setCorner(id4 , CORNER_X, 0); |
|
65 |
int id6 = setCorner(id5 , CORNER_Y, 1); |
|
66 |
int id7 = setCorner(id6 , CORNER_X, 2); |
|
67 |
int id8 = setCorner(id7 , CORNER_Z, 3); |
|
68 |
int id9 = setCorner(id8 , CORNER_Y, 4); |
|
69 |
int id10= setCorner(id9 , CORNER_Y, 5); |
|
70 |
int id11= setCorner(id10, CORNER_S, 6); |
|
71 |
int id12= setCorner(id11, CORNER_Z, 7); |
|
72 |
|
|
73 |
ScrambleStateBandagedEvil bsg = new ScrambleStateBandagedEvil(id12); |
|
74 |
graph = new ArrayList<>(); |
|
75 |
graph.add(bsg); |
|
76 |
|
|
77 |
insertChildren(graph,id12); |
|
78 |
pruneGraph(graph); |
|
79 |
remapGraph(graph); |
|
80 |
|
|
81 |
int num = graph.size(); |
|
82 |
android.util.Log.e("D", "\n"+num+" states\n"); |
|
83 |
|
|
84 |
for(int i=0; i<num; i++) |
|
85 |
{ |
|
86 |
bsg = graph.get(i); |
|
87 |
android.util.Log.e("D", formatMoves(bsg)); |
|
88 |
} |
|
89 |
} |
|
90 |
|
|
91 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
92 |
|
|
93 |
private static void insertChildren(ArrayList<ScrambleStateBandagedEvil> list, int id) |
|
94 |
{ |
|
95 |
ScrambleStateBandagedEvil bsg = findState(list,id); |
|
96 |
|
|
97 |
if( bsg==null ) |
|
98 |
{ |
|
99 |
android.util.Log.e("D", "error: "+id+" doesn't exist"); |
|
100 |
return; |
|
101 |
} |
|
102 |
|
|
103 |
for(int i=0; i<12; i++) |
|
104 |
{ |
|
105 |
int move = bsg.getMove(i); |
|
106 |
|
|
107 |
if( move!=INVALID_MOVE ) |
|
108 |
{ |
|
109 |
ScrambleStateBandagedEvil tmp = findState(list,move); |
|
110 |
|
|
111 |
if( tmp==null ) |
|
112 |
{ |
|
113 |
tmp = new ScrambleStateBandagedEvil(move); |
|
114 |
list.add(tmp); |
|
115 |
insertChildren(list,move); |
|
116 |
} |
|
117 |
} |
|
118 |
} |
|
119 |
} |
|
120 |
|
|
121 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
122 |
|
|
123 |
private static void pruneGraph(ArrayList<ScrambleStateBandagedEvil> list) |
|
124 |
{ |
|
125 |
int num = list.size(), numAxis; |
|
126 |
boolean pruned = false; |
|
127 |
ScrambleStateBandagedEvil bsg; |
|
128 |
|
|
129 |
for(int i=0; i<num; i++) |
|
130 |
{ |
|
131 |
bsg = list.get(i); |
|
132 |
numAxis = bsg.numAxis(); |
|
133 |
|
|
134 |
if( numAxis<2 ) |
|
135 |
{ |
|
136 |
list.remove(i); |
|
137 |
int id = bsg.getID(); |
|
138 |
pruned = true; |
|
139 |
remapID(list,id,INVALID_MOVE); |
|
140 |
break; |
|
141 |
} |
|
142 |
} |
|
143 |
|
|
144 |
if( pruned ) pruneGraph(list); |
|
145 |
} |
|
146 |
|
|
147 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
148 |
|
|
149 |
private static void remapGraph(ArrayList<ScrambleStateBandagedEvil> list) |
|
150 |
{ |
|
151 |
int id, num = list.size(); |
|
152 |
ScrambleStateBandagedEvil bsg; |
|
153 |
|
|
154 |
for(int i=0; i<num; i++ ) |
|
155 |
{ |
|
156 |
bsg = list.get(i); |
|
157 |
id = bsg.getID(); |
|
158 |
bsg.setID(i); |
|
159 |
remapID(list,id,i); |
|
160 |
} |
|
161 |
} |
|
162 |
|
|
163 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
164 |
|
|
165 |
private static void remapID(ArrayList<ScrambleStateBandagedEvil> list, int id, int newId) |
|
166 |
{ |
|
167 |
ScrambleStateBandagedEvil bsg; |
|
168 |
int size = list.size(); |
|
169 |
|
|
170 |
for(int i=0; i<size; i++) |
|
171 |
{ |
|
172 |
bsg = list.get(i); |
|
173 |
|
|
174 |
for(int j=0; j<12; j++) |
|
175 |
{ |
|
176 |
if( bsg.getMove(j)==id ) bsg.setMove(j,newId); |
|
177 |
} |
|
178 |
} |
|
179 |
} |
|
180 |
|
|
181 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
182 |
|
|
183 |
private static ScrambleStateBandagedEvil findState(ArrayList<ScrambleStateBandagedEvil> list, int id) |
|
184 |
{ |
|
185 |
ScrambleStateBandagedEvil bsg; |
|
186 |
int num = list.size(); |
|
187 |
|
|
188 |
for(int i=0; i<num; i++) |
|
189 |
{ |
|
190 |
bsg= list.get(i); |
|
191 |
if( bsg.getID() == id ) return bsg; |
|
192 |
} |
|
193 |
|
|
194 |
return null; |
|
195 |
} |
|
196 |
|
|
197 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
198 |
|
|
199 |
private static String formatMoves(ScrambleStateBandagedEvil bsg) |
|
200 |
{ |
|
201 |
String x = getTable(bsg,0); |
|
202 |
String y = getTable(bsg,3); |
|
203 |
String z = getTable(bsg,6); |
|
204 |
|
|
205 |
return " new ScrambleStateGraph( new int[][] { "+x+", "+y+", "+z+" } ),"; |
|
206 |
} |
|
207 |
|
|
208 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
209 |
|
|
210 |
private static String getTable(ScrambleStateBandagedEvil sc, int index) |
|
211 |
{ |
|
212 |
String ret = ""; |
|
213 |
|
|
214 |
if( index==0 || index==3 ) |
|
215 |
{ |
|
216 |
int m0 = sc.getMove(index ); |
|
217 |
int m1 = sc.getMove(index+1); |
|
218 |
int m2 = sc.getMove(index+2); |
|
219 |
|
|
220 |
if( m0==INVALID_MOVE && m1==INVALID_MOVE && m2==INVALID_MOVE ) return formatL("{}"); |
|
221 |
|
|
222 |
if( m0!=INVALID_MOVE ) ret += formatRet(ret,2, 1,m0); |
|
223 |
if( m1!=INVALID_MOVE ) ret += formatRet(ret,2, 2,m1); |
|
224 |
if( m2!=INVALID_MOVE ) ret += formatRet(ret,2,-1,m2); |
|
225 |
} |
|
226 |
else |
|
227 |
{ |
|
228 |
int m0 = sc.getMove(index ); |
|
229 |
int m1 = sc.getMove(index+1); |
|
230 |
int m2 = sc.getMove(index+2); |
|
231 |
int m3 = sc.getMove(index+3); |
|
232 |
int m4 = sc.getMove(index+4); |
|
233 |
int m5 = sc.getMove(index+5); |
|
234 |
|
|
235 |
if( m0==INVALID_MOVE && m1==INVALID_MOVE && m2==INVALID_MOVE && |
|
236 |
m3==INVALID_MOVE && m4==INVALID_MOVE && m5==INVALID_MOVE ) |
|
237 |
{ |
|
238 |
return formatL("{}"); |
|
239 |
} |
|
240 |
|
|
241 |
if( m0!=INVALID_MOVE ) ret += formatRet(ret,0, 1,m0); |
|
242 |
if( m1!=INVALID_MOVE ) ret += formatRet(ret,0, 2,m1); |
|
243 |
if( m2!=INVALID_MOVE ) ret += formatRet(ret,0,-1,m2); |
|
244 |
if( m3!=INVALID_MOVE ) ret += formatRet(ret,2, 1,m3); |
|
245 |
if( m4!=INVALID_MOVE ) ret += formatRet(ret,2, 2,m4); |
|
246 |
if( m5!=INVALID_MOVE ) ret += formatRet(ret,2,-1,m5); |
|
247 |
} |
|
248 |
|
|
249 |
return formatL("{" + ret + "}"); |
|
250 |
} |
|
251 |
|
|
252 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
253 |
|
|
254 |
private static String formatRet(String str, int row, int angle, int id) |
|
255 |
{ |
|
256 |
String ret = str.length()!=0 ? ",":""; |
|
257 |
|
|
258 |
ret += row; |
|
259 |
ret += angle<0 ? "," : ", "; |
|
260 |
ret += angle; |
|
261 |
|
|
262 |
if( id< 10 ) ret += (", "+id); |
|
263 |
else if( id<100 ) ret += (", " +id); |
|
264 |
else ret += ("," +id); |
|
265 |
|
|
266 |
return ret; |
|
267 |
} |
|
268 |
|
|
269 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
270 |
|
|
271 |
private static final int LENGTH = 28; |
|
272 |
|
|
273 |
private static String formatL(String input) |
|
274 |
{ |
|
275 |
int len = input.length(); |
|
276 |
String ret = input; |
|
277 |
for(int i=0 ;i<LENGTH-len; i++) ret += " "; |
|
278 |
return ret; |
|
279 |
} |
|
280 |
|
|
281 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
282 |
|
|
283 |
private int getID() |
|
284 |
{ |
|
285 |
return mID; |
|
286 |
} |
|
287 |
|
|
288 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
289 |
|
|
290 |
private void setID(int id) |
|
291 |
{ |
|
292 |
mID = id; |
|
293 |
} |
|
294 |
|
|
295 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
296 |
|
|
297 |
private int getMove(int index) |
|
298 |
{ |
|
299 |
return (index>=0 && index<12) ? mMoves[index] : -1; |
|
300 |
} |
|
301 |
|
|
302 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
303 |
|
|
304 |
private int numAxis() |
|
305 |
{ |
|
306 |
int num = 0; |
|
307 |
|
|
308 |
if( mMoves[ 0]!=INVALID_MOVE || mMoves[ 1]!=INVALID_MOVE || mMoves[ 2]!=INVALID_MOVE ) num++; |
|
309 |
if( mMoves[ 3]!=INVALID_MOVE || mMoves[ 4]!=INVALID_MOVE || mMoves[ 5]!=INVALID_MOVE ) num++; |
|
310 |
if( mMoves[ 6]!=INVALID_MOVE || mMoves[ 7]!=INVALID_MOVE || mMoves[ 8]!=INVALID_MOVE ) num++; |
|
311 |
if( mMoves[ 9]!=INVALID_MOVE || mMoves[10]!=INVALID_MOVE || mMoves[11]!=INVALID_MOVE ) num++; |
|
312 |
|
|
313 |
return num; |
|
314 |
} |
|
315 |
|
|
316 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
317 |
|
|
318 |
private void setMove(int index, int newMove) |
|
319 |
{ |
|
320 |
if( index>=0 && index<12 ) mMoves[index] = newMove; |
|
321 |
} |
|
322 |
|
|
323 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
324 |
|
|
325 |
private static String debug(int id) |
|
326 |
{ |
|
327 |
int ce0 = getCenter(id,0); |
|
328 |
int ce1 = getCenter(id,1); |
|
329 |
int ce2 = getCenter(id,2); |
|
330 |
int ce3 = getCenter(id,3); |
|
331 |
|
|
332 |
int co0 = getCorner(id,0); |
|
333 |
int co1 = getCorner(id,1); |
|
334 |
int co2 = getCorner(id,2); |
|
335 |
int co3 = getCorner(id,3); |
|
336 |
int co4 = getCorner(id,4); |
|
337 |
int co5 = getCorner(id,5); |
|
338 |
int co6 = getCorner(id,6); |
|
339 |
int co7 = getCorner(id,7); |
|
340 |
|
|
341 |
String center = centerString(ce0) + centerString(ce1) + centerString(ce2) + centerString(ce3); |
|
342 |
String corner = cornerString(co0) + cornerString(co1) + cornerString(co2) + cornerString(co3) + |
|
343 |
cornerString(co4) + cornerString(co5) + cornerString(co6) + cornerString(co7); |
|
344 |
|
|
345 |
return center + " -" + corner; |
|
346 |
} |
|
347 |
|
|
348 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
349 |
|
|
350 |
private static String centerString(int center) |
|
351 |
{ |
|
352 |
return " "+center; |
|
353 |
} |
|
354 |
|
|
355 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
356 |
|
|
357 |
private static String cornerString(int corner) |
|
358 |
{ |
|
359 |
switch(corner) |
|
360 |
{ |
|
361 |
case CORNER_S: return " S"; |
|
362 |
case CORNER_X: return " X"; |
|
363 |
case CORNER_Y: return " Y"; |
|
364 |
case CORNER_Z: return " Z"; |
|
365 |
} |
|
366 |
|
|
367 |
return "?"; |
|
368 |
} |
|
369 |
|
|
370 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
371 |
|
|
372 |
private static int[] createMoves(int id) |
|
373 |
{ |
|
374 |
int[] ret = new int[12]; |
|
375 |
|
|
376 |
boolean moveX = xPossible(id); |
|
377 |
boolean moveY = yPossible(id); |
|
378 |
boolean moveZ0 = z0Possible(id); |
|
379 |
boolean moveZ2 = z2Possible(id); |
|
380 |
|
|
381 |
if( moveX ) createXmoves(id,ret); |
|
382 |
else { ret[ 0] = INVALID_MOVE; ret[ 1] = INVALID_MOVE; ret[ 2] = INVALID_MOVE; } |
|
383 |
if( moveY ) createYmoves(id,ret); |
|
384 |
else { ret[ 3] = INVALID_MOVE; ret[ 4] = INVALID_MOVE; ret[ 5] = INVALID_MOVE; } |
|
385 |
if( moveZ0) createZ0moves(id,ret); |
|
386 |
else { ret[ 6] = INVALID_MOVE; ret[ 7] = INVALID_MOVE; ret[ 8] = INVALID_MOVE; } |
|
387 |
if( moveZ2) createZ2moves(id,ret); |
|
388 |
else { ret[ 9] = INVALID_MOVE; ret[10] = INVALID_MOVE; ret[11] = INVALID_MOVE; } |
|
389 |
|
|
390 |
return ret; |
|
391 |
} |
|
392 |
|
|
393 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
394 |
|
|
395 |
private static boolean xPossible(int id) |
|
396 |
{ |
|
397 |
if( getCorner(id,4)==CORNER_X ) return false; |
|
398 |
if( getCorner(id,5)==CORNER_X ) return false; |
|
399 |
if( getCorner(id,6)==CORNER_X ) return false; |
|
400 |
if( getCorner(id,7)==CORNER_X ) return false; |
|
401 |
|
|
402 |
if( getCenter(id,1)==CENTER_1 ) return false; |
|
403 |
if( getCenter(id,2)==CENTER_1 ) return false; |
|
404 |
if( getCenter(id,3)==CENTER_1 ) return false; |
|
405 |
|
|
406 |
return true; |
|
407 |
} |
|
408 |
|
|
409 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
410 |
|
|
411 |
private static boolean yPossible(int id) |
|
412 |
{ |
|
413 |
if( getCorner(id,2)==CORNER_Y ) return false; |
|
414 |
if( getCorner(id,3)==CORNER_Y ) return false; |
|
415 |
if( getCorner(id,6)==CORNER_Y ) return false; |
|
416 |
if( getCorner(id,7)==CORNER_Y ) return false; |
|
417 |
|
|
418 |
if( getCenter(id,0)==CENTER_0 ) return false; |
|
419 |
if( getCenter(id,2)==CENTER_0 ) return false; |
|
420 |
if( getCenter(id,3)==CENTER_0 ) return false; |
|
421 |
|
|
422 |
return true; |
|
423 |
} |
|
424 |
|
|
425 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
426 |
|
|
427 |
private static boolean z0Possible(int id) |
|
428 |
{ |
|
429 |
if( getCorner(id,0)==CORNER_Z ) return false; |
|
430 |
if( getCorner(id,2)==CORNER_Z ) return false; |
|
431 |
if( getCorner(id,4)==CORNER_Z ) return false; |
|
432 |
if( getCorner(id,6)==CORNER_Z ) return false; |
|
433 |
|
|
434 |
if( getCenter(id,0)==CENTER_1 ) return false; |
|
435 |
if( getCenter(id,1)==CENTER_0 ) return false; |
|
436 |
|
|
437 |
return true; |
|
438 |
} |
|
439 |
|
|
440 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
441 |
|
|
442 |
private static boolean z2Possible(int id) |
|
443 |
{ |
|
444 |
if( getCorner(id,1)==CORNER_Z ) return false; |
|
445 |
if( getCorner(id,3)==CORNER_Z ) return false; |
|
446 |
if( getCorner(id,5)==CORNER_Z ) return false; |
|
447 |
if( getCorner(id,7)==CORNER_Z ) return false; |
|
448 |
|
|
449 |
if( getCenter(id,0)==CENTER_3 ) return false; |
|
450 |
if( getCenter(id,1)==CENTER_2 ) return false; |
|
451 |
|
|
452 |
return true; |
|
453 |
} |
|
454 |
|
|
455 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
456 |
|
|
457 |
private static int getCorner(int id, int index) |
|
458 |
{ |
|
459 |
return (id>>(14-2*index))&3; |
|
460 |
} |
|
461 |
|
|
462 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
463 |
|
|
464 |
private static int getCenter(int id, int index) |
|
465 |
{ |
|
466 |
return (id>>(22-2*index))&3; |
|
467 |
} |
|
468 |
|
|
469 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
470 |
|
|
471 |
private static int setCorner(int id, int corner, int index) |
|
472 |
{ |
|
473 |
return id + ((corner-getCorner(id,index))<<(14-2*index)); |
|
474 |
} |
|
475 |
|
|
476 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
477 |
|
|
478 |
private static int setCenter(int id, int center, int index) |
|
479 |
{ |
|
480 |
return id + ((center-getCenter(id,index))<<(22-2*index)); |
|
481 |
} |
|
482 |
|
|
483 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
484 |
|
|
485 |
private static void createXmoves(int id, int[] moves) |
|
486 |
{ |
|
487 |
int id1 = rotateX(id); |
|
488 |
moves[0] = id1; |
|
489 |
int id2 = rotateX(id1); |
|
490 |
moves[1] = id2; |
|
491 |
int id3 = rotateX(id2); |
|
492 |
moves[2] = id3; |
|
493 |
} |
|
494 |
|
|
495 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
496 |
|
|
497 |
private static void createYmoves(int id, int[] moves) |
|
498 |
{ |
|
499 |
int id1 = rotateY(id); |
|
500 |
moves[3] = id1; |
|
501 |
int id2 = rotateY(id1); |
|
502 |
moves[4] = id2; |
|
503 |
int id3 = rotateY(id2); |
|
504 |
moves[5] = id3; |
|
505 |
} |
|
506 |
|
|
507 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
508 |
|
|
509 |
private static void createZ0moves(int id, int[] moves) |
|
510 |
{ |
|
511 |
int id1 = rotateZ0(id); |
|
512 |
moves[6] = id1; |
|
513 |
int id2 = rotateZ0(id1); |
|
514 |
moves[7] = id2; |
|
515 |
int id3 = rotateZ0(id2); |
|
516 |
moves[8] = id3; |
|
517 |
} |
|
518 |
|
|
519 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
520 |
|
|
521 |
private static void createZ2moves(int id, int[] moves) |
|
522 |
{ |
|
523 |
int id1 = rotateZ2(id); |
|
524 |
moves[ 9] = id1; |
|
525 |
int id2 = rotateZ2(id1); |
|
526 |
moves[10] = id2; |
|
527 |
int id3 = rotateZ2(id2); |
|
528 |
moves[11] = id3; |
|
529 |
} |
|
530 |
|
|
531 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
532 |
|
|
533 |
private static int rotateX(int id) |
|
534 |
{ |
|
535 |
int newCorner4 = rotCornerX(getCorner(id,5)); |
|
536 |
int newCorner5 = rotCornerX(getCorner(id,7)); |
|
537 |
int newCorner6 = rotCornerX(getCorner(id,4)); |
|
538 |
int newCorner7 = rotCornerX(getCorner(id,6)); |
|
539 |
int newCenter = rotCenter (getCenter(id,0)); |
|
540 |
|
|
541 |
int id1 = setCorner(id ,newCorner4,4); |
|
542 |
int id2 = setCorner(id1,newCorner5,5); |
|
543 |
int id3 = setCorner(id2,newCorner6,6); |
|
544 |
int id4 = setCorner(id3,newCorner7,7); |
|
545 |
int id5 = setCenter(id4,newCenter ,0); |
|
546 |
|
|
547 |
return id5; |
|
548 |
} |
|
549 |
|
|
550 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
551 |
|
|
552 |
private static int rotateY(int id) |
|
553 |
{ |
|
554 |
int newCorner2 = rotCornerY(getCorner(id,6)); |
|
555 |
int newCorner3 = rotCornerY(getCorner(id,2)); |
|
556 |
int newCorner6 = rotCornerY(getCorner(id,7)); |
|
557 |
int newCorner7 = rotCornerY(getCorner(id,3)); |
|
558 |
int newCenter = rotCenter (getCenter(id,1)); |
|
559 |
|
|
560 |
int id1 = setCorner(id ,newCorner2,2); |
|
561 |
int id2 = setCorner(id1,newCorner3,3); |
|
562 |
int id3 = setCorner(id2,newCorner6,6); |
|
563 |
int id4 = setCorner(id3,newCorner7,7); |
|
564 |
int id5 = setCenter(id4,newCenter ,1); |
|
565 |
|
|
566 |
return id5; |
|
567 |
} |
|
568 |
|
|
569 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
570 |
|
|
571 |
private static int rotateZ0(int id) |
|
572 |
{ |
|
573 |
int newCorner0 = rotCornerZ(getCorner(id,2)); |
|
574 |
int newCorner2 = rotCornerZ(getCorner(id,6)); |
|
575 |
int newCorner4 = rotCornerZ(getCorner(id,0)); |
|
576 |
int newCorner6 = rotCornerZ(getCorner(id,4)); |
|
577 |
int newCenter = rotCenter (getCenter(id,2)); |
|
578 |
|
|
579 |
int id1 = setCorner(id ,newCorner0,0); |
|
580 |
int id2 = setCorner(id1,newCorner2,2); |
|
581 |
int id3 = setCorner(id2,newCorner4,4); |
|
582 |
int id4 = setCorner(id3,newCorner6,6); |
|
583 |
int id5 = setCenter(id4,newCenter ,2); |
|
584 |
|
|
585 |
return id5; |
|
586 |
} |
|
587 |
|
|
588 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
589 |
|
|
590 |
private static int rotateZ2(int id) |
|
591 |
{ |
|
592 |
int newCorner1 = rotCornerZ(getCorner(id,3)); |
|
593 |
int newCorner3 = rotCornerZ(getCorner(id,7)); |
|
594 |
int newCorner5 = rotCornerZ(getCorner(id,1)); |
|
595 |
int newCorner7 = rotCornerZ(getCorner(id,5)); |
|
596 |
int newCenter = rotCenter (getCenter(id,3)); |
|
597 |
|
|
598 |
int id1 = setCorner(id ,newCorner1,1); |
|
599 |
int id2 = setCorner(id1,newCorner3,3); |
|
600 |
int id3 = setCorner(id2,newCorner5,5); |
|
601 |
int id4 = setCorner(id3,newCorner7,7); |
|
602 |
int id5 = setCenter(id4,newCenter ,3); |
|
603 |
|
|
604 |
return id5; |
|
605 |
} |
|
606 |
|
|
607 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
608 |
|
|
609 |
private static int rotCornerX(int corner) |
|
610 |
{ |
|
611 |
switch(corner) |
|
612 |
{ |
|
613 |
case CORNER_S: return CORNER_S; |
|
614 |
case CORNER_X: android.util.Log.e("DIST", "rotateX: ERROR"); |
|
615 |
return CORNER_S; |
|
616 |
case CORNER_Y: return CORNER_Z; |
|
617 |
case CORNER_Z: return CORNER_Y; |
|
618 |
} |
|
619 |
|
|
620 |
return CORNER_S; |
|
621 |
} |
|
622 |
|
|
623 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
624 |
|
|
625 |
private static int rotCornerY(int corner) |
|
626 |
{ |
|
627 |
switch(corner) |
|
628 |
{ |
|
629 |
case CORNER_S: return CORNER_S; |
|
630 |
case CORNER_X: return CORNER_Z; |
|
631 |
case CORNER_Y: android.util.Log.e("DIST", "rotateY: ERROR"); |
|
632 |
return CORNER_S; |
|
633 |
case CORNER_Z: return CORNER_X; |
|
634 |
} |
|
635 |
|
|
636 |
return CORNER_S; |
|
637 |
} |
|
638 |
|
|
639 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
640 |
|
|
641 |
private static int rotCornerZ(int corner) |
|
642 |
{ |
|
643 |
switch(corner) |
|
644 |
{ |
|
645 |
case CORNER_S: return CORNER_S; |
|
646 |
case CORNER_X: return CORNER_Y; |
|
647 |
case CORNER_Y: return CORNER_X; |
|
648 |
case CORNER_Z: android.util.Log.e("DIST", "rotateZ: ERROR"); |
|
649 |
return CORNER_S; |
|
650 |
} |
|
651 |
|
|
652 |
return CORNER_S; |
|
653 |
} |
|
654 |
|
|
655 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
656 |
|
|
657 |
private static int rotCenter(int center) |
|
658 |
{ |
|
659 |
switch(center) |
|
660 |
{ |
|
661 |
case CENTER_0: return CENTER_3; |
|
662 |
case CENTER_1: return CENTER_0; |
|
663 |
case CENTER_2: return CENTER_1; |
|
664 |
case CENTER_3: return CENTER_2; |
|
665 |
} |
|
666 |
|
|
667 |
return CENTER_0; |
|
668 |
} |
|
669 |
} |
Also available in: Unified diff
Generalized ScrambleState generator: finished. Remove the specialized 'Evil' generator.