Revision d3c2aa29
Added by Leszek Koltunski almost 2 years ago
src/main/java/org/distorted/solvers/SolverPyraminx.java | ||
---|---|---|
47 | 47 |
private static final int ERROR_C_V_DONT_MATCH = -19; |
48 | 48 |
private static final int ERROR_TWO_EDGES = -20; |
49 | 49 |
|
50 |
private static final int[][] edgeColors = new int[][] |
|
51 |
{ |
|
52 |
{3,2},{1,3},{0,3},{2,1},{2,0},{1,0} // order of those pairs determines edge twist |
|
53 |
}; |
|
54 |
|
|
50 | 55 |
TablebasesAbstract mSolver; |
51 | 56 |
|
52 | 57 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
63 | 68 |
|
64 | 69 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
65 | 70 |
|
66 |
private boolean pieceEqual2(int[] piece, int c1, int c2)
|
|
71 |
private boolean pieceEqual2(int[] piece, int[] colors)
|
|
67 | 72 |
{ |
68 |
return ( (piece[0]==c1 && piece[1]==c2) ||
|
|
69 |
(piece[0]==c2 && piece[1]==c1) );
|
|
73 |
return ( (piece[0]==colors[0] && piece[1]==colors[1]) ||
|
|
74 |
(piece[0]==colors[1] && piece[1]==colors[0]) );
|
|
70 | 75 |
} |
71 | 76 |
|
72 | 77 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
123 | 128 |
|
124 | 129 |
private int checkAllEdgesPresent(int[][] edges) |
125 | 130 |
{ |
126 |
boolean rb = false; |
|
127 |
boolean ry = false; |
|
128 |
boolean rg = false; |
|
129 |
boolean yb = false; |
|
130 |
boolean gb = false; |
|
131 |
boolean gy = false; |
|
131 |
boolean[] present = new boolean[6]; |
|
132 |
for(int i=0; i<6; i++) present[i] = false; |
|
132 | 133 |
|
133 | 134 |
for(int i=0; i<6; i++) |
134 |
{ |
|
135 |
if( pieceEqual2(edges[i],3,2) ) rb = true; |
|
136 |
if( pieceEqual2(edges[i],3,1) ) ry = true; |
|
137 |
if( pieceEqual2(edges[i],3,0) ) rg = true; |
|
138 |
if( pieceEqual2(edges[i],2,1) ) yb = true; |
|
139 |
if( pieceEqual2(edges[i],2,0) ) gb = true; |
|
140 |
if( pieceEqual2(edges[i],1,0) ) gy = true; |
|
141 |
} |
|
142 |
|
|
143 |
if( !rb ) return ERROR_EDGE_RB_MISSING; |
|
144 |
if( !ry ) return ERROR_EDGE_RY_MISSING; |
|
145 |
if( !rg ) return ERROR_EDGE_RG_MISSING; |
|
146 |
if( !yb ) return ERROR_EDGE_YB_MISSING; |
|
147 |
if( !gb ) return ERROR_EDGE_GB_MISSING; |
|
148 |
if( !gy ) return ERROR_EDGE_GY_MISSING; |
|
135 |
for(int j=0; j<6; j++) |
|
136 |
if (pieceEqual2(edges[i], edgeColors[j])) |
|
137 |
{ |
|
138 |
present[j] = true; |
|
139 |
break; |
|
140 |
} |
|
141 |
|
|
142 |
if( !present[0] ) return ERROR_EDGE_RB_MISSING; |
|
143 |
if( !present[1] ) return ERROR_EDGE_RY_MISSING; |
|
144 |
if( !present[2] ) return ERROR_EDGE_RG_MISSING; |
|
145 |
if( !present[3] ) return ERROR_EDGE_YB_MISSING; |
|
146 |
if( !present[4] ) return ERROR_EDGE_GB_MISSING; |
|
147 |
if( !present[5] ) return ERROR_EDGE_GY_MISSING; |
|
149 | 148 |
|
150 | 149 |
return 0; |
151 | 150 |
} |
... | ... | |
211 | 210 |
break; |
212 | 211 |
} |
213 | 212 |
|
214 |
return ( twist1!=twist2 || twist1!=twist3 ) ? -1 : twist1; |
|
213 |
return ( twist1!=twist2 || twist1!=twist3 ) ? ERROR_CORNERS_CANNOT : twist1; |
|
214 |
} |
|
215 |
|
|
216 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
217 |
|
|
218 |
private int locateEdge(int[][] edges, int[] colors) |
|
219 |
{ |
|
220 |
for(int i=0; i<6; i++) |
|
221 |
if( edges[i][0]==colors[0] && edges[i][1]==colors[1] || |
|
222 |
edges[i][0]==colors[1] && edges[i][1]==colors[0] ) return i; |
|
223 |
|
|
224 |
return -1; |
|
225 |
} |
|
226 |
|
|
227 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
228 |
|
|
229 |
private int edgeTwist(int[] edge, int[] colors) |
|
230 |
{ |
|
231 |
return edge[0]==colors[0] ? 0:1; |
|
215 | 232 |
} |
216 | 233 |
|
217 | 234 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
218 | 235 |
|
219 | 236 |
private int[] computeEdgeQuats(int[][] edges) |
220 | 237 |
{ |
221 |
return null; |
|
238 |
int[] quats = new int[6]; |
|
239 |
|
|
240 |
for(int i=0; i<6; i++) |
|
241 |
{ |
|
242 |
int pos = locateEdge(edges,edgeColors[i]); |
|
243 |
int twist = edgeTwist(edges[pos],edgeColors[i]); |
|
244 |
|
|
245 |
//android.util.Log.e("D", "edge "+i+" pos: "+pos+" twist: "+twist); |
|
246 |
|
|
247 |
quats[i] = TablebasesPyraminx.EDGE_QUATS[pos][twist]; |
|
248 |
} |
|
249 |
/* |
|
250 |
for(int i=0; i<6; i++) |
|
251 |
android.util.Log.e("D", "edge "+i+" : "+quats[i]); |
|
252 |
*/ |
|
253 |
return quats; |
|
222 | 254 |
} |
223 | 255 |
|
224 | 256 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
232 | 264 |
|
233 | 265 |
private void getCorners(TwistyObject object, int[][] corners) |
234 | 266 |
{ |
235 |
corners[0][0] = object.getCubitFaceStickerIndex(6,3); // R
|
|
236 |
corners[0][1] = object.getCubitFaceStickerIndex(6,2); // B
|
|
237 |
corners[0][2] = object.getCubitFaceStickerIndex(6,1); // Y
|
|
267 |
corners[0][0] = object.getCubitFaceStickerIndex(4,0); // G
|
|
268 |
corners[0][1] = object.getCubitFaceStickerIndex(4,3); // R
|
|
269 |
corners[0][2] = object.getCubitFaceStickerIndex(4,2); // B
|
|
238 | 270 |
|
239 |
corners[1][0] = object.getCubitFaceStickerIndex(4,3); // R
|
|
240 |
corners[1][1] = object.getCubitFaceStickerIndex(4,0); // G
|
|
241 |
corners[1][2] = object.getCubitFaceStickerIndex(4,2); // B
|
|
271 |
corners[1][0] = object.getCubitFaceStickerIndex(6,1); // Y
|
|
272 |
corners[1][1] = object.getCubitFaceStickerIndex(6,2); // B
|
|
273 |
corners[1][2] = object.getCubitFaceStickerIndex(6,3); // R
|
|
242 | 274 |
|
243 |
corners[2][0] = object.getCubitFaceStickerIndex(13,3); // R
|
|
244 |
corners[2][1] = object.getCubitFaceStickerIndex(13,1); // Y
|
|
245 |
corners[2][2] = object.getCubitFaceStickerIndex(13,0); // G
|
|
275 |
corners[2][0] = object.getCubitFaceStickerIndex(11,1); // Y
|
|
276 |
corners[2][1] = object.getCubitFaceStickerIndex(11,0); // G
|
|
277 |
corners[2][2] = object.getCubitFaceStickerIndex(11,2); // B
|
|
246 | 278 |
|
247 |
corners[3][0] = object.getCubitFaceStickerIndex(11,0); // G
|
|
248 |
corners[3][1] = object.getCubitFaceStickerIndex(11,1); // Y
|
|
249 |
corners[3][2] = object.getCubitFaceStickerIndex(11,2); // B
|
|
279 |
corners[3][0] = object.getCubitFaceStickerIndex(13,1); // Y
|
|
280 |
corners[3][1] = object.getCubitFaceStickerIndex(13,3); // R
|
|
281 |
corners[3][2] = object.getCubitFaceStickerIndex(13,0); // G
|
|
250 | 282 |
} |
251 | 283 |
|
252 | 284 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
253 | 285 |
|
254 | 286 |
private void getVertices(TwistyObject object, int[][] vertex) |
255 | 287 |
{ |
256 |
vertex[0][0] = object.getCubitFaceStickerIndex(1,5); // R
|
|
257 |
vertex[0][1] = object.getCubitFaceStickerIndex(1,7); // B
|
|
258 |
vertex[0][2] = object.getCubitFaceStickerIndex(1,2); // Y
|
|
288 |
vertex[0][0] = object.getCubitFaceStickerIndex(0,0); // G
|
|
289 |
vertex[0][1] = object.getCubitFaceStickerIndex(0,5); // R
|
|
290 |
vertex[0][2] = object.getCubitFaceStickerIndex(0,7); // B
|
|
259 | 291 |
|
260 |
vertex[1][0] = object.getCubitFaceStickerIndex(0,5); // R
|
|
261 |
vertex[1][1] = object.getCubitFaceStickerIndex(0,0); // G
|
|
262 |
vertex[1][2] = object.getCubitFaceStickerIndex(0,7); // B
|
|
292 |
vertex[1][0] = object.getCubitFaceStickerIndex(1,2); // Y
|
|
293 |
vertex[1][1] = object.getCubitFaceStickerIndex(1,7); // B
|
|
294 |
vertex[1][2] = object.getCubitFaceStickerIndex(1,5); // R
|
|
263 | 295 |
|
264 |
vertex[2][0] = object.getCubitFaceStickerIndex(3,5); // R
|
|
265 |
vertex[2][1] = object.getCubitFaceStickerIndex(3,2); // Y
|
|
266 |
vertex[2][2] = object.getCubitFaceStickerIndex(3,0); // G
|
|
296 |
vertex[2][0] = object.getCubitFaceStickerIndex(2,2); // Y
|
|
297 |
vertex[2][1] = object.getCubitFaceStickerIndex(2,0); // G
|
|
298 |
vertex[2][2] = object.getCubitFaceStickerIndex(2,7); // B
|
|
267 | 299 |
|
268 |
vertex[3][0] = object.getCubitFaceStickerIndex(2,0); // G
|
|
269 |
vertex[3][1] = object.getCubitFaceStickerIndex(2,2); // Y
|
|
270 |
vertex[3][2] = object.getCubitFaceStickerIndex(2,7); // B
|
|
300 |
vertex[3][0] = object.getCubitFaceStickerIndex(3,2); // Y
|
|
301 |
vertex[3][1] = object.getCubitFaceStickerIndex(3,5); // R
|
|
302 |
vertex[3][2] = object.getCubitFaceStickerIndex(3,0); // G
|
|
271 | 303 |
} |
272 | 304 |
|
273 | 305 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
277 | 309 |
edges[0][0] = object.getCubitFaceStickerIndex(5,3); // R |
278 | 310 |
edges[0][1] = object.getCubitFaceStickerIndex(5,2); // B |
279 | 311 |
|
280 |
edges[1][0] = object.getCubitFaceStickerIndex(10,3); // R
|
|
281 |
edges[1][1] = object.getCubitFaceStickerIndex(10,1); // Y
|
|
312 |
edges[1][0] = object.getCubitFaceStickerIndex(10,1); // Y
|
|
313 |
edges[1][1] = object.getCubitFaceStickerIndex(10,3); // R
|
|
282 | 314 |
|
283 |
edges[2][0] = object.getCubitFaceStickerIndex(9,3); // R
|
|
284 |
edges[2][1] = object.getCubitFaceStickerIndex(9,0); // G
|
|
315 |
edges[2][0] = object.getCubitFaceStickerIndex(9,0); // G
|
|
316 |
edges[2][1] = object.getCubitFaceStickerIndex(9,3); // R
|
|
285 | 317 |
|
286 |
edges[3][0] = object.getCubitFaceStickerIndex(8,1); // Y
|
|
287 |
edges[3][1] = object.getCubitFaceStickerIndex(8,2); // B
|
|
318 |
edges[3][0] = object.getCubitFaceStickerIndex(8,2); // B
|
|
319 |
edges[3][1] = object.getCubitFaceStickerIndex(8,1); // Y
|
|
288 | 320 |
|
289 |
edges[4][0] = object.getCubitFaceStickerIndex(7,0); // G
|
|
290 |
edges[4][1] = object.getCubitFaceStickerIndex(7,2); // B
|
|
321 |
edges[4][0] = object.getCubitFaceStickerIndex(7,2); // B
|
|
322 |
edges[4][1] = object.getCubitFaceStickerIndex(7,0); // G
|
|
291 | 323 |
|
292 |
edges[5][0] = object.getCubitFaceStickerIndex(12,0); // G
|
|
293 |
edges[5][1] = object.getCubitFaceStickerIndex(12,1); // Y
|
|
324 |
edges[5][0] = object.getCubitFaceStickerIndex(12,1); // Y
|
|
325 |
edges[5][1] = object.getCubitFaceStickerIndex(12,0); // G
|
|
294 | 326 |
} |
295 | 327 |
|
296 | 328 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
321 | 353 |
|
322 | 354 |
int result4 = checkAgreement(faces1,faces2); |
323 | 355 |
if( result4<0 ) return result4; |
324 |
|
|
356 |
/* |
|
357 |
for(int i=0; i<4; i++) |
|
358 |
android.util.Log.e("D", "face "+i+" : "+faces1[i]); |
|
359 |
*/ |
|
325 | 360 |
for(int i=0; i<4; i++) |
326 | 361 |
{ |
327 | 362 |
corner_twist[i] = computePieceTwist(i,corners[i],faces1); |
363 |
|
|
364 |
android.util.Log.e("D", "corner twist "+i+" : "+corner_twist[i]); |
|
365 |
|
|
328 | 366 |
if( corner_twist[i]<0 ) return ERROR_CORNERS_CANNOT; |
329 | 367 |
} |
330 | 368 |
|
... | ... | |
333 | 371 |
vertex_twist[i] = computePieceTwist(i,vertices[i],faces1); |
334 | 372 |
if( vertex_twist[i]<0 ) return ERROR_VERTICES_CANNOT; |
335 | 373 |
} |
374 |
/* |
|
375 |
for(int i=0; i<6; i++) |
|
376 |
android.util.Log.e("D", "edge "+i+" : "+edges[i][0]+" "+edges[i][1]); |
|
377 |
*/ |
|
336 | 378 |
|
337 | 379 |
int[] quats = computeEdgeQuats(edges); |
338 | 380 |
int[] permutation = new int[6]; |
339 |
TablebasesPyraminx.getEdgePermutation(permutation,quats); |
|
381 |
TablebasesPyraminx.getEdgePermutation(permutation,quats,0);
|
|
340 | 382 |
boolean even = TablebaseHelpers.permutationIsEven(permutation); |
341 | 383 |
if( !even ) return ERROR_TWO_EDGES; |
342 |
|
|
343 |
return 0; |
|
384 |
int[] edge_twist = new int[6]; |
|
385 |
TablebasesPyraminx.getEdgeTwist(edge_twist,quats,0); |
|
386 |
/* |
|
387 |
for(int i=0; i<6; i++) |
|
388 |
android.util.Log.e("D", "edge twist "+i+" : "+edge_twist[i]); |
|
389 |
*/ |
|
390 |
int totalEdgeTwist=0; |
|
391 |
for(int i=0; i<6; i++) totalEdgeTwist += edge_twist[i]; |
|
392 |
if( (totalEdgeTwist%2)!=0 ) return ERROR_EDGE_TWISTED; |
|
393 |
|
|
394 |
int vertexTwist = vertex_twist[0]+ 3*(vertex_twist[1]+ 3*(vertex_twist[2]+ 3*vertex_twist[3])); |
|
395 |
int edgeTwist = edge_twist[0]+ 2*(edge_twist[1]+ 2*(edge_twist[2]+ 2*(edge_twist[3]+ 2*edge_twist[4]))); |
|
396 |
int perm_num = TablebaseHelpers.computeEvenPermutationNum(permutation); |
|
397 |
|
|
398 |
android.util.Log.e("D", "vertexTwist: : "+vertexTwist+" edgeTwist: "+edgeTwist+" perm_num: "+perm_num ); |
|
399 |
|
|
400 |
return vertexTwist + 81*(edgeTwist + 32*perm_num); |
|
344 | 401 |
} |
345 | 402 |
|
346 | 403 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
Also available in: Unified diff
Pyraminx solver: progress