Revision 91792184
Added by Leszek Koltunski over 2 years ago
src/main/java/org/distorted/objects/TwistySquare1.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; |
29 | 30 |
import org.distorted.library.type.Static4D; |
30 | 31 |
import org.distorted.main.R; |
31 | 32 |
|
32 |
import java.util.Random; |
|
33 |
|
|
34 | 33 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
35 | 34 |
|
36 | 35 |
class TwistySquare1 extends TwistySquare |
37 | 36 |
{ |
38 | 37 |
private static final int NUM_STICKERS = 6; |
39 | 38 |
|
40 |
private final int[][] mPermittedAngles; |
|
41 |
private final int[] mCornerQuat; |
|
42 |
private int mPermittedUp, mPermittedDo; |
|
43 | 39 |
private ObjectSticker[] mStickers; |
44 | 40 |
private int[] mQuatNumber; |
45 | 41 |
private float[][] mCenters; |
46 |
private int[][] mBadCornerQuats; |
|
47 | 42 |
private int[][] mStickerColor; |
48 | 43 |
private int[][] mStickerType; |
49 | 44 |
|
... | ... | |
53 | 48 |
DistortedEffects effects, int[][] moves, Resources res, int scrWidth) |
54 | 49 |
{ |
55 | 50 |
super(size, quat, texture, mesh, effects, moves, ObjectList.SQU1, res, scrWidth); |
51 |
} |
|
52 |
|
|
53 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
56 | 54 |
|
57 |
if( mBasicAngle==null ) initializeBasicAngle(); |
|
58 |
mLastRot = LAST_SL; |
|
59 |
mPermittedAngles = new int[2][mBasicAngle[0]]; |
|
60 |
mCornerQuat = new int[8]; |
|
55 |
ScrambleState[] getScrambleStates() |
|
56 |
{ |
|
57 |
return null; |
|
58 |
} |
|
59 |
|
|
60 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
61 |
|
|
62 |
int getScrambleType() |
|
63 |
{ |
|
64 |
return 1; |
|
61 | 65 |
} |
62 | 66 |
|
63 | 67 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
333 | 337 |
return mStickerType[variant][cubitface]*FACE_COLORS.length + mStickerColor[cubit][cubitface]; |
334 | 338 |
} |
335 | 339 |
|
336 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
337 |
|
|
338 |
private boolean cornerIsUp(int index) |
|
339 |
{ |
|
340 |
return ((index<4) ^ (mCornerQuat[index]>=12)); |
|
341 |
} |
|
342 |
|
|
343 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
344 |
|
|
345 |
private boolean cornerIsLeft(int index) |
|
346 |
{ |
|
347 |
int q = mCornerQuat[index]; |
|
348 |
|
|
349 |
switch(index) |
|
350 |
{ |
|
351 |
case 0: |
|
352 |
case 4: return ((q>=3 && q<= 7) || (q>=18 && q<=22)); |
|
353 |
case 1: |
|
354 |
case 5: return ((q>=6 && q<=10) || (q>=15 && q<=19)); |
|
355 |
case 2: |
|
356 |
case 6: return ((q==0 || q==1 || (q>=9 && q<=11)) || (q>=12 && q<=16)); |
|
357 |
case 3: |
|
358 |
case 7: return ((q>=0 && q<=4) || (q==12 || q==13 || (q>=21 && q<=23))); |
|
359 |
} |
|
360 |
|
|
361 |
return false; |
|
362 |
} |
|
363 |
|
|
364 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
365 |
|
|
366 |
private boolean quatIsBad(int quatIndex, int corner) |
|
367 |
{ |
|
368 |
if( mBadCornerQuats ==null ) |
|
369 |
{ |
|
370 |
// quat indices that make corner cubits bandage the puzzle. |
|
371 |
mBadCornerQuats = new int[][] { { 2, 8,17,23}, { 5,11,14,20} }; |
|
372 |
} |
|
373 |
|
|
374 |
int index = (corner%2); |
|
375 |
|
|
376 |
return ( quatIndex== mBadCornerQuats[index][0] || |
|
377 |
quatIndex== mBadCornerQuats[index][1] || |
|
378 |
quatIndex== mBadCornerQuats[index][2] || |
|
379 |
quatIndex== mBadCornerQuats[index][3] ); |
|
380 |
} |
|
381 |
|
|
382 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
383 |
|
|
384 |
private boolean isPermittedDo(int angle) |
|
385 |
{ |
|
386 |
if( mQuatMult==null ) initializeQuatMult(); |
|
387 |
|
|
388 |
for(int corner=0; corner<8; corner++) |
|
389 |
{ |
|
390 |
if( !cornerIsUp(corner) ) |
|
391 |
{ |
|
392 |
int currQuat = mCornerQuat[corner]; |
|
393 |
int finalQuat= mQuatMult[angle][currQuat]; |
|
394 |
if( quatIsBad(finalQuat,corner) ) return false; |
|
395 |
} |
|
396 |
} |
|
397 |
|
|
398 |
return true; |
|
399 |
} |
|
400 |
|
|
401 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
402 |
|
|
403 |
private boolean isPermittedUp(int angle) |
|
404 |
{ |
|
405 |
if( mQuatMult==null ) initializeQuatMult(); |
|
406 |
|
|
407 |
for(int corner=0; corner<8; corner++) |
|
408 |
{ |
|
409 |
if( cornerIsUp(corner) ) |
|
410 |
{ |
|
411 |
int currQuat = mCornerQuat[corner]; |
|
412 |
int finalQuat= mQuatMult[angle][currQuat]; |
|
413 |
if( quatIsBad(finalQuat,corner) ) return false; |
|
414 |
} |
|
415 |
} |
|
416 |
|
|
417 |
return true; |
|
418 |
} |
|
419 |
|
|
420 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
421 |
|
|
422 |
private void computePermittedAngles() |
|
423 |
{ |
|
424 |
if( mBasicAngle==null ) initializeBasicAngle(); |
|
425 |
|
|
426 |
mPermittedDo = 0; |
|
427 |
|
|
428 |
for(int angle=0; angle<mBasicAngle[0]; angle++) |
|
429 |
{ |
|
430 |
if( isPermittedDo(angle ) ) mPermittedAngles[0][mPermittedDo++] = angle; |
|
431 |
} |
|
432 |
|
|
433 |
mPermittedUp = 0; |
|
434 |
|
|
435 |
for(int angle=0; angle<mBasicAngle[0]; angle++) |
|
436 |
{ |
|
437 |
if( isPermittedUp(angle ) ) mPermittedAngles[1][mPermittedUp++] = angle; |
|
438 |
} |
|
439 |
} |
|
440 |
|
|
441 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
442 |
|
|
443 |
private int getNextAngle(Random rnd, int layer) |
|
444 |
{ |
|
445 |
if( mBasicAngle==null ) initializeBasicAngle(); |
|
446 |
int basic = mBasicAngle[0]; |
|
447 |
int num = layer==0 ? mPermittedDo:mPermittedUp; |
|
448 |
int index = rnd.nextInt(num); |
|
449 |
int angle = mPermittedAngles[layer][index]; |
|
450 |
return angle<basic/2 ? -angle : basic-angle; |
|
451 |
} |
|
452 |
|
|
453 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
454 |
|
|
455 |
private int getNextAngleNotZero(Random rnd, int layer) |
|
456 |
{ |
|
457 |
if( mBasicAngle==null ) initializeBasicAngle(); |
|
458 |
int basic = mBasicAngle[0]; |
|
459 |
int num = layer==0 ? mPermittedDo:mPermittedUp; |
|
460 |
int index = rnd.nextInt(num-1); |
|
461 |
int angle = mPermittedAngles[layer][index+1]; |
|
462 |
return angle<basic/2 ? -angle : basic-angle; |
|
463 |
} |
|
464 |
|
|
465 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
466 |
|
|
467 |
private int makeQuat(int axis,int index) |
|
468 |
{ |
|
469 |
if( axis==1 ) return 13; |
|
470 |
if( index<0 ) index+=12; |
|
471 |
return index; |
|
472 |
} |
|
473 |
|
|
474 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
475 |
|
|
476 |
private boolean cornerBelongs(int index, int axis, int layer) |
|
477 |
{ |
|
478 |
if( axis==0 ) |
|
479 |
{ |
|
480 |
boolean up = cornerIsUp(index); |
|
481 |
return ((up && layer==2) || (!up && layer==0)); |
|
482 |
} |
|
483 |
else |
|
484 |
{ |
|
485 |
boolean le = cornerIsLeft(index); |
|
486 |
return ((le && layer==0) || (!le && layer==1)); |
|
487 |
} |
|
488 |
} |
|
489 |
|
|
490 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
491 |
|
|
492 |
private void updateCornerQuats(int[] rotInfo) |
|
493 |
{ |
|
494 |
if( mQuatMult==null ) initializeQuatMult(); |
|
495 |
|
|
496 |
int axis = rotInfo[0]; |
|
497 |
int layer= rotInfo[1]; |
|
498 |
int index=-rotInfo[2]; |
|
499 |
|
|
500 |
int quat = makeQuat(axis,index); |
|
501 |
|
|
502 |
for(int corner=0; corner<8; corner++) |
|
503 |
{ |
|
504 |
if( cornerBelongs(corner,axis,layer) ) |
|
505 |
{ |
|
506 |
int curr = mCornerQuat[corner]; |
|
507 |
mCornerQuat[corner] = mQuatMult[quat][curr]; |
|
508 |
} |
|
509 |
} |
|
510 |
} |
|
511 |
|
|
512 | 340 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
513 | 341 |
// PUBLIC API |
514 | 342 |
|
515 |
public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total) |
|
516 |
{ |
|
517 |
int layer, nextAngle; |
|
518 |
|
|
519 |
if( curr==0 ) |
|
520 |
{ |
|
521 |
for(int corner=0; corner<8; corner++) mCornerQuat[corner] = 0; |
|
522 |
mLastRot = rnd.nextInt(4); |
|
523 |
computePermittedAngles(); |
|
524 |
} |
|
525 |
|
|
526 |
switch(mLastRot) |
|
527 |
{ |
|
528 |
case LAST_SL: layer = rnd.nextInt(2); |
|
529 |
nextAngle = getNextAngle(rnd,layer); |
|
530 |
|
|
531 |
if( nextAngle==0 ) |
|
532 |
{ |
|
533 |
layer = 1-layer; |
|
534 |
nextAngle = getNextAngleNotZero(rnd,layer); |
|
535 |
} |
|
536 |
|
|
537 |
scramble[curr][0] = 0; |
|
538 |
scramble[curr][1] = 2*layer; |
|
539 |
scramble[curr][2] = nextAngle; |
|
540 |
mLastRot = layer==0 ? LAST_LO : LAST_UP; |
|
541 |
updateCornerQuats(scramble[curr]); |
|
542 |
break; |
|
543 |
case LAST_LO: |
|
544 |
case LAST_UP: layer = mLastRot==LAST_LO ? 1:0; |
|
545 |
nextAngle = getNextAngle(rnd,layer); |
|
546 |
|
|
547 |
if( nextAngle!=0 ) |
|
548 |
{ |
|
549 |
scramble[curr][0] = 0; |
|
550 |
scramble[curr][1] = 2*layer; |
|
551 |
scramble[curr][2] = nextAngle; |
|
552 |
updateCornerQuats(scramble[curr]); |
|
553 |
mLastRot = LAST_UL; |
|
554 |
} |
|
555 |
else |
|
556 |
{ |
|
557 |
scramble[curr][0] = 1; |
|
558 |
scramble[curr][1] = rnd.nextInt(2); |
|
559 |
scramble[curr][2] = 1; |
|
560 |
mLastRot = LAST_SL; |
|
561 |
updateCornerQuats(scramble[curr]); |
|
562 |
computePermittedAngles(); |
|
563 |
} |
|
564 |
|
|
565 |
break; |
|
566 |
case LAST_UL: scramble[curr][0] = 1; |
|
567 |
scramble[curr][1] = rnd.nextInt(2); |
|
568 |
scramble[curr][2] = 1; |
|
569 |
mLastRot = LAST_SL; |
|
570 |
updateCornerQuats(scramble[curr]); |
|
571 |
computePermittedAngles(); |
|
572 |
break; |
|
573 |
} |
|
574 |
} |
|
575 |
|
|
576 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
577 |
|
|
578 | 343 |
public int getObjectName(int numLayers) |
579 | 344 |
{ |
580 | 345 |
return R.string.squa1; |
Also available in: Unified diff
Make object scrambling abstract (well, almost - with exception of Square-1 - this theoretically could also be done the generic way, but this would require almost 20000 'ScrambleStates')