Revision a480ee80
Added by Leszek Koltunski over 3 years ago
src/main/java/org/distorted/objects/MovementSquare.java | ||
---|---|---|
46 | 46 |
|
47 | 47 |
int computeRowFromOffset(int face, int axisIndex, int numLayers, float offset) |
48 | 48 |
{ |
49 |
//android.util.Log.e("D", "face="+face+" size="+numLayers+" offset="+offset); |
|
50 |
|
|
51 | 49 |
return offset>DIST2D? 2-axisIndex : 0; |
52 | 50 |
} |
53 | 51 |
|
src/main/java/org/distorted/objects/TwistyBandagedAbstract.java | ||
---|---|---|
161 | 161 |
abstract float[][] getPositions(); |
162 | 162 |
abstract int[] getQuatIndices(); |
163 | 163 |
|
164 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
165 |
|
|
166 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
167 |
{ |
|
168 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
169 |
return status<0 ? null : buildSolvedQuats(MovementCube.FACE_AXIS[status],QUATS); |
|
170 |
} |
|
171 |
|
|
164 | 172 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
165 | 173 |
|
166 | 174 |
int getNumCubits() |
... | ... | |
461 | 469 |
{ |
462 | 470 |
return BASIC_ANGLE; |
463 | 471 |
} |
464 |
|
|
465 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
466 |
|
|
467 |
public boolean isSolved() |
|
468 |
{ |
|
469 |
int index = CUBITS[0].mQuatIndex; |
|
470 |
|
|
471 |
for(int i=1; i<NUM_CUBITS; i++) |
|
472 |
{ |
|
473 |
if( thereIsVisibleDifference(CUBITS[i], index) ) return false; |
|
474 |
} |
|
475 |
|
|
476 |
return true; |
|
477 |
} |
|
478 | 472 |
} |
src/main/java/org/distorted/objects/TwistyCube.java | ||
---|---|---|
136 | 136 |
super(size, size, quat, texture, mesh, effects, moves, ObjectList.CUBE, res, scrWidth); |
137 | 137 |
} |
138 | 138 |
|
139 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
140 |
|
|
141 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
142 |
{ |
|
143 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
144 |
return status<0 ? null : buildSolvedQuats(MovementCube.FACE_AXIS[status],QUATS); |
|
145 |
} |
|
146 |
|
|
139 | 147 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
140 | 148 |
|
141 | 149 |
ObjectShape getObjectShape(int cubit, int numLayers) |
... | ... | |
356 | 364 |
} |
357 | 365 |
} |
358 | 366 |
|
359 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
360 |
|
|
361 |
public boolean isSolved() |
|
362 |
{ |
|
363 |
int index = CUBITS[0].mQuatIndex; |
|
364 |
|
|
365 |
for(int i=1; i<NUM_CUBITS; i++) |
|
366 |
{ |
|
367 |
if( thereIsVisibleDifference(CUBITS[i], index) ) return false; |
|
368 |
} |
|
369 |
|
|
370 |
return true; |
|
371 |
} |
|
372 |
|
|
373 | 367 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
374 | 368 |
|
375 | 369 |
public int getObjectName(int numLayers) |
src/main/java/org/distorted/objects/TwistyDiamond.java | ||
---|---|---|
57 | 57 |
COLOR_GREEN , COLOR_GREY |
58 | 58 |
}; |
59 | 59 |
|
60 |
private static final int[] mFaceMap = new int[] {4,0,6,2,7,3,5,1}; |
|
61 |
|
|
60 | 62 |
// All legal rotation quats of a Diamond: unit + three 180 deg turns + 8 generators |
61 | 63 |
private static final Static4D[] QUATS = new Static4D[] |
62 | 64 |
{ |
... | ... | |
77 | 79 |
|
78 | 80 |
private static final float DIST = 0.50f; |
79 | 81 |
|
80 |
private static final int[][] mFaceNeutralQuatIndex = new int[][] |
|
81 |
{ |
|
82 |
{6,10}, |
|
83 |
{4, 8}, |
|
84 |
{7,11}, |
|
85 |
{5, 9}, |
|
86 |
{7,11}, |
|
87 |
{5, 9}, |
|
88 |
{6,10}, |
|
89 |
{4, 8} |
|
90 |
}; |
|
91 |
|
|
92 | 82 |
private static final int[] mTetraToFaceMap = new int[] {1,2,3,0,5,6,7,4}; |
93 | 83 |
|
94 | 84 |
private static final double[][] VERTICES_TETRA = new double[][] |
... | ... | |
153 | 143 |
super(size, size, quat, texture, mesh, effects, moves, ObjectList.DIAM, res, scrWidth); |
154 | 144 |
} |
155 | 145 |
|
146 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
147 |
|
|
148 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
149 |
{ |
|
150 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
151 |
return status<0 ? null : buildSolvedQuats(MovementDiamond.FACE_AXIS[mFaceMap[status]],QUATS); |
|
152 |
} |
|
153 |
|
|
156 | 154 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
157 | 155 |
|
158 | 156 |
float getScreenRatio() |
... | ... | |
541 | 539 |
} |
542 | 540 |
} |
543 | 541 |
|
544 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
545 |
// The Diamond is solved if and only if: |
|
546 |
// |
|
547 |
// - all cubits are rotated by the same quat |
|
548 |
// - those which are internal to the side, i.e. those which have only one 'non-black' face, might |
|
549 |
// also be optionally rotated by one of the two quats whose axis is perpendicular to the face. |
|
550 |
// (including some octahedrons if numLayers>=4) |
|
551 |
|
|
552 |
public boolean isSolved() |
|
553 |
{ |
|
554 |
int q = CUBITS[0].mQuatIndex; |
|
555 |
int layers = getNumLayers(); |
|
556 |
int numO = getNumOctahedrons(layers); |
|
557 |
|
|
558 |
for(int i=1; i<numO; i++) |
|
559 |
{ |
|
560 |
if( CUBITS[i].mQuatIndex != q ) return false; |
|
561 |
} |
|
562 |
|
|
563 |
int qI, q1Index, q2Index, face; |
|
564 |
|
|
565 |
for(int i=numO; i<NUM_CUBITS; i++) |
|
566 |
{ |
|
567 |
face = retFaceTetraBelongsTo(i-numO,layers); |
|
568 |
q1Index = mFaceNeutralQuatIndex[face][0]; |
|
569 |
q2Index = mFaceNeutralQuatIndex[face][1]; |
|
570 |
qI = CUBITS[i].mQuatIndex; |
|
571 |
|
|
572 |
if( qI != q && qI != mulQuat(q,q1Index) && qI != mulQuat(q,q2Index) ) return false; |
|
573 |
} |
|
574 |
|
|
575 |
return true; |
|
576 |
} |
|
577 |
|
|
578 | 542 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
579 | 543 |
|
580 | 544 |
public int getObjectName(int numLayers) |
src/main/java/org/distorted/objects/TwistyDino4.java | ||
---|---|---|
88 | 88 |
super(size, quat, texture, mesh, effects, moves, ObjectList.DIN4, res, scrWidth); |
89 | 89 |
} |
90 | 90 |
|
91 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
92 |
|
|
93 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
94 |
{ |
|
95 |
return null; |
|
96 |
} |
|
97 |
|
|
91 | 98 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
92 | 99 |
|
93 | 100 |
int getFaceColor(int cubit, int cubitface, int size) |
src/main/java/org/distorted/objects/TwistyDino6.java | ||
---|---|---|
45 | 45 |
super(size, quat, texture, mesh, effects, moves, ObjectList.DINO, res, scrWidth); |
46 | 46 |
} |
47 | 47 |
|
48 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
49 |
// Dino6 is solved if and only if: |
|
50 |
// |
|
51 |
// All four 'X' cubits (i.e. those whose longest edge goes along the X axis) are rotated |
|
52 |
// by the same quaternion qX, similarly all four 'Y' cubits by the same qY and all four 'Z' |
|
53 |
// by the same qZ, and then either: |
|
54 |
// |
|
55 |
// a) qX = qY = qZ |
|
56 |
// b) qY = qX*Q2 and qZ = qX*Q8 (i.e. swap of WHITE and YELLOW faces) |
|
57 |
// c) qX = qY*Q2 and qZ = qY*Q10 (i.e. swap of BLUE and GREEN faces) |
|
58 |
// d) qX = qZ*Q8 and qY = qZ*Q10 (i.e. swap of RED and BROWN faces) |
|
59 |
// |
|
60 |
// BUT: cases b), c) and d) are really the same - it's all just a mirror image of the original. |
|
61 |
// |
|
62 |
// X cubits: 0, 2, 8, 10 |
|
63 |
// Y cubits: 1, 3, 9, 11 |
|
64 |
// Z cubits: 4, 5, 6, 7 |
|
65 |
|
|
66 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
67 |
{ |
|
68 |
switch(cubit) |
|
69 |
{ |
|
70 |
case 0: case 2: case 8: case 10: return null; |
|
71 |
case 1: case 3: case 9: case 11: return new int[] {2}; |
|
72 |
case 4: case 5: case 6: case 7: return new int[] {8}; |
|
73 |
} |
|
74 |
|
|
75 |
return null; |
|
76 |
} |
|
77 |
|
|
48 | 78 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
49 | 79 |
|
50 | 80 |
int getFaceColor(int cubit, int cubitface, int size) |
... | ... | |
87 | 117 |
} |
88 | 118 |
} |
89 | 119 |
|
90 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
91 |
// Dino6 is solved if and only if: |
|
92 |
// |
|
93 |
// All four 'X' cubits (i.e. those whose longest edge goes along the X axis) are rotated |
|
94 |
// by the same quaternion qX, similarly all four 'Y' cubits by the same qY and all four 'Z' |
|
95 |
// by the same qZ, and then either: |
|
96 |
// |
|
97 |
// a) qX = qY = qZ |
|
98 |
// b) qY = qX*Q2 and qZ = qX*Q8 (i.e. swap of WHITE and YELLOW faces) |
|
99 |
// c) qX = qY*Q2 and qZ = qY*Q10 (i.e. swap of BLUE and GREEN faces) |
|
100 |
// d) qX = qZ*Q8 and qY = qZ*Q10 (i.e. swap of RED and BROWN faces) |
|
101 |
// |
|
102 |
// BUT: cases b), c) and d) are really the same - it's all just a mirror image of the original. |
|
103 |
// |
|
104 |
// X cubits: 0, 2, 8, 10 |
|
105 |
// Y cubits: 1, 3, 9, 11 |
|
106 |
// Z cubits: 4, 5, 6, 7 |
|
107 |
|
|
108 |
public boolean isSolved() |
|
109 |
{ |
|
110 |
int qX = CUBITS[0].mQuatIndex; |
|
111 |
int qY = CUBITS[1].mQuatIndex; |
|
112 |
int qZ = CUBITS[4].mQuatIndex; |
|
113 |
|
|
114 |
if( CUBITS[2].mQuatIndex != qX || CUBITS[8].mQuatIndex != qX || CUBITS[10].mQuatIndex != qX || |
|
115 |
CUBITS[3].mQuatIndex != qY || CUBITS[9].mQuatIndex != qY || CUBITS[11].mQuatIndex != qY || |
|
116 |
CUBITS[5].mQuatIndex != qZ || CUBITS[6].mQuatIndex != qZ || CUBITS[ 7].mQuatIndex != qZ ) |
|
117 |
{ |
|
118 |
return false; |
|
119 |
} |
|
120 |
|
|
121 |
return ( qX==qY && qX==qZ ) || ( qY==mulQuat(qX,2) && qZ==mulQuat(qX,8) ); |
|
122 |
} |
|
123 |
|
|
124 | 120 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
125 | 121 |
|
126 | 122 |
public int getObjectName(int numLayers) |
src/main/java/org/distorted/objects/TwistyHelicopter.java | ||
---|---|---|
243 | 243 |
super(size, size, quat, texture, mesh, effects, moves, ObjectList.HELI, res, scrWidth); |
244 | 244 |
} |
245 | 245 |
|
246 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
247 |
|
|
248 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
249 |
{ |
|
250 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
251 |
return status<0 ? null : buildSolvedQuats(MovementHelicopter.FACE_AXIS[status],QUATS); |
|
252 |
} |
|
253 |
|
|
246 | 254 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
247 | 255 |
|
248 | 256 |
float getScreenRatio() |
... | ... | |
426 | 434 |
} |
427 | 435 |
} |
428 | 436 |
|
429 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
430 |
// The Helicopter is solved if and only if: |
|
431 |
// |
|
432 |
// 1) all of its corner cubits are rotated with the same quat |
|
433 |
// 2) all its face cubits are rotated with the same quat like the corner ones, |
|
434 |
// and optionally they also might be turned by a multiple of 90 degrees along |
|
435 |
// a vector perpendicular to the face they lie on. |
|
436 |
// |
|
437 |
// i.e. |
|
438 |
// cubits 8, 9,10,11,12,13,14,15 - might be extra QUAT 1,8,9 |
|
439 |
// cubits 16,17,18,19,20,21,22,23 - might be extra QUAT 2,12,13 |
|
440 |
// cubits 24,25,26,27,28,29,30,31 - might be extra QUAT 3,14,15 |
|
441 |
|
|
442 |
public boolean isSolved() |
|
443 |
{ |
|
444 |
int q = CUBITS[0].mQuatIndex; |
|
445 |
|
|
446 |
if ( CUBITS[1].mQuatIndex == q && |
|
447 |
CUBITS[2].mQuatIndex == q && |
|
448 |
CUBITS[3].mQuatIndex == q && |
|
449 |
CUBITS[4].mQuatIndex == q && |
|
450 |
CUBITS[5].mQuatIndex == q && |
|
451 |
CUBITS[6].mQuatIndex == q && |
|
452 |
CUBITS[7].mQuatIndex == q ) |
|
453 |
{ |
|
454 |
int q1 = mulQuat(q,1); |
|
455 |
int q2 = mulQuat(q,8); |
|
456 |
int q3 = mulQuat(q,9); |
|
457 |
|
|
458 |
for(int index=8; index<16; index++) |
|
459 |
{ |
|
460 |
int qIndex = CUBITS[index].mQuatIndex; |
|
461 |
if( qIndex!=q && qIndex!=q1 && qIndex!=q2 && qIndex!=q3 ) return false; |
|
462 |
} |
|
463 |
|
|
464 |
q1 = mulQuat(q, 2); |
|
465 |
q2 = mulQuat(q,12); |
|
466 |
q3 = mulQuat(q,13); |
|
467 |
|
|
468 |
for(int index=16; index<24; index++) |
|
469 |
{ |
|
470 |
int qIndex = CUBITS[index].mQuatIndex; |
|
471 |
if( qIndex!=q && qIndex!=q1 && qIndex!=q2 && qIndex!=q3 ) return false; |
|
472 |
} |
|
473 |
|
|
474 |
q1 = mulQuat(q, 3); |
|
475 |
q2 = mulQuat(q,14); |
|
476 |
q3 = mulQuat(q,15); |
|
477 |
|
|
478 |
for(int index=24; index<32; index++) |
|
479 |
{ |
|
480 |
int qIndex = CUBITS[index].mQuatIndex; |
|
481 |
if( qIndex!=q && qIndex!=q1 && qIndex!=q2 && qIndex!=q3 ) return false; |
|
482 |
} |
|
483 |
|
|
484 |
return true; |
|
485 |
} |
|
486 |
|
|
487 |
return false; |
|
488 |
} |
|
489 |
|
|
490 | 437 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
491 | 438 |
|
492 | 439 |
public int getObjectName(int numLayers) |
src/main/java/org/distorted/objects/TwistyIvy.java | ||
---|---|---|
124 | 124 |
super(size, size, quat, texture, mesh, effects, moves, ObjectList.IVY, res, scrWidth); |
125 | 125 |
} |
126 | 126 |
|
127 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
128 |
|
|
129 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
130 |
{ |
|
131 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
132 |
return status<0 ? null : buildSolvedQuats(MovementIvy.FACE_AXIS[status],QUATS); |
|
133 |
} |
|
134 |
|
|
127 | 135 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
128 | 136 |
|
129 | 137 |
float getScreenRatio() |
... | ... | |
456 | 464 |
} |
457 | 465 |
} |
458 | 466 |
|
459 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
460 |
// The Ivy is solved if and only if: |
|
461 |
// |
|
462 |
// 1) all 4 of its corner cubits are rotated with the same quat |
|
463 |
// 2) all its face cubits are rotated with the same quat like the corner ones, |
|
464 |
// and optionally they also might be upside down. |
|
465 |
// |
|
466 |
// i.e. |
|
467 |
// cubits [4] and [5] - might be extra QUAT[1] |
|
468 |
// cubits [6] and [7] - might be extra QUAT[2] |
|
469 |
// cubits [8] and [9] - might be extra QUAT[3] |
|
470 |
|
|
471 |
public boolean isSolved() |
|
472 |
{ |
|
473 |
int q1,q = CUBITS[0].mQuatIndex; |
|
474 |
|
|
475 |
if( CUBITS[1].mQuatIndex == q && |
|
476 |
CUBITS[2].mQuatIndex == q && |
|
477 |
CUBITS[3].mQuatIndex == q ) |
|
478 |
{ |
|
479 |
q1 = mulQuat(q,1); |
|
480 |
if( CUBITS[4].mQuatIndex != q && CUBITS[4].mQuatIndex != q1 ) return false; |
|
481 |
if( CUBITS[5].mQuatIndex != q && CUBITS[5].mQuatIndex != q1 ) return false; |
|
482 |
|
|
483 |
q1 = mulQuat(q,2); |
|
484 |
if( CUBITS[6].mQuatIndex != q && CUBITS[6].mQuatIndex != q1 ) return false; |
|
485 |
if( CUBITS[7].mQuatIndex != q && CUBITS[7].mQuatIndex != q1 ) return false; |
|
486 |
|
|
487 |
q1 = mulQuat(q,3); |
|
488 |
if( CUBITS[8].mQuatIndex != q && CUBITS[8].mQuatIndex != q1 ) return false; |
|
489 |
if( CUBITS[9].mQuatIndex != q && CUBITS[9].mQuatIndex != q1 ) return false; |
|
490 |
|
|
491 |
return true; |
|
492 |
} |
|
493 |
|
|
494 |
return false; |
|
495 |
} |
|
496 |
|
|
497 | 467 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
498 | 468 |
|
499 | 469 |
public int getObjectName(int numLayers) |
src/main/java/org/distorted/objects/TwistyJing.java | ||
---|---|---|
223 | 223 |
super(size, size, quat, texture, mesh, effects, moves, ObjectList.JING, res, scrWidth); |
224 | 224 |
} |
225 | 225 |
|
226 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
227 |
|
|
228 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
229 |
{ |
|
230 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
231 |
return status<0 ? null : buildSolvedQuats(MovementJing.FACE_AXIS[status],QUATS); |
|
232 |
} |
|
233 |
|
|
226 | 234 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
227 | 235 |
|
228 | 236 |
float[][] getCubitPositions(int size) |
... | ... | |
406 | 414 |
} |
407 | 415 |
} |
408 | 416 |
|
409 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
410 |
// JingPyraminx is solved iff |
|
411 |
// a) all of its corner and edge cubits are rotated with the same quat |
|
412 |
// b) its 4 face cubits might also be rotated along the axis perpendicular to the face. |
|
413 |
// |
|
414 |
// So: |
|
415 |
// [10] might be extra QUAT[4] or QUAT[8] |
|
416 |
// [11] might be extra QUAT[5] or QUAT[9] |
|
417 |
// [12] might be extra QUAT[2] or QUAT[6] |
|
418 |
// [13] might be extra QUAT[3] or QUAT[7] |
|
419 |
|
|
420 |
public boolean isSolved() |
|
421 |
{ |
|
422 |
int q1, q = CUBITS[0].mQuatIndex; |
|
423 |
|
|
424 |
if( CUBITS[1].mQuatIndex != q ) return false; |
|
425 |
if( CUBITS[2].mQuatIndex != q ) return false; |
|
426 |
if( CUBITS[3].mQuatIndex != q ) return false; |
|
427 |
if( CUBITS[4].mQuatIndex != q ) return false; |
|
428 |
if( CUBITS[5].mQuatIndex != q ) return false; |
|
429 |
if( CUBITS[6].mQuatIndex != q ) return false; |
|
430 |
if( CUBITS[7].mQuatIndex != q ) return false; |
|
431 |
if( CUBITS[8].mQuatIndex != q ) return false; |
|
432 |
if( CUBITS[9].mQuatIndex != q ) return false; |
|
433 |
|
|
434 |
q1 = CUBITS[10].mQuatIndex; |
|
435 |
if( q1!=q && q1!=mulQuat(q,4) && q1!=mulQuat(q,8) ) return false; |
|
436 |
q1 = CUBITS[11].mQuatIndex; |
|
437 |
if( q1!=q && q1!=mulQuat(q,5) && q1!=mulQuat(q,9) ) return false; |
|
438 |
q1 = CUBITS[12].mQuatIndex; |
|
439 |
if( q1!=q && q1!=mulQuat(q,2) && q1!=mulQuat(q,6) ) return false; |
|
440 |
q1 = CUBITS[13].mQuatIndex; |
|
441 |
if( q1!=q && q1!=mulQuat(q,3) && q1!=mulQuat(q,7) ) return false; |
|
442 |
|
|
443 |
return true; |
|
444 |
} |
|
445 |
|
|
446 | 417 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
447 | 418 |
|
448 | 419 |
public int getObjectName(int numLayers) |
src/main/java/org/distorted/objects/TwistyKilominx.java | ||
---|---|---|
695 | 695 |
return 2; |
696 | 696 |
} |
697 | 697 |
|
698 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
699 |
// PUBLIC API |
|
700 |
|
|
701 |
public boolean isSolved() |
|
702 |
{ |
|
703 |
int index = CUBITS[0].mQuatIndex; |
|
704 |
|
|
705 |
for(int i=1; i<NUM_CUBITS; i++) |
|
706 |
{ |
|
707 |
if( thereIsVisibleDifference(CUBITS[i], index) ) return false; |
|
708 |
} |
|
709 |
|
|
710 |
return true; |
|
711 |
} |
|
712 |
|
|
713 | 698 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
714 | 699 |
|
715 | 700 |
public int getObjectName(int numLayers) |
src/main/java/org/distorted/objects/TwistyMegaminx.java | ||
---|---|---|
608 | 608 |
return 4; |
609 | 609 |
} |
610 | 610 |
|
611 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
612 |
// PUBLIC API |
|
613 |
|
|
614 |
public boolean isSolved() |
|
615 |
{ |
|
616 |
int index = CUBITS[0].mQuatIndex; |
|
617 |
|
|
618 |
for(int i=1; i<NUM_CUBITS; i++) |
|
619 |
{ |
|
620 |
if( thereIsVisibleDifference(CUBITS[i], index) ) return false; |
|
621 |
} |
|
622 |
|
|
623 |
return true; |
|
624 |
} |
|
625 |
|
|
626 | 611 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
627 | 612 |
|
628 | 613 |
public int getObjectName(int numLayers) |
src/main/java/org/distorted/objects/TwistyMinx.java | ||
---|---|---|
81 | 81 |
MINX_DBLUE , MINX_DYELLOW, MINX_WHITE , MINX_GREY |
82 | 82 |
}; |
83 | 83 |
|
84 |
private static final int[] mFaceMap = new int[] {8,10,3,7,1,11,9,2,4,0,5,6}; |
|
85 |
|
|
84 | 86 |
// All 60 legal rotation quats of a Minx |
85 | 87 |
static final Static4D[] QUATS = new Static4D[] |
86 | 88 |
{ |
... | ... | |
336 | 338 |
super(numLayers, realSize, quat, texture, mesh, effects, moves, obj, res, scrWidth); |
337 | 339 |
} |
338 | 340 |
|
341 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
342 |
|
|
343 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
344 |
{ |
|
345 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
346 |
return status<0 ? null : buildSolvedQuats(MovementMinx.FACE_AXIS[mFaceMap[status]],QUATS); |
|
347 |
} |
|
348 |
|
|
339 | 349 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
340 | 350 |
|
341 | 351 |
Static4D[] getQuats() |
src/main/java/org/distorted/objects/TwistyObject.java | ||
---|---|---|
95 | 95 |
final int NUM_CUBITS; |
96 | 96 |
final int NUM_AXIS; |
97 | 97 |
|
98 |
private static final float[] mTmp1 = new float[4]; |
|
99 |
private static final float[] mTmp2 = new float[4]; |
|
100 |
|
|
101 | 98 |
private final int mNumCubitFaces; |
102 | 99 |
private final Static3D[] mAxis; |
103 | 100 |
private final float[][] mCuts; |
... | ... | |
119 | 116 |
private final DistortedTexture mTexture; |
120 | 117 |
private final float mInitScreenRatio; |
121 | 118 |
private float mObjectScreenRatio; |
119 |
private int[][] mSolvedQuats; |
|
120 |
private int[][] mQuatMult; |
|
121 |
private int[] mTmpQuats; |
|
122 | 122 |
private int mNumTexRows, mNumTexCols; |
123 | 123 |
private int mRotRowBitmap; |
124 | 124 |
private int mRotAxis; |
... | ... | |
186 | 186 |
|
187 | 187 |
CUBITS = new Cubit[NUM_CUBITS]; |
188 | 188 |
createMeshAndCubits(list,res); |
189 |
createDataStructuresForSolved(numLayers); |
|
189 | 190 |
|
190 | 191 |
mTexture = new DistortedTexture(); |
191 | 192 |
mEffects = new DistortedEffects(); |
... | ... | |
316 | 317 |
return mesh; |
317 | 318 |
} |
318 | 319 |
|
320 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
321 |
|
|
322 |
private void createDataStructuresForSolved(int numLayers) |
|
323 |
{ |
|
324 |
mTmpQuats = new int[QUATS.length]; |
|
325 |
mSolvedQuats = new int[NUM_CUBITS][]; |
|
326 |
|
|
327 |
for(int c=0; c<NUM_CUBITS; c++) |
|
328 |
{ |
|
329 |
mSolvedQuats[c] = getSolvedQuats(c,numLayers); |
|
330 |
} |
|
331 |
} |
|
332 |
|
|
333 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
334 |
// This is used to build internal data structures for the generic 'isSolved()' |
|
335 |
// |
|
336 |
// if this is an internal cubit (all faces black): return -1 |
|
337 |
// if this is a face cubit (one non-black face): return the color index of the only non-black face. |
|
338 |
// Color index, i.e. the index into the 'FACE_COLORS' table. |
|
339 |
// else (edge or corner cubit, more than one non-black face): return -2. |
|
340 |
|
|
341 |
int retCubitSolvedStatus(int cubit, int numLayers) |
|
342 |
{ |
|
343 |
int numNonBlack=0, nonBlackIndex=-1, color; |
|
344 |
|
|
345 |
for(int face=0; face<mNumCubitFaces; face++) |
|
346 |
{ |
|
347 |
color = getFaceColor(cubit,face,numLayers); |
|
348 |
|
|
349 |
if( color<NUM_TEXTURES ) |
|
350 |
{ |
|
351 |
numNonBlack++; |
|
352 |
nonBlackIndex = color%NUM_FACES; |
|
353 |
} |
|
354 |
} |
|
355 |
|
|
356 |
if( numNonBlack==0 ) return -1; |
|
357 |
if( numNonBlack>=2 ) return -2; |
|
358 |
|
|
359 |
return nonBlackIndex; |
|
360 |
} |
|
361 |
|
|
362 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
363 |
|
|
364 |
int[] buildSolvedQuats(Static3D faceAx, Static4D[] quats) |
|
365 |
{ |
|
366 |
final float MAXD = 0.0001f; |
|
367 |
float x = faceAx.get0(); |
|
368 |
float y = faceAx.get1(); |
|
369 |
float z = faceAx.get2(); |
|
370 |
float a,dx,dy,dz,qx,qy,qz; |
|
371 |
Static4D quat; |
|
372 |
|
|
373 |
int len = quats.length; |
|
374 |
int place = 0; |
|
375 |
|
|
376 |
for(int q=1; q<len; q++) |
|
377 |
{ |
|
378 |
quat = quats[q]; |
|
379 |
qx = quat.get0(); |
|
380 |
qy = quat.get1(); |
|
381 |
qz = quat.get2(); |
|
382 |
|
|
383 |
if( x!=0.0f ) { a = qx/x; } |
|
384 |
else if( y!=0.0f ) { a = qy/y; } |
|
385 |
else { a = qz/z; } |
|
386 |
|
|
387 |
dx = a*x-qx; |
|
388 |
dy = a*y-qy; |
|
389 |
dz = a*z-qz; |
|
390 |
|
|
391 |
if( dx>-MAXD && dx<MAXD && dy>-MAXD && dy<MAXD && dz>-MAXD && dz<MAXD ) |
|
392 |
{ |
|
393 |
mTmpQuats[place++] = q; |
|
394 |
} |
|
395 |
} |
|
396 |
|
|
397 |
if( place!=0 ) |
|
398 |
{ |
|
399 |
int[] ret = new int[place]; |
|
400 |
System.arraycopy(mTmpQuats,0,ret,0,place); |
|
401 |
return ret; |
|
402 |
} |
|
403 |
|
|
404 |
return null; |
|
405 |
} |
|
406 |
|
|
407 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
408 |
|
|
409 |
private int getMultQuat(int index1, int index2) |
|
410 |
{ |
|
411 |
if( mQuatMult==null ) |
|
412 |
{ |
|
413 |
int len = QUATS.length; |
|
414 |
mQuatMult = new int[len][len]; |
|
415 |
|
|
416 |
for(int i=0; i<len; i++) |
|
417 |
for(int j=0; j<len; j++) mQuatMult[i][j] = -1; |
|
418 |
} |
|
419 |
|
|
420 |
if( mQuatMult[index1][index2]==-1 ) |
|
421 |
{ |
|
422 |
mQuatMult[index1][index2] = mulQuat(index1,index2); |
|
423 |
} |
|
424 |
|
|
425 |
return mQuatMult[index1][index2]; |
|
426 |
} |
|
427 |
|
|
428 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
429 |
|
|
430 |
public boolean isSolved() |
|
431 |
{ |
|
432 |
int len, q1,q = CUBITS[0].mQuatIndex; |
|
433 |
int[] solved; |
|
434 |
boolean skip; |
|
435 |
|
|
436 |
for(int c=1; c<NUM_CUBITS; c++) |
|
437 |
{ |
|
438 |
q1 = CUBITS[c].mQuatIndex; |
|
439 |
|
|
440 |
if( q1==q ) continue; |
|
441 |
|
|
442 |
skip = false; |
|
443 |
solved = mSolvedQuats[c]; |
|
444 |
len = solved==null ? 0:solved.length; |
|
445 |
|
|
446 |
for(int i=0; i<len; i++) |
|
447 |
{ |
|
448 |
if( q1==getMultQuat(q,solved[i]) ) |
|
449 |
{ |
|
450 |
skip = true; |
|
451 |
break; |
|
452 |
} |
|
453 |
} |
|
454 |
|
|
455 |
if( !skip ) return false; |
|
456 |
} |
|
457 |
|
|
458 |
return true; |
|
459 |
} |
|
460 |
|
|
319 | 461 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
320 | 462 |
|
321 | 463 |
public void setObjectRatio(float sizeChange) |
... | ... | |
523 | 665 |
return -1; |
524 | 666 |
} |
525 | 667 |
|
526 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
527 |
// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different |
|
528 |
// then if it were rotated by quaternion 'quat'. |
|
529 |
// No it is not so simple as the quats need to be the same - imagine a 4x4x4 cube where the two |
|
530 |
// middle squares get interchanged. No visible difference! |
|
531 |
// |
|
532 |
// So: this is true iff the cubit |
|
533 |
// a) is a corner or edge and the quaternions are the same |
|
534 |
// b) is inside one of the faces and after rotations by both quats it ends up on the same face. |
|
535 |
|
|
536 |
boolean thereIsVisibleDifference(Cubit cubit, int quatIndex) |
|
537 |
{ |
|
538 |
if ( cubit.mQuatIndex == quatIndex ) return false; |
|
539 |
|
|
540 |
int belongsToHowManyFaces = 0; |
|
541 |
int bitmap = (1<<(getNumLayers()-1)) + 1; |
|
542 |
|
|
543 |
for(int i = 0; i< NUM_AXIS; i++) |
|
544 |
{ |
|
545 |
if( (cubit.mRotationRow[i] & bitmap) != 0 ) belongsToHowManyFaces++; |
|
546 |
} |
|
547 |
|
|
548 |
switch(belongsToHowManyFaces) |
|
549 |
{ |
|
550 |
case 0 : return false; // 'inside' cubit that does not lie on any face |
|
551 |
case 1 : // cubit that lies inside one of the faces |
|
552 |
float[] orig = cubit.getOrigPosition(); |
|
553 |
Static4D quat1 = QUATS[quatIndex]; |
|
554 |
Static4D quat2 = QUATS[cubit.mQuatIndex]; |
|
555 |
|
|
556 |
Static4D cubitCenter = new Static4D( orig[0], orig[1], orig[2], 0); // not used for bandaged objects, |
|
557 |
Static4D rotated1 = QuatHelper.rotateVectorByQuat( cubitCenter, quat1 ); // only check the first position |
|
558 |
Static4D rotated2 = QuatHelper.rotateVectorByQuat( cubitCenter, quat2 ); |
|
559 |
|
|
560 |
rotated1.get(mTmp1, 0, 0, 0); |
|
561 |
rotated2.get(mTmp2, 0, 0, 0); |
|
562 |
|
|
563 |
for(int i = 0; i< NUM_AXIS; i++) |
|
564 |
{ |
|
565 |
if( (computeRow(mTmp1,i) & computeRow(mTmp2,i) & bitmap) != 0 ) return false; |
|
566 |
} |
|
567 |
return true; |
|
568 |
|
|
569 |
default: return true; // edge or corner |
|
570 |
} |
|
571 |
} |
|
572 |
|
|
573 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
574 |
// create StickerCoord and FaceTransform data structures |
|
575 |
|
|
576 |
void createFaceDataStructures(double[][][] verts, int[][][] indices) |
|
577 |
{ |
|
578 |
int numCubitTypes = verts.length; |
|
579 |
FactoryCubit factory = FactoryCubit.getInstance(); |
|
580 |
factory.clear(); |
|
581 |
|
|
582 |
for(int cubit=0; cubit<numCubitTypes; cubit++) |
|
583 |
{ |
|
584 |
double[][] vertices = verts[cubit]; |
|
585 |
int[][] vertIndices = indices[cubit]; |
|
586 |
factory.createNewFaceTransform(vertices,vertIndices); |
|
587 |
} |
|
588 |
|
|
589 |
factory.printFaceTransform(); |
|
590 |
factory.printStickerCoords(); |
|
591 |
} |
|
592 |
|
|
593 | 668 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
594 | 669 |
|
595 | 670 |
public int getCubitFaceColorIndex(int cubit, int face) |
... | ... | |
1013 | 1088 |
abstract int getNumCubitVariants(int numLayers); |
1014 | 1089 |
abstract Static4D getQuat(int cubit, int numLayers); |
1015 | 1090 |
abstract ObjectShape getObjectShape(int cubit, int numLayers); |
1091 |
abstract int[] getSolvedQuats(int cubit, int numLayers); |
|
1016 | 1092 |
|
1017 | 1093 |
public abstract Static3D[] getRotationAxis(); |
1018 |
public abstract boolean isSolved(); |
|
1019 | 1094 |
public abstract int[] getBasicAngle(); |
1020 | 1095 |
public abstract void randomizeNewScramble(int[][] scramble, Random rnd, int curScramble, int totScrambles); |
1021 | 1096 |
public abstract int getObjectName(int numLayers); |
src/main/java/org/distorted/objects/TwistyPyraminx.java | ||
---|---|---|
135 | 135 |
super(size, size, quat, texture, mesh, effects, moves, ObjectList.PYRA, res, scrWidth); |
136 | 136 |
} |
137 | 137 |
|
138 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
139 |
|
|
140 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
141 |
{ |
|
142 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
143 |
return status<0 ? null : buildSolvedQuats(MovementPyraminx.FACE_AXIS[status],QUATS); |
|
144 |
} |
|
145 |
|
|
138 | 146 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
139 | 147 |
|
140 | 148 |
private float[] getRowChances(int numLayers) |
... | ... | |
441 | 449 |
} |
442 | 450 |
} |
443 | 451 |
|
444 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
445 |
|
|
446 |
public boolean isSolved() |
|
447 |
{ |
|
448 |
int index = CUBITS[0].mQuatIndex; |
|
449 |
|
|
450 |
for(int i=1; i<NUM_CUBITS; i++) |
|
451 |
{ |
|
452 |
if( thereIsVisibleDifference(CUBITS[i], index) ) return false; |
|
453 |
} |
|
454 |
|
|
455 |
return true; |
|
456 |
} |
|
457 |
|
|
458 | 452 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
459 | 453 |
|
460 | 454 |
public int getObjectName(int numLayers) |
src/main/java/org/distorted/objects/TwistyRedi.java | ||
---|---|---|
213 | 213 |
super(size, size, quat, texture, mesh, effects, moves, ObjectList.REDI, res, scrWidth); |
214 | 214 |
} |
215 | 215 |
|
216 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
217 |
|
|
218 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
219 |
{ |
|
220 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
221 |
return status<0 ? null : buildSolvedQuats(MovementRedi.FACE_AXIS[status],QUATS); |
|
222 |
} |
|
223 |
|
|
216 | 224 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
217 | 225 |
|
218 | 226 |
float getScreenRatio() |
... | ... | |
478 | 486 |
} |
479 | 487 |
} |
480 | 488 |
|
481 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
482 |
// The Redi is solved if and only if all cubits are rotated with the same quat. |
|
483 |
|
|
484 |
public boolean isSolved() |
|
485 |
{ |
|
486 |
int q = CUBITS[0].mQuatIndex; |
|
487 |
|
|
488 |
return ( CUBITS[ 1].mQuatIndex == q && |
|
489 |
CUBITS[ 2].mQuatIndex == q && |
|
490 |
CUBITS[ 3].mQuatIndex == q && |
|
491 |
CUBITS[ 4].mQuatIndex == q && |
|
492 |
CUBITS[ 5].mQuatIndex == q && |
|
493 |
CUBITS[ 6].mQuatIndex == q && |
|
494 |
CUBITS[ 7].mQuatIndex == q && |
|
495 |
CUBITS[ 8].mQuatIndex == q && |
|
496 |
CUBITS[ 9].mQuatIndex == q && |
|
497 |
CUBITS[10].mQuatIndex == q && |
|
498 |
CUBITS[11].mQuatIndex == q && |
|
499 |
CUBITS[12].mQuatIndex == q && |
|
500 |
CUBITS[13].mQuatIndex == q && |
|
501 |
CUBITS[14].mQuatIndex == q && |
|
502 |
CUBITS[15].mQuatIndex == q && |
|
503 |
CUBITS[16].mQuatIndex == q && |
|
504 |
CUBITS[17].mQuatIndex == q && |
|
505 |
CUBITS[18].mQuatIndex == q && |
|
506 |
CUBITS[19].mQuatIndex == q ); |
|
507 |
} |
|
508 |
|
|
509 | 489 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
510 | 490 |
|
511 | 491 |
public int getObjectName(int numLayers) |
src/main/java/org/distorted/objects/TwistyRex.java | ||
---|---|---|
160 | 160 |
super(size, size, quat, texture, mesh, effects, moves, ObjectList.REX, res, scrWidth); |
161 | 161 |
} |
162 | 162 |
|
163 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
164 |
|
|
165 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
166 |
{ |
|
167 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
168 |
return status<0 ? null : buildSolvedQuats(MovementRex.FACE_AXIS[status],QUATS); |
|
169 |
} |
|
170 |
|
|
163 | 171 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
164 | 172 |
|
165 | 173 |
float getScreenRatio() |
... | ... | |
487 | 495 |
} |
488 | 496 |
} |
489 | 497 |
|
490 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
491 |
// The Rex is solved if and only if: |
|
492 |
// |
|
493 |
// 1) all 12 of its edge cubits are rotated with the same quat |
|
494 |
// 2) all its face & corner cubits are rotated with the same quat like the edge ones, |
|
495 |
// and optionally they also might be upside down. |
|
496 |
// |
|
497 |
// i.e. |
|
498 |
// corners ( 0, 1, 2, 3, 4, 5, 6, 7) and faces (24,25) - might be extra QUAT[1] |
|
499 |
// corners ( 8, 9,10,11,12,13,14,15) and faces (26,27) - might be extra QUAT[2] |
|
500 |
// corners (16,17,18,19,20,21,22,23) and faces (28,29) - might be extra QUAT[3] |
|
501 |
|
|
502 |
public boolean isSolved() |
|
503 |
{ |
|
504 |
int q1,q = CUBITS[30].mQuatIndex; |
|
505 |
|
|
506 |
for(int i=31; i<42; i++) |
|
507 |
{ |
|
508 |
if( CUBITS[i].mQuatIndex != q) return false; |
|
509 |
} |
|
510 |
|
|
511 |
q1 = mulQuat(q,1); |
|
512 |
|
|
513 |
for(int i=0; i<8; i++) |
|
514 |
{ |
|
515 |
if( CUBITS[i].mQuatIndex != q && CUBITS[i].mQuatIndex != q1 ) return false; |
|
516 |
} |
|
517 |
|
|
518 |
if( CUBITS[24].mQuatIndex != q && CUBITS[24].mQuatIndex != q1 ) return false; |
|
519 |
if( CUBITS[25].mQuatIndex != q && CUBITS[25].mQuatIndex != q1 ) return false; |
|
520 |
|
|
521 |
q1 = mulQuat(q,2); |
|
522 |
|
|
523 |
for(int i=8; i<16; i++) |
|
524 |
{ |
|
525 |
if( CUBITS[i].mQuatIndex != q && CUBITS[i].mQuatIndex != q1 ) return false; |
|
526 |
} |
|
527 |
|
|
528 |
if( CUBITS[26].mQuatIndex != q && CUBITS[26].mQuatIndex != q1 ) return false; |
|
529 |
if( CUBITS[27].mQuatIndex != q && CUBITS[27].mQuatIndex != q1 ) return false; |
|
530 |
|
|
531 |
q1 = mulQuat(q,3); |
|
532 |
|
|
533 |
for(int i=16; i<24; i++) |
|
534 |
{ |
|
535 |
if( CUBITS[i].mQuatIndex != q && CUBITS[i].mQuatIndex != q1 ) return false; |
|
536 |
} |
|
537 |
|
|
538 |
if( CUBITS[28].mQuatIndex != q && CUBITS[28].mQuatIndex != q1 ) return false; |
|
539 |
if( CUBITS[29].mQuatIndex != q && CUBITS[29].mQuatIndex != q1 ) return false; |
|
540 |
|
|
541 |
return true; |
|
542 |
} |
|
543 |
|
|
544 | 498 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
545 | 499 |
|
546 | 500 |
public int getObjectName(int numLayers) |
src/main/java/org/distorted/objects/TwistySkewb.java | ||
---|---|---|
197 | 197 |
super(size, 2*size-2, quat, texture, mesh, effects, moves, ObjectList.SKEW, res, scrWidth); |
198 | 198 |
} |
199 | 199 |
|
200 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
201 |
|
|
202 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
203 |
{ |
|
204 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
205 |
return status<0 ? null : buildSolvedQuats(MovementSkewb.FACE_AXIS[status],QUATS); |
|
206 |
} |
|
207 |
|
|
200 | 208 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
201 | 209 |
|
202 | 210 |
private int getNumCorners() |
... | ... | |
605 | 613 |
} |
606 | 614 |
} |
607 | 615 |
|
608 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
609 |
// The Skewb is solved if and only if: |
|
610 |
// |
|
611 |
// 1) all of its corner and edge cubits are rotated with the same quat |
|
612 |
// 2) all its face cubits are rotated with the same quat like the corner ones, |
|
613 |
// and optionally they also might be upside down. |
|
614 |
// |
|
615 |
// i.e. |
|
616 |
// cubits [ 8] and [ 9] - might be extra QUAT[1] |
|
617 |
// cubits [10] and [11] - might be extra QUAT[2] |
|
618 |
// cubits [12] and [13] - might be extra QUAT[3] |
|
619 |
|
|
620 |
public boolean isSolved() |
|
621 |
{ |
|
622 |
int q = CUBITS[0].mQuatIndex; |
|
623 |
|
|
624 |
int numLayers = getNumLayers(); |
|
625 |
int numCorners = getNumCorners(); |
|
626 |
int numEdges = getNumEdges(numLayers); |
|
627 |
int cornersAndEdges= numCorners + numEdges; |
|
628 |
int centersPerFace = getNumCentersPerFace(numLayers); |
|
629 |
int cubit, q1=q; |
|
630 |
|
|
631 |
for(cubit=0; cubit<cornersAndEdges; cubit++) |
|
632 |
{ |
|
633 |
if( CUBITS[cubit].mQuatIndex != q ) return false; |
|
634 |
} |
|
635 |
|
|
636 |
for(int face=0; face<6; face++) |
|
637 |
{ |
|
638 |
if( face%2==0 ) q1 = mulQuat(q, (face/2)+1); |
|
639 |
|
|
640 |
for(int center=0; center<centersPerFace; center++) |
|
641 |
{ |
|
642 |
if( CUBITS[cubit].mQuatIndex != q && CUBITS[cubit].mQuatIndex != q1 ) return false; |
|
643 |
cubit++; |
|
644 |
} |
|
645 |
} |
|
646 |
|
|
647 |
return true; |
|
648 |
} |
|
649 |
|
|
650 | 616 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
651 | 617 |
|
652 | 618 |
public int getObjectName(int numLayers) |
src/main/java/org/distorted/objects/TwistySquare1.java | ||
---|---|---|
176 | 176 |
mCornerQuat = new int[8]; |
177 | 177 |
} |
178 | 178 |
|
179 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
180 |
|
|
181 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
182 |
{ |
|
183 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
184 |
return status<0 ? null : buildSolvedQuats(MovementSquare.FACE_AXIS[status],QUATS); |
|
185 |
} |
|
186 |
|
|
179 | 187 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
180 | 188 |
|
181 | 189 |
ObjectShape getObjectShape(int cubit, int numLayers) |
... | ... | |
513 | 521 |
} |
514 | 522 |
} |
515 | 523 |
|
516 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
517 |
|
|
518 |
public boolean isSolved() |
|
519 |
{ |
|
520 |
int index = CUBITS[0].mQuatIndex; |
|
521 |
|
|
522 |
for(int i=1; i<NUM_CUBITS; i++) |
|
523 |
{ |
|
524 |
if( CUBITS[i].mQuatIndex != index ) return false; |
|
525 |
} |
|
526 |
|
|
527 |
return true; |
|
528 |
} |
|
529 |
|
|
530 | 524 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
531 | 525 |
|
532 | 526 |
public int getObjectName(int numLayers) |
src/main/java/org/distorted/objects/TwistySquare2.java | ||
---|---|---|
181 | 181 |
super(size, quat, texture, mesh, effects, moves, ObjectList.SQU2, res, scrWidth); |
182 | 182 |
} |
183 | 183 |
|
184 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
185 |
// Square-2 is solved iff |
|
186 |
// a) all of its cubits are rotated with the same quat |
|
187 |
// b) its two 'middle' cubits are rotated with the same quat, the 6 'front' and 6 'back' |
|
188 |
// edges and corners with this quat multiplied by QUATS[18] (i.e. those are upside down) |
|
189 |
// and all the 12 left and right edges and corners also with the same quat multiplied by |
|
190 |
// QUATS[12] - i.e. also upside down. |
|
191 |
|
|
192 |
private static final int[] S18 = new int[] {18}; |
|
193 |
private static final int[] S12 = new int[] {12}; |
|
194 |
|
|
195 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
196 |
{ |
|
197 |
switch(cubit) |
|
198 |
{ |
|
199 |
case 0: case 1: return null; |
|
200 |
case 2: case 4: case 6: case 8: |
|
201 |
case 10: case 12: case 14: case 16: |
|
202 |
case 19: case 21: case 23: case 25: return S18; |
|
203 |
case 3: case 5: case 7: case 9: |
|
204 |
case 11: case 13: case 15: case 17: |
|
205 |
case 18: case 20: case 22: case 24: return S12; |
|
206 |
} |
|
207 |
|
|
208 |
return null; |
|
209 |
} |
|
210 |
|
|
184 | 211 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
185 | 212 |
|
186 | 213 |
ObjectShape getObjectShape(int cubit, int numLayers) |
... | ... | |
327 | 354 |
} |
328 | 355 |
} |
329 | 356 |
|
330 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
331 |
// Square-2 is solved iff |
|
332 |
// a) all of its cubits are rotated with the same quat |
|
333 |
// b) its two 'middle' cubits are rotated with the same quat, the 6 'front' and 6 'back' |
|
334 |
// edges and corners with this quat multiplied by QUATS[18] (i.e. those are upside down) |
|
335 |
// and all the 12 left and right edges and corners also with the same quat multiplied by |
|
336 |
// QUATS[12] - i.e. also upside down. |
|
337 |
|
|
338 |
public boolean isSolved() |
|
339 |
{ |
|
340 |
int index = CUBITS[0].mQuatIndex; |
|
341 |
|
|
342 |
if( CUBITS[1].mQuatIndex!=index ) return false; |
|
343 |
|
|
344 |
int indexX = mulQuat(index,12); // QUATS[12] = 180deg (1,0,0) |
|
345 |
int indexZ = mulQuat(index,18); // QUATS[18] = 180deg (0,0,1) |
|
346 |
|
|
347 |
for(int i=2; i<18; i+=2) |
|
348 |
{ |
|
349 |
if( CUBITS[i].mQuatIndex != index && CUBITS[i].mQuatIndex != indexZ ) return false; |
|
350 |
} |
|
351 |
for(int i=3; i<18; i+=2) |
|
352 |
{ |
|
353 |
if( CUBITS[i].mQuatIndex != index && CUBITS[i].mQuatIndex != indexX ) return false; |
|
354 |
} |
|
355 |
for(int i=18; i<NUM_CUBITS; i+=2) |
|
356 |
{ |
|
357 |
if( CUBITS[i].mQuatIndex != index && CUBITS[i].mQuatIndex != indexX ) return false; |
|
358 |
} |
|
359 |
for(int i=19; i<NUM_CUBITS; i+=2) |
|
360 |
{ |
|
361 |
if( CUBITS[i].mQuatIndex != index && CUBITS[i].mQuatIndex != indexZ ) return false; |
|
362 |
} |
|
363 |
|
|
364 |
return true; |
|
365 |
} |
|
366 |
|
|
367 | 357 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
368 | 358 |
|
369 | 359 |
public int getObjectName(int numLayers) |
src/main/java/org/distorted/objects/TwistyUltimate.java | ||
---|---|---|
240 | 240 |
super(size, size, quat, texture, mesh, effects, moves, ObjectList.ULTI, res, scrWidth); |
241 | 241 |
} |
242 | 242 |
|
243 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
244 |
|
|
245 |
int[] getSolvedQuats(int cubit, int numLayers) |
|
246 |
{ |
|
247 |
int status = retCubitSolvedStatus(cubit,numLayers); |
|
248 |
return status<0 ? null : buildSolvedQuats(MovementUltimate.FACE_AXIS[status],QUATS); |
|
249 |
} |
|
250 |
|
|
243 | 251 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
244 | 252 |
|
245 | 253 |
ObjectShape getObjectShape(int cubit, int numLayers) |
... | ... | |
422 | 430 |
} |
423 | 431 |
} |
424 | 432 |
|
425 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
426 |
|
|
427 |
public boolean isSolved() |
|
428 |
{ |
|
429 |
int index = CUBITS[0].mQuatIndex; |
|
430 |
|
|
431 |
for(int i=1; i<NUM_CUBITS; i++) |
|
432 |
{ |
|
433 |
if( CUBITS[i].mQuatIndex != index ) return false; |
|
434 |
} |
|
435 |
|
|
436 |
return true; |
|
437 |
} |
|
438 |
|
|
439 | 433 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
440 | 434 |
|
441 | 435 |
public int getObjectName(int numLayers) |
Also available in: Unified diff
Standarize the 'isSolved()' method: now all objects, except one (Dino4) have a standard isSolved().
This incidentally also fixes detection of the solved state in case of Diamond4, i.e. a Master FTO.