Revision bbbfb6af
Added by Leszek Koltunski over 3 years ago
src/main/java/org/distorted/objects/TwistyPyraminx.java | ||
---|---|---|
23 | 23 |
|
24 | 24 |
import org.distorted.helpers.ObjectShape; |
25 | 25 |
import org.distorted.helpers.ObjectSticker; |
26 |
import org.distorted.helpers.ScrambleState; |
|
26 | 27 |
import org.distorted.library.main.DistortedEffects; |
27 | 28 |
import org.distorted.library.main.DistortedTexture; |
28 | 29 |
import org.distorted.library.mesh.MeshSquare; |
... | ... | |
114 | 115 |
{ -0.4330127f, -0.25f, 0.4330127f, -0.25f, 0.0f, 0.5f } |
115 | 116 |
}; |
116 | 117 |
|
117 |
private static float[] mRowChances; |
|
118 |
|
|
119 | 118 |
private static final ObjectSticker[] mStickers; |
120 | 119 |
|
121 | 120 |
static |
... | ... | |
127 | 126 |
mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke); |
128 | 127 |
} |
129 | 128 |
|
129 |
private int mCurrState; |
|
130 |
private int mIndexExcluded; |
|
131 |
private ScrambleState[] mStates; |
|
132 |
private int[][] mScrambleTable; |
|
133 |
private int[] mNumOccurences; |
|
134 |
|
|
130 | 135 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
131 | 136 |
|
132 | 137 |
TwistyPyraminx(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh, |
133 | 138 |
DistortedEffects effects, int[][] moves, Resources res, int scrWidth) |
134 | 139 |
{ |
135 | 140 |
super(size, size, quat, texture, mesh, effects, moves, ObjectList.PYRA, res, scrWidth); |
141 |
|
|
142 |
initializeScrambleStates(size); |
|
136 | 143 |
} |
137 | 144 |
|
138 | 145 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
139 | 146 |
|
140 |
int[] getSolvedQuats(int cubit, int numLayers)
|
|
147 |
private int[][] generateState(int start, int end)
|
|
141 | 148 |
{ |
142 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
143 |
return status<0 ? null : buildSolvedQuats(MovementPyraminx.FACE_AXIS[status],QUATS); |
|
149 |
int len = end-start+1; |
|
150 |
int[] tmp = new int[6*len]; |
|
151 |
|
|
152 |
for(int i=0; i<len; i++) |
|
153 |
{ |
|
154 |
tmp[6*i ] = start; |
|
155 |
tmp[6*i+1] = -1; |
|
156 |
tmp[6*i+2] = start; |
|
157 |
tmp[6*i+3] = start; |
|
158 |
tmp[6*i+4] = +1; |
|
159 |
tmp[6*i+5] = start; |
|
160 |
|
|
161 |
start++; |
|
162 |
} |
|
163 |
|
|
164 |
return new int[][] {tmp,tmp,tmp,tmp}; |
|
144 | 165 |
} |
145 | 166 |
|
146 | 167 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
147 | 168 |
|
148 |
private float[] getRowChances(int numLayers)
|
|
169 |
private void initializeScrambleStates(int numLayers)
|
|
149 | 170 |
{ |
150 |
int total = numLayers*(numLayers+1)/2; |
|
151 |
float running=0.0f; |
|
152 |
float[] chances = new float[numLayers]; |
|
171 |
mStates = new ScrambleState[numLayers]; |
|
153 | 172 |
|
154 |
for(int i=0; i<numLayers; i++) |
|
173 |
for(int i=0; i<numLayers-1; i++)
|
|
155 | 174 |
{ |
156 |
running += (numLayers-i); |
|
157 |
chances[i] = running / total; |
|
175 |
mStates[i] = new ScrambleState( generateState(0,numLayers-1-i) ); |
|
158 | 176 |
} |
159 | 177 |
|
160 |
return chances; |
|
178 |
mStates[numLayers-1] = new ScrambleState( generateState(1,numLayers-2) ); |
|
179 |
} |
|
180 |
|
|
181 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
182 |
|
|
183 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
184 |
{ |
|
185 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
186 |
return status<0 ? null : buildSolvedQuats(MovementPyraminx.FACE_AXIS[status],QUATS); |
|
161 | 187 |
} |
162 | 188 |
|
163 | 189 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
389 | 415 |
return getNumLayers()/(SQ6/3); |
390 | 416 |
} |
391 | 417 |
|
392 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
393 |
// PUBLIC API |
|
394 |
|
|
395 |
public Static3D[] getRotationAxis() |
|
396 |
{ |
|
397 |
return ROT_AXIS; |
|
398 |
} |
|
399 |
|
|
400 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
401 |
|
|
402 |
public int[] getBasicAngle() |
|
403 |
{ |
|
404 |
return BASIC_ANGLE; |
|
405 |
} |
|
406 |
|
|
407 | 418 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
408 | 419 |
|
409 |
public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total)
|
|
420 |
private void initializeScrambling()
|
|
410 | 421 |
{ |
411 | 422 |
int numLayers = getNumLayers(); |
412 | 423 |
|
413 |
if( mRowChances==null ) mRowChances = getRowChances(numLayers); |
|
414 |
|
|
415 |
if( curr==0 ) |
|
424 |
if( mScrambleTable ==null ) |
|
416 | 425 |
{ |
417 |
scramble[curr][0] = rnd.nextInt(NUM_AXIS);
|
|
426 |
mScrambleTable = new int[NUM_AXIS][numLayers];
|
|
418 | 427 |
} |
419 |
else
|
|
428 |
if( mNumOccurences ==null )
|
|
420 | 429 |
{ |
421 |
int newVector = rnd.nextInt(NUM_AXIS-1); |
|
422 |
scramble[curr][0] = (newVector>=scramble[curr-1][0] ? newVector+1 : newVector); |
|
423 |
|
|
424 |
// Correct the situation when we first rotate the largest layer, then a tip (which doesn't |
|
425 |
// intersect anything besides the largest layer!) and then we try to rotate again along |
|
426 |
// the same axis like 2 rotations before - which carries the risk we rotate the largest |
|
427 |
// layer back to its spot again and the three moves end up being only a single tip rotation. |
|
428 |
if( curr>=2 && scramble[curr-1][1]==(numLayers-1) && scramble[curr][0]==scramble[curr-2][0] ) |
|
430 |
int max=0; |
|
431 |
|
|
432 |
for (ScrambleState mState : mStates) |
|
429 | 433 |
{ |
430 |
for(int ax=0; ax<NUM_AXIS; ax++) |
|
431 |
{ |
|
432 |
if( scramble[curr-1][0]!=ax && scramble[curr-2][0]!=ax ) |
|
433 |
{ |
|
434 |
scramble[curr][0]=ax; |
|
435 |
break; |
|
436 |
} |
|
437 |
} |
|
434 |
int tmp = mState.getTotal(-1); |
|
435 |
if (max < tmp) max = tmp; |
|
438 | 436 |
} |
437 |
|
|
438 |
mNumOccurences = new int[max]; |
|
439 | 439 |
} |
440 | 440 |
|
441 |
float rowFloat = rnd.nextFloat(); |
|
441 |
for(int i=0; i<NUM_AXIS; i++) |
|
442 |
for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0; |
|
443 |
} |
|
442 | 444 |
|
443 |
for(int row=0; row<numLayers; row++) |
|
444 |
{ |
|
445 |
if( rowFloat<=mRowChances[row] ) |
|
446 |
{ |
|
447 |
scramble[curr][1] = row; |
|
448 |
break; |
|
449 |
} |
|
450 |
} |
|
445 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
446 |
// PUBLIC API |
|
451 | 447 |
|
452 |
switch( rnd.nextInt(2) ) |
|
448 |
public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles) |
|
449 |
{ |
|
450 |
if( curr==0 ) |
|
453 | 451 |
{ |
454 |
case 0: scramble[curr][2] = -1; break; |
|
455 |
case 1: scramble[curr][2] = 1; break; |
|
452 |
mCurrState = 0; |
|
453 |
mIndexExcluded =-1; |
|
454 |
initializeScrambling(); |
|
456 | 455 |
} |
456 |
|
|
457 |
int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences); |
|
458 |
|
|
459 |
scramble[curr][0] = info[0]; |
|
460 |
scramble[curr][1] = info[1]; |
|
461 |
scramble[curr][2] = info[2]; |
|
462 |
|
|
463 |
mCurrState = info[3]; |
|
464 |
mIndexExcluded = info[0]; |
|
465 |
} |
|
466 |
|
|
467 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
468 |
|
|
469 |
public Static3D[] getRotationAxis() |
|
470 |
{ |
|
471 |
return ROT_AXIS; |
|
472 |
} |
|
473 |
|
|
474 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
475 |
|
|
476 |
public int[] getBasicAngle() |
|
477 |
{ |
|
478 |
return BASIC_ANGLE; |
|
457 | 479 |
} |
458 | 480 |
|
459 | 481 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
Also available in: Unified diff
Convert the Pyraminxes to the new scrambling paradigm.
This leaves only the two Squares.