Revision d3c2aa29
Added by Leszek Koltunski over 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