| 12 |
12 |
import java.util.ArrayList;
|
| 13 |
13 |
import java.util.Random;
|
| 14 |
14 |
|
|
15 |
import org.distorted.objectlib.helpers.ObjectMove;
|
| 15 |
16 |
import org.distorted.objectlib.signature.ObjectSignature;
|
| 16 |
17 |
import org.distorted.objectlib.solvers.tablebases.TablebasesAbstract;
|
| 17 |
18 |
|
| ... | ... | |
| 29 |
30 |
private final int mType;
|
| 30 |
31 |
private final int mNumAxis;
|
| 31 |
32 |
private final int[] mNumL; // this is not exactly the same as mNumLayers - counterexample: shape-shifting cuboids.
|
| 32 |
|
private final int[][] mAlgorithms;
|
|
33 |
private final ObjectMove[][] mAlgorithms;
|
| 33 |
34 |
|
| 34 |
35 |
// type=0, i.e. main
|
| 35 |
36 |
private int mCurrState;
|
| ... | ... | |
| 66 |
67 |
|
| 67 |
68 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
| 68 |
69 |
|
| 69 |
|
public ObjectScrambler(int type, int numAxis, int[] numL, int[][] algorithms, int[][] edges, TablebasesAbstract tablebase)
|
|
70 |
public ObjectScrambler(int type, int numAxis, int[] numL, ObjectMove[][] algorithms, int[][] edges, TablebasesAbstract tablebase)
|
| 70 |
71 |
{
|
| 71 |
72 |
mType = type;
|
| 72 |
73 |
mNumAxis = numAxis;
|
| ... | ... | |
| 128 |
129 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
| 129 |
130 |
// PUBLIC API
|
| 130 |
131 |
|
| 131 |
|
private void randomizeNewScramble0(int[][] scramble, Random rnd, int curr)
|
|
132 |
private void randomizeNewScramble0(ObjectMove[] scramble, Random rnd, int curr)
|
| 132 |
133 |
{
|
| 133 |
134 |
if( curr==0 )
|
| 134 |
135 |
{
|
| ... | ... | |
| 138 |
139 |
initializeScrambling();
|
| 139 |
140 |
}
|
| 140 |
141 |
|
| 141 |
|
if( mCurrStep+6 <= mAlgorithms[mCurrAlgorithm].length )
|
|
142 |
if( mCurrStep+1 < mAlgorithms[mCurrAlgorithm].length )
|
| 142 |
143 |
{
|
| 143 |
|
mCurrStep += 3;
|
|
144 |
mCurrStep++;
|
| 144 |
145 |
}
|
| 145 |
146 |
else
|
| 146 |
147 |
{
|
| ... | ... | |
| 150 |
151 |
mCurrStep = 0;
|
| 151 |
152 |
}
|
| 152 |
153 |
|
| 153 |
|
int[] algorithm = mAlgorithms[mCurrAlgorithm];
|
| 154 |
|
scramble[curr][0] = algorithm[mCurrStep ];
|
| 155 |
|
scramble[curr][1] = algorithm[mCurrStep+1];
|
| 156 |
|
scramble[curr][2] = algorithm[mCurrStep+2];
|
| 157 |
|
|
| 158 |
|
mAxisExcluded = algorithm[0];
|
|
154 |
ObjectMove algorithm = mAlgorithms[mCurrAlgorithm][mCurrStep];
|
|
155 |
scramble[curr].set(algorithm);
|
|
156 |
mAxisExcluded = algorithm.getAxis();
|
| 159 |
157 |
}
|
| 160 |
158 |
|
| 161 |
159 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
| ... | ... | |
| 356 |
354 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
| 357 |
355 |
// TYPE 1
|
| 358 |
356 |
|
| 359 |
|
private void updateCornerQuats(int[] rotInfo)
|
|
357 |
private void updateCornerQuats(int axis, int row, int angle)
|
| 360 |
358 |
{
|
| 361 |
359 |
if( mQuatMult==null ) initializeQuatMult();
|
| 362 |
360 |
|
| 363 |
|
int axis = rotInfo[0];
|
| 364 |
|
int layer= rotInfo[1];
|
| 365 |
|
int index=-rotInfo[2];
|
| 366 |
|
|
| 367 |
|
int quat = makeQuat(axis,index);
|
|
361 |
int quat = makeQuat(axis,-angle);
|
| 368 |
362 |
|
| 369 |
363 |
for(int corner=0; corner<8; corner++)
|
| 370 |
364 |
{
|
| 371 |
|
if( cornerBelongs(corner,axis,layer) )
|
|
365 |
if( cornerBelongs(corner,axis,row) )
|
| 372 |
366 |
{
|
| 373 |
367 |
int curr = mCornerQuat[corner];
|
| 374 |
368 |
mCornerQuat[corner] = mQuatMult[quat][curr];
|
| ... | ... | |
| 379 |
373 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
| 380 |
374 |
// TYPE 1
|
| 381 |
375 |
|
| 382 |
|
private void randomizeNewScramble1(int[][] scramble, Random rnd, int curr)
|
|
376 |
private void randomizeNewScramble1(ObjectMove[] scramble, Random rnd, int curr)
|
| 383 |
377 |
{
|
| 384 |
378 |
int layer, nextAngle;
|
| 385 |
379 |
|
| ... | ... | |
| 401 |
395 |
nextAngle = getNextAngleNotZero(rnd,layer);
|
| 402 |
396 |
}
|
| 403 |
397 |
|
| 404 |
|
scramble[curr][0] = 0;
|
| 405 |
|
scramble[curr][1] = 2*layer;
|
| 406 |
|
scramble[curr][2] = nextAngle;
|
| 407 |
|
mLastRot = layer==0 ? LAST_LO : LAST_UP;
|
| 408 |
|
updateCornerQuats(scramble[curr]);
|
| 409 |
|
scramble[curr][1] = (1<<scramble[curr][1]);
|
|
398 |
int axis1 = 0;
|
|
399 |
int row1 = 2*layer;
|
|
400 |
int angle1= nextAngle;
|
|
401 |
mLastRot = layer==0 ? LAST_LO : LAST_UP;
|
|
402 |
updateCornerQuats(axis1,row1,angle1);
|
|
403 |
scramble[curr].set(axis1, 1<<row1, angle1);
|
| 410 |
404 |
break;
|
| 411 |
405 |
case LAST_LO:
|
| 412 |
406 |
case LAST_UP: layer = mLastRot==LAST_LO ? 1:0;
|
| ... | ... | |
| 414 |
408 |
|
| 415 |
409 |
if( nextAngle!=0 )
|
| 416 |
410 |
{
|
| 417 |
|
scramble[curr][0] = 0;
|
| 418 |
|
scramble[curr][1] = 2*layer;
|
| 419 |
|
scramble[curr][2] = nextAngle;
|
| 420 |
|
updateCornerQuats(scramble[curr]);
|
| 421 |
|
scramble[curr][1] = (1<<scramble[curr][1]);
|
|
411 |
int axis2 = 0;
|
|
412 |
int row2 = 2*layer;
|
|
413 |
int angle2= nextAngle;
|
|
414 |
updateCornerQuats(axis2,row2,angle2);
|
|
415 |
scramble[curr].set(axis2, 1<<row2, angle2);
|
| 422 |
416 |
mLastRot = LAST_UL;
|
| 423 |
417 |
}
|
| 424 |
418 |
else
|
| 425 |
419 |
{
|
| 426 |
|
scramble[curr][0] = 1;
|
| 427 |
|
scramble[curr][1] = rnd.nextInt(2);
|
| 428 |
|
scramble[curr][2] = 1;
|
| 429 |
|
mLastRot = LAST_SL;
|
| 430 |
|
updateCornerQuats(scramble[curr]);
|
| 431 |
|
scramble[curr][1] = (1<<scramble[curr][1]);
|
|
420 |
int axis3 = 1;
|
|
421 |
int row3 = rnd.nextInt(2);
|
|
422 |
int angle3= 1;
|
|
423 |
mLastRot = LAST_SL;
|
|
424 |
updateCornerQuats(axis3,row3,angle3);
|
|
425 |
scramble[curr].set(axis3, 1<<row3, angle3);
|
| 432 |
426 |
computePermittedAngles();
|
| 433 |
427 |
}
|
| 434 |
428 |
|
| 435 |
429 |
break;
|
| 436 |
|
case LAST_UL: scramble[curr][0] = 1;
|
| 437 |
|
scramble[curr][1] = rnd.nextInt(2);
|
| 438 |
|
scramble[curr][2] = 1;
|
| 439 |
|
mLastRot = LAST_SL;
|
| 440 |
|
updateCornerQuats(scramble[curr]);
|
|
430 |
case LAST_UL: int axis4 = 1;
|
|
431 |
int row4 = rnd.nextInt(2);
|
|
432 |
int angle4= 1;
|
|
433 |
mLastRot = LAST_SL;
|
|
434 |
updateCornerQuats(axis4,row4,angle4);
|
| 441 |
435 |
computePermittedAngles();
|
| 442 |
|
scramble[curr][1] = (1<<scramble[curr][1]);
|
|
436 |
scramble[curr].set(axis4, 1<<row4, angle4);
|
| 443 |
437 |
break;
|
| 444 |
438 |
}
|
| 445 |
439 |
}
|
| ... | ... | |
| 447 |
441 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
| 448 |
442 |
// TYPE 2
|
| 449 |
443 |
|
| 450 |
|
private void buildMoveForced(int[][] scramble, Random rnd, int curr)
|
|
444 |
private void buildMoveForced(ObjectMove[] scramble, Random rnd, int curr)
|
| 451 |
445 |
{
|
| 452 |
446 |
ScrambleStateLocallyBandaged currState = mStatesHistory.get(curr);
|
| 453 |
|
int indexExcluded = curr>0 ? scramble[curr-1][0] : ScrambleStateLocallyBandaged.AXIS_NONE;
|
| 454 |
|
int numMoves = currState.numMoves(indexExcluded);
|
|
447 |
int axisExcluded = curr>0 ? scramble[curr-1].getAxis() : ScrambleStateLocallyBandaged.AXIS_NONE;
|
|
448 |
int numMoves = currState.numMoves(axisExcluded);
|
| 455 |
449 |
ObjectSignature signature;
|
| 456 |
450 |
|
| 457 |
451 |
if( numMoves==0 )
|
| 458 |
452 |
{
|
| 459 |
|
indexExcluded = ScrambleStateLocallyBandaged.AXIS_NONE;
|
| 460 |
|
numMoves = currState.numMoves(indexExcluded);
|
|
453 |
axisExcluded = ScrambleStateLocallyBandaged.AXIS_NONE;
|
|
454 |
numMoves = currState.numMoves(axisExcluded);
|
| 461 |
455 |
}
|
| 462 |
456 |
|
| 463 |
457 |
if( numMoves==0 )
|
| 464 |
458 |
{
|
| 465 |
|
scramble[curr][0] = 0;
|
| 466 |
|
scramble[curr][1] = 0;
|
| 467 |
|
scramble[curr][2] = 0;
|
|
459 |
scramble[curr].set(0,0,0);
|
| 468 |
460 |
signature = currState.getSignature();
|
| 469 |
461 |
}
|
| 470 |
462 |
else
|
| 471 |
463 |
{
|
| 472 |
464 |
int randMove = rnd.nextInt(numMoves);
|
| 473 |
|
int moveIndex = currState.getNthMove(randMove,indexExcluded);
|
|
465 |
int moveIndex = currState.getNthMove(randMove,axisExcluded);
|
| 474 |
466 |
signature = currState.getMove(moveIndex);
|
| 475 |
467 |
currState.fillOutScramble(scramble[curr],moveIndex);
|
| 476 |
468 |
}
|
| ... | ... | |
| 483 |
475 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
| 484 |
476 |
// TYPE 2
|
| 485 |
477 |
|
| 486 |
|
private boolean buildMove2Cons(int[][] scramble, Random rnd, int curr)
|
|
478 |
private boolean buildMove2Cons(ObjectMove[] scramble, Random rnd, int curr)
|
| 487 |
479 |
{
|
| 488 |
480 |
ScrambleStateLocallyBandaged currState = mStatesHistory.get(curr);
|
| 489 |
|
boolean lock= (curr>=2 && scramble[curr-2][0]==scramble[curr-1][0] );
|
| 490 |
|
int axisExcluded = lock ? scramble[curr-1][0] : ScrambleStateLocallyBandaged.AXIS_NONE;
|
| 491 |
|
int layerExcluded= !lock && curr>=1 ? scramble[curr-1][1] : -1;
|
|
481 |
boolean lock= (curr>=2 && scramble[curr-2].getAxis()==scramble[curr-1].getAxis() );
|
|
482 |
int axisExcluded = lock ? scramble[curr-1].getAxis() : ScrambleStateLocallyBandaged.AXIS_NONE;
|
|
483 |
int AlayerExcluded= !lock && curr>=1 ? scramble[curr-1][1] : -1;
|
| 492 |
484 |
int numMoves = currState.numMoves(axisExcluded,layerExcluded);
|
| 493 |
485 |
|
| 494 |
486 |
while( numMoves==0 )
|
ObjectMove