Revision c0266cb1
Added by Leszek Koltunski about 1 year ago
src/main/java/org/distorted/objectlib/tablebases/TablebasesAbstract.java | ||
---|---|---|
27 | 27 |
public abstract class TablebasesAbstract |
28 | 28 |
{ |
29 | 29 |
private final Static3D[] mAxis; |
30 |
private final int mSize; |
|
30 |
private final int mSize, mMinScramble;
|
|
31 | 31 |
private final int[][] mAngles; |
32 | 32 |
private final int mNumAxis; |
33 | 33 |
private final int[] mNumLayers; |
... | ... | |
56 | 56 |
|
57 | 57 |
abstract boolean[][] getRotatable(); |
58 | 58 |
|
59 |
abstract int getMinScramble(); |
|
59 | 60 |
abstract int getSize(); |
60 | 61 |
abstract int[] getQuats(int index); |
61 | 62 |
abstract int getIndex(int[] quats); |
... | ... | |
65 | 66 |
public TablebasesAbstract() |
66 | 67 |
{ |
67 | 68 |
mSize = getSize(); |
69 |
mMinScramble = getMinScramble(); |
|
68 | 70 |
mAngles = getBasicAngles(); |
69 | 71 |
mAxis = getRotationAxis(); |
70 | 72 |
mNumAxis = mAxis.length; |
... | ... | |
122 | 124 |
} |
123 | 125 |
} |
124 | 126 |
|
127 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
128 |
|
|
129 |
private int computeRowFromBitmap(int rowBitmap) |
|
130 |
{ |
|
131 |
int index = 0; |
|
132 |
|
|
133 |
while(index<32) |
|
134 |
{ |
|
135 |
if( (rowBitmap&0x1) != 0 ) return index; |
|
136 |
rowBitmap>>=1; |
|
137 |
index++; |
|
138 |
} |
|
139 |
return 0; |
|
140 |
} |
|
141 |
|
|
125 | 142 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
126 | 143 |
|
127 | 144 |
private int computeRow(float[] pos, int quat, int axisIndex) |
... | ... | |
323 | 340 |
moves.add(move); |
324 | 341 |
} |
325 | 342 |
|
326 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
327 |
|
|
328 |
private void addMove(int[] moves, int axis, int layer, int angle) |
|
329 |
{ |
|
330 |
int maxAngle = mAngles[axis][layer]; |
|
331 |
angle = maxAngle-angle; |
|
332 |
if( angle> 0.5f*maxAngle ) angle -= maxAngle; |
|
333 |
|
|
334 |
moves[0] = axis; |
|
335 |
moves[1] = (1<<layer); |
|
336 |
moves[2] = angle; |
|
337 |
} |
|
338 |
|
|
339 | 343 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
340 | 344 |
|
341 | 345 |
private int[][] convertMoves(ArrayList<int[]> moves) |
... | ... | |
446 | 450 |
|
447 | 451 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
448 | 452 |
|
449 |
public int[][] scramble(Random rnd, int depth)
|
|
453 |
public void scramble(Random rnd, int depth, int[][] scramble)
|
|
450 | 454 |
{ |
451 |
if( !mInitialized ) return null;
|
|
455 |
if( !mInitialized ) return; |
|
452 | 456 |
|
453 |
int[] data = new int[4]; |
|
454 |
int level=0; |
|
455 |
int[][] moves = new int[depth][3]; |
|
456 |
int[] quats = getQuats(0); |
|
457 |
int numQuats = quats.length; |
|
458 |
int[] tmpQuats = new int[numQuats]; |
|
457 |
int solDepth = 0; |
|
458 |
int scraLen = scramble.length; |
|
459 |
if( depth>mMinScramble ) depth = mMinScramble; |
|
459 | 460 |
|
460 |
while(level<depth)
|
|
461 |
while( solDepth<depth )
|
|
461 | 462 |
{ |
462 |
boolean found = false; |
|
463 |
|
|
464 |
data[0]=0; |
|
465 |
data[1]=0; |
|
466 |
data[2]=1; |
|
467 |
data[3]=1; |
|
468 |
|
|
469 |
int random = rnd.nextInt(mScalingFactor); |
|
470 |
for(int i=0; i<random; i++) getNextAxisLayerAngleQuat(data); |
|
471 |
|
|
472 |
for(int ax=0; ax<mNumAxis; ax++) |
|
473 |
for(int cubit=0; cubit<mNumCubits; cubit++) |
|
474 |
mRotRow[cubit][ax] = computeRow(mPosition[cubit],quats[cubit],ax); |
|
463 |
int randomPosition = rnd.nextInt(mSize-1); |
|
464 |
int[][] sol = solution(randomPosition); |
|
465 |
solDepth = sol.length; |
|
475 | 466 |
|
476 |
for(int s=0; s<mScalingFactor && !found; s++)
|
|
467 |
if( solDepth>=depth )
|
|
477 | 468 |
{ |
478 |
int ax = data[0]; |
|
479 |
int layer = data[1]; |
|
480 |
int angle = data[2]; |
|
481 |
int quat = data[3]; |
|
469 |
int num = Math.min(scraLen,solDepth); |
|
482 | 470 |
|
483 |
if( mRotatable[ax][layer] )
|
|
471 |
for(int i=0; i<num; i++)
|
|
484 | 472 |
{ |
485 |
int bitLayer = (1<<layer); |
|
486 |
System.arraycopy(quats, 0, tmpQuats, 0, numQuats); |
|
487 |
|
|
488 |
for(int cubit=0; cubit<mNumCubits; cubit++) |
|
489 |
if( mRotRow[cubit][ax]==bitLayer ) |
|
490 |
{ |
|
491 |
int currQuat = tmpQuats[cubit]; |
|
492 |
int newQuat = getMultQuat(quat,currQuat); |
|
493 |
tmpQuats[cubit] = newQuat; |
|
494 |
} |
|
495 |
|
|
496 |
int childIndex = getIndex(tmpQuats); |
|
497 |
byte newLevel = mTablebase.retrievePacked(childIndex); |
|
498 |
|
|
499 |
if( ((newLevel-level-1)%3) == 0 ) |
|
500 |
{ |
|
501 |
addMove(moves[level],ax,layer,angle); |
|
502 |
level++; |
|
503 |
quats = getQuats(childIndex); |
|
504 |
found = true; |
|
505 |
} |
|
473 |
int[] source = sol[solDepth-1-i]; |
|
474 |
scramble[i][0] = source[0]; |
|
475 |
scramble[i][1] = computeRowFromBitmap(source[1]); |
|
476 |
scramble[i][2] =-source[2]; |
|
506 | 477 |
} |
507 |
|
|
508 |
getNextAxisLayerAngleQuat(data); |
|
509 |
} |
|
510 |
|
|
511 |
if( !found ) |
|
512 |
{ |
|
513 |
android.util.Log.e("D", "scramble error: no move found!"); |
|
514 |
return null; |
|
515 | 478 |
} |
516 | 479 |
} |
517 |
|
|
518 |
return moves; |
|
519 | 480 |
} |
520 | 481 |
|
521 | 482 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
Also available in: Unified diff
Tablebase-based scrambling.