Project

General

Profile

Download (21.5 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / objects / TwistySkewb.java @ 323b217c

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.objects;
21

    
22
import android.content.res.Resources;
23
import android.graphics.Canvas;
24
import android.graphics.Paint;
25

    
26
import org.distorted.library.effect.MatrixEffect;
27
import org.distorted.library.effect.MatrixEffectQuaternion;
28
import org.distorted.library.effect.MatrixEffectScale;
29
import org.distorted.library.main.DistortedEffects;
30
import org.distorted.library.main.DistortedTexture;
31
import org.distorted.library.mesh.MeshBase;
32
import org.distorted.library.mesh.MeshSquare;
33
import org.distorted.library.type.Static3D;
34
import org.distorted.library.type.Static4D;
35
import org.distorted.main.R;
36
import org.distorted.main.RubikSurfaceView;
37

    
38
import java.util.Random;
39

    
40
import static org.distorted.effects.scramble.ScrambleEffect.START_AXIS;
41

    
42
///////////////////////////////////////////////////////////////////////////////////////////////////
43

    
44
public class TwistySkewb extends TwistyObject
45
{
46
  private static final int FACES_PER_CUBIT =6;
47

    
48
  // the four rotation axis of a RubikSkewb. Must be normalized.
49
  static final Static3D[] ROT_AXIS = new Static3D[]
50
         {
51
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
52
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
53
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
54
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
55
         };
56

    
57
  private static final int[] FACE_COLORS = new int[]
58
         {
59
           COLOR_YELLOW, COLOR_WHITE,
60
           COLOR_BLUE  , COLOR_GREEN,
61
           COLOR_RED   , COLOR_ORANGE
62
         };
63

    
64
  // All legal rotation quats of a RubikSkewb
65
  private static final Static4D[] QUATS = new Static4D[]
66
         {
67
           new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
68
           new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
69
           new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
70
           new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
71

    
72
           new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
73
           new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
74
           new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
75
           new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
76
           new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
77
           new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
78
           new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
79
           new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
80
         };
81

    
82
  private static final int[][] mCornerMap =
83
         {
84
           {  4, 2, 0, 18,18,18 },
85
           {  2, 5, 0, 18,18,18 },
86
           {  3, 4, 0, 18,18,18 },
87
           {  5, 3, 0, 18,18,18 },
88
           {  1, 2, 4, 18,18,18 },
89
           {  5, 2, 1, 18,18,18 },
90
           {  4, 3, 1, 18,18,18 },
91
           {  1, 3, 5, 18,18,18 },
92
         };
93

    
94
  private static final int[][] mEdgeMap =
95
         {
96
           { 10, 8, 18,18,18,18 },
97
           {  6,10, 18,18,18,18 },
98
           { 10, 9, 18,18,18,18 },
99
           {  7,10, 18,18,18,18 },
100
           {  8, 6, 18,18,18,18 },
101
           {  9, 6, 18,18,18,18 },
102
           {  9, 7, 18,18,18,18 },
103
           {  8, 7, 18,18,18,18 },
104
           { 11, 8, 18,18,18,18 },
105
           {  6,11, 18,18,18,18 },
106
           { 11, 9, 18,18,18,18 },
107
           {  7,11, 18,18,18,18 }
108
         };
109

    
110
  private static final int[][] mCenterMap =
111
         {
112
           { 12, 18,18,18,18,18 },
113
           { 13, 18,18,18,18,18 },
114
           { 14, 18,18,18,18,18 },
115
           { 15, 18,18,18,18,18 },
116
           { 16, 18,18,18,18,18 },
117
           { 17, 18,18,18,18,18 },
118
         };
119

    
120
  private static MeshBase mCornerMesh, mFaceMesh, mEdgeMesh;
121

    
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123

    
124
  TwistySkewb(int size, Static4D quat, DistortedTexture texture,
125
              MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
126
    {
127
    super(size, 2*size-2, 60, quat, texture, mesh, effects, moves, ObjectList.SKEW, res, scrWidth);
128
    }
129

    
130
///////////////////////////////////////////////////////////////////////////////////////////////////
131

    
132
  private int getNumCorners()
133
    {
134
    return 8;
135
    }
136

    
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138

    
139
  private int getNumEdges(int layers)
140
    {
141
    return (layers-2)*12;
142
    }
143

    
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145

    
146
  private int getNumCentersPerFace(int layers)
147
    {
148
    return ((layers-2)*(layers-2) + (layers-1)*(layers-1));
149
    }
150

    
151
///////////////////////////////////////////////////////////////////////////////////////////////////
152

    
153
  float getScreenRatio()
154
    {
155
    return 1.0f;
156
    }
157

    
158
///////////////////////////////////////////////////////////////////////////////////////////////////
159

    
160
  Static4D[] getQuats()
161
    {
162
    return QUATS;
163
    }
164

    
165
///////////////////////////////////////////////////////////////////////////////////////////////////
166

    
167
  int getNumFaces()
168
    {
169
    return FACE_COLORS.length;
170
    }
171

    
172
///////////////////////////////////////////////////////////////////////////////////////////////////
173

    
174
  boolean shouldResetTextureMaps()
175
    {
176
    return false;
177
    }
178

    
179
///////////////////////////////////////////////////////////////////////////////////////////////////
180

    
181
  int getNumStickerTypes()
182
    {
183
    return 3;
184
    }
185

    
186
///////////////////////////////////////////////////////////////////////////////////////////////////
187

    
188
  float[] getCuts(int numLayers)
189
    {
190
    float[] cuts = new float[numLayers-1];
191

    
192
    switch(numLayers)
193
      {
194
      case 2: cuts[0] = 0;
195
              break;
196
      case 3: cuts[0] = -SQ3/12;
197
              cuts[1] = +SQ3/12;
198
              break;
199
      case 4: cuts[0] = -SQ3/9;
200
              cuts[1] = 0;
201
              cuts[2] = +SQ3/9;
202
              break;
203
      }
204
    return cuts;
205
    }
206

    
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208

    
209
  int getNumCubitFaces()
210
    {
211
    return FACES_PER_CUBIT;
212
    }
213

    
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215

    
216
  Static3D[] getCubitPositions(int numLayers)
217
    {
218
    final float DIST_CORNER = (numLayers-1)*0.50f;
219
    final float DIST_EDGE   = (numLayers-1)*0.50f;
220
    final float DIST_CENTER = (numLayers-1)*0.50f;
221

    
222
    final int numCorners = getNumCorners();
223
    final int numEdges   = getNumEdges(numLayers);
224
    final int numCenters = 6*getNumCentersPerFace(numLayers);
225

    
226
    final Static3D[] CENTERS = new Static3D[numCorners+numEdges+numCenters];
227

    
228
    /// CORNERS //////////////////////////////////////////////
229

    
230
    CENTERS[0] = new Static3D( DIST_CORNER, DIST_CORNER, DIST_CORNER );
231
    CENTERS[1] = new Static3D( DIST_CORNER, DIST_CORNER,-DIST_CORNER );
232
    CENTERS[2] = new Static3D( DIST_CORNER,-DIST_CORNER, DIST_CORNER );
233
    CENTERS[3] = new Static3D( DIST_CORNER,-DIST_CORNER,-DIST_CORNER );
234
    CENTERS[4] = new Static3D(-DIST_CORNER, DIST_CORNER, DIST_CORNER );
235
    CENTERS[5] = new Static3D(-DIST_CORNER, DIST_CORNER,-DIST_CORNER );
236
    CENTERS[6] = new Static3D(-DIST_CORNER,-DIST_CORNER, DIST_CORNER );
237
    CENTERS[7] = new Static3D(-DIST_CORNER,-DIST_CORNER,-DIST_CORNER );
238

    
239
    /// EDGES ///////////////////////////////////////////////
240

    
241
    final float[][]  edgeTable =
242
        {
243
            {0,+DIST_EDGE,+DIST_EDGE},
244
            {+DIST_EDGE,0,+DIST_EDGE},
245
            {0,-DIST_EDGE,+DIST_EDGE},
246
            {-DIST_EDGE,0,+DIST_EDGE},
247
            {+DIST_EDGE,+DIST_EDGE,0},
248
            {+DIST_EDGE,-DIST_EDGE,0},
249
            {-DIST_EDGE,-DIST_EDGE,0},
250
            {-DIST_EDGE,+DIST_EDGE,0},
251
            {0,+DIST_EDGE,-DIST_EDGE},
252
            {+DIST_EDGE,0,-DIST_EDGE},
253
            {0,-DIST_EDGE,-DIST_EDGE},
254
            {-DIST_EDGE,0,-DIST_EDGE}
255
        };
256

    
257
    int index=8;
258

    
259
    for (float[] edges : edgeTable)
260
      {
261
      float c = (3-numLayers)*0.5f;
262

    
263
      for (int j=0; j<numLayers-2; j++, c+=1.0f, index++)
264
        {
265
        CENTERS[index] = new Static3D( edges[0]==0 ? c : edges[0] ,
266
                                       edges[1]==0 ? c : edges[1] ,
267
                                       edges[2]==0 ? c : edges[2] );
268
        }
269
      }
270

    
271
    /// CENTERS //////////////////////////////////////////////
272

    
273
    final float X= -1000.0f;
274
    final float Y= -1001.0f;
275

    
276
    final float[][]  centerTable =
277
        {
278
            {+DIST_CENTER,X,Y},
279
            {-DIST_CENTER,X,Y},
280
            {X,+DIST_CENTER,Y},
281
            {X,-DIST_CENTER,Y},
282
            {X,Y,+DIST_CENTER},
283
            {X,Y,-DIST_CENTER}
284
        };
285

    
286
    float x,y, cen0, cen1, cen2;
287

    
288
    for( float[] centers : centerTable )
289
      {
290
      x = (2-numLayers)*0.5f;
291

    
292
      for(int i=0; i<numLayers-1; i++, x+=1.0f)
293
        {
294
        y = (2-numLayers)*0.5f;
295

    
296
        for(int j=0; j<numLayers-1; j++, y+=1.0f, index++)
297
          {
298
               if( centers[0]==Y ) cen0 = y;
299
          else if( centers[0]==X ) cen0 = x;
300
          else                     cen0 = centers[0];
301

    
302
               if( centers[1]==Y ) cen1 = y;
303
          else if( centers[1]==X ) cen1 = x;
304
          else                     cen1 = centers[1];
305

    
306
               if( centers[2]==Y ) cen2 = y;
307
          else if( centers[2]==X ) cen2 = x;
308
          else                     cen2 = centers[2];
309

    
310
          CENTERS[index] = new Static3D(cen0,cen1,cen2);
311
          }
312
        }
313

    
314
      x = (3-numLayers)*0.5f;
315

    
316
      for(int i=0; i<numLayers-2; i++, x+=1.0f)
317
        {
318
        y = (3-numLayers)*0.5f;
319

    
320
        for(int j=0; j<numLayers-2; j++, y+=1.0f, index++)
321
          {
322
               if( centers[0]==Y ) cen0 = y;
323
          else if( centers[0]==X ) cen0 = x;
324
          else                     cen0 = centers[0];
325

    
326
               if( centers[1]==Y ) cen1 = y;
327
          else if( centers[1]==X ) cen1 = x;
328
          else                     cen1 = centers[1];
329

    
330
               if( centers[2]==Y ) cen2 = y;
331
          else if( centers[2]==X ) cen2 = x;
332
          else                     cen2 = centers[2];
333

    
334
          CENTERS[index] = new Static3D(cen0,cen1,cen2);
335
          }
336
        }
337
      }
338

    
339
    return CENTERS;
340
    }
341

    
342
///////////////////////////////////////////////////////////////////////////////////////////////////
343

    
344
  private Static4D getQuat(int cubit, int numLayers)
345
    {
346
    int numCorners = getNumCorners();
347
    int numEdges   = getNumEdges(numLayers);
348

    
349
    if( cubit<numCorners )
350
      {
351
      switch(cubit)
352
        {
353
        case  0: return QUATS[0];                          //  unit quat
354
        case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
355
        case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
356
        case  3: return QUATS[1];                          // 180 along X
357
        case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
358
        case  5: return QUATS[2];                          // 180 along Y
359
        case  6: return QUATS[3];                          // 180 along Z
360
        case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
361
        }
362
      }
363
    else if( cubit<numCorners+numEdges )
364
      {
365
      int edge = (cubit-numCorners)/(numLayers-2);
366

    
367
      switch(edge)
368
        {
369
        case  0: return QUATS[ 0];
370
        case  1: return QUATS[ 5];
371
        case  2: return QUATS[ 3];
372
        case  3: return QUATS[11];
373
        case  4: return QUATS[ 4];
374
        case  5: return QUATS[ 7];
375
        case  6: return QUATS[ 9];
376
        case  7: return QUATS[10];
377
        case  8: return QUATS[ 2];
378
        case  9: return QUATS[ 8];
379
        case 10: return QUATS[ 1];
380
        case 11: return QUATS[ 6];
381
        }
382
      }
383
    else
384
      {
385
      int center = (cubit-numCorners-numEdges)/getNumCentersPerFace(numLayers);
386

    
387
      switch(center)
388
        {
389
        case 0: return new Static4D(0,-SQ2/2,0,SQ2/2);    // -90 along Y
390
        case 1: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
391
        case 2: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
392
        case 3: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
393
        case 4: return QUATS[0];                          //  unit quaternion
394
        case 5: return QUATS[1];                          // 180 along X
395
        }
396
      }
397

    
398
    return null;
399
    }
400

    
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402

    
403
  MeshBase createCubitMesh(int cubit)
404
    {
405
    MeshBase mesh;
406

    
407
    int numLayers  = getNumLayers();
408
    int numCorners = getNumCorners();
409
    int numEdges   = getNumEdges(numLayers);
410

    
411
    if( cubit<numCorners )
412
      {
413
      if( mCornerMesh==null ) mCornerMesh = FactoryCubit.getInstance().createSkewbCornerMesh();
414
      mesh = mCornerMesh.copy(true);
415
      }
416
    else if( cubit<numCorners+numEdges )
417
      {
418
      if( mEdgeMesh==null )
419
        {
420
        mEdgeMesh = FactoryCubit.getInstance().createDinoMesh();
421
        MatrixEffect effect = new MatrixEffectScale(1.0f/3);
422
        mEdgeMesh.apply(effect,-1,0);
423
        mEdgeMesh.addEmptyTexComponent();
424
        mEdgeMesh.addEmptyTexComponent();
425
        }
426
      mesh = mEdgeMesh.copy(true);
427
      }
428
    else
429
      {
430
      if( mFaceMesh==null ) mFaceMesh = FactoryCubit.getInstance().createSkewbFaceMesh();
431
      mesh = mFaceMesh.copy(true);
432
      }
433

    
434
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit,numLayers), new Static3D(0,0,0) );
435
    mesh.apply(quat,0xffffffff,0);
436

    
437
    return mesh;
438
    }
439

    
440
///////////////////////////////////////////////////////////////////////////////////////////////////
441

    
442
  int getFaceColor(int cubit, int cubitface, int numLayers)
443
    {
444
    int numCorners = getNumCorners();
445
    int numEdges   = getNumEdges(numLayers);
446

    
447
    if( cubit<numCorners )
448
      {
449
      return mCornerMap[cubit][cubitface];
450
      }
451
    else if( cubit<numCorners+numEdges )
452
      {
453
      int edge = (cubit-numCorners)/(numLayers-2);
454
      return mEdgeMap[edge][cubitface];
455
      }
456
    else
457
      {
458
      int center = (cubit-numCorners-numEdges)/getNumCentersPerFace(numLayers);
459
      return mCenterMap[center][cubitface];
460
      }
461
    }
462

    
463
///////////////////////////////////////////////////////////////////////////////////////////////////
464

    
465
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
466
    {
467
    int COLORS = FACE_COLORS.length;
468
    float R,S;
469
    float[] vertices;
470

    
471
    if( face<COLORS )
472
      {
473
      float E = 0.5f;
474
      R = 0.023f;
475
      S = 0.035f;
476
      vertices = new float[] { -E+E/4,E/4, E/4,-E+E/4, E/4,E/4};
477
      }
478
    else if( face<2*COLORS )
479
      {
480
      float E = 0.5f;
481
      R = 0.025f;
482
      S = 0.05f;
483
      vertices = new float[] { -E,E/3, 0,-2*E/3, +E,E/3 };
484
      }
485
    else
486
      {
487
      float E = SQ2/4;
488
      R = 0.055f;
489
      S = 0.035f;
490
      vertices = new float[] { -E,-E, +E,-E, +E,+E, -E,+E };
491
      }
492

    
493
    FactorySticker factory = FactorySticker.getInstance();
494
    factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[face%COLORS], R);
495
    }
496

    
497
///////////////////////////////////////////////////////////////////////////////////////////////////
498

    
499
  float returnMultiplier()
500
    {
501
    return 2.0f;
502
    }
503

    
504
///////////////////////////////////////////////////////////////////////////////////////////////////
505

    
506
  float[] getRowChances()
507
    {
508
    int numLayers = getNumLayers();
509
    float[] chances = new float[numLayers];
510

    
511
    switch(numLayers)
512
      {
513
      case 2: chances[0] = 0.5f;
514
              chances[1] = 1.0f;
515
              break;
516
      case 3: chances[0] = 0.5f;
517
              chances[1] = 0.5f;
518
              chances[2] = 1.0f;
519
              break;
520
      default:for(int i=0; i<numLayers; i++)
521
                {
522
                chances[i] = (float)(i+1)/numLayers;
523
                }
524
      }
525

    
526
    return chances;
527
    }
528

    
529
///////////////////////////////////////////////////////////////////////////////////////////////////
530
// PUBLIC API
531

    
532
  public Static3D[] getRotationAxis()
533
    {
534
    return ROT_AXIS;
535
    }
536

    
537
///////////////////////////////////////////////////////////////////////////////////////////////////
538

    
539
  public int getBasicAngle()
540
    {
541
    return 3;
542
    }
543

    
544
///////////////////////////////////////////////////////////////////////////////////////////////////
545

    
546
  public int randomizeNewRotAxis(Random rnd, int oldRotAxis)
547
    {
548
    int numAxis = ROTATION_AXIS.length;
549

    
550
    if( oldRotAxis == START_AXIS )
551
      {
552
      return rnd.nextInt(numAxis);
553
      }
554
    else
555
      {
556
      int newVector = rnd.nextInt(numAxis-1);
557
      return (newVector>=oldRotAxis ? newVector+1 : newVector);
558
      }
559
    }
560

    
561
///////////////////////////////////////////////////////////////////////////////////////////////////
562

    
563
  public int randomizeNewRow(Random rnd, int oldRotAxis, int oldRow, int newRotAxis)
564
    {
565
    float rowFloat = rnd.nextFloat();
566

    
567
    for(int row=0; row<mRowChances.length; row++)
568
      {
569
      if( rowFloat<=mRowChances[row] ) return row;
570
      }
571

    
572
    return 0;
573
    }
574

    
575
///////////////////////////////////////////////////////////////////////////////////////////////////
576
// remember about the double cover or unit quaternions!
577

    
578
  private int mulQuat(int q1, int q2)
579
    {
580
    Static4D result = RubikSurfaceView.quatMultiply(QUATS[q1],QUATS[q2]);
581

    
582
    float rX = result.get0();
583
    float rY = result.get1();
584
    float rZ = result.get2();
585
    float rW = result.get3();
586

    
587
    final float MAX_ERROR = 0.1f;
588
    float dX,dY,dZ,dW;
589

    
590
    for(int i=0; i<QUATS.length; i++)
591
      {
592
      dX = QUATS[i].get0() - rX;
593
      dY = QUATS[i].get1() - rY;
594
      dZ = QUATS[i].get2() - rZ;
595
      dW = QUATS[i].get3() - rW;
596

    
597
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
598
          dY<MAX_ERROR && dY>-MAX_ERROR &&
599
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
600
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
601

    
602
      dX = QUATS[i].get0() + rX;
603
      dY = QUATS[i].get1() + rY;
604
      dZ = QUATS[i].get2() + rZ;
605
      dW = QUATS[i].get3() + rW;
606

    
607
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
608
          dY<MAX_ERROR && dY>-MAX_ERROR &&
609
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
610
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
611
      }
612

    
613
    return -1;
614
    }
615

    
616
///////////////////////////////////////////////////////////////////////////////////////////////////
617
// The Skewb is solved if and only if:
618
//
619
// 1) all of its corner and edge cubits are rotated with the same quat
620
// 2) all its face cubits are rotated with the same quat like the corner ones,
621
//    and optionally they also might be upside down.
622
//
623
// i.e.
624
// cubits [ 8] and [ 9] - might be extra QUAT[1]
625
// cubits [10] and [11] - might be extra QUAT[2]
626
// cubits [12] and [13] - might be extra QUAT[3]
627

    
628
  public boolean isSolved()
629
    {
630
    int q = CUBITS[0].mQuatIndex;
631

    
632
    int numLayers      = getNumLayers();
633
    int numCorners     = getNumCorners();
634
    int numEdges       = getNumEdges(numLayers);
635
    int cornersAndEdges= numCorners + numEdges;
636
    int centersPerFace = getNumCentersPerFace(numLayers);
637
    int cubit, q1=q;
638

    
639
    for(cubit=0; cubit<cornersAndEdges; cubit++)
640
      {
641
      if( CUBITS[cubit].mQuatIndex != q ) return false;
642
      }
643

    
644
    for(int face=0; face<6; face++)
645
      {
646
      if( face%2==0 ) q1 = mulQuat(q, (face/2)+1);
647

    
648
      for(int center=0; center<centersPerFace; center++)
649
        {
650
        if( CUBITS[cubit].mQuatIndex != q && CUBITS[cubit].mQuatIndex != q1 ) return false;
651
        cubit++;
652
        }
653
      }
654

    
655
    return true;
656
    }
657

    
658
///////////////////////////////////////////////////////////////////////////////////////////////////
659
// only needed for solvers - there are no Skewb solvers ATM)
660

    
661
  public String retObjectString()
662
    {
663
    return "";
664
    }
665

    
666
///////////////////////////////////////////////////////////////////////////////////////////////////
667

    
668
  public int getObjectName(int numLayers)
669
    {
670
    switch(numLayers)
671
      {
672
      case 2: return R.string.skew2;
673
      case 3: return R.string.skew3;
674
      }
675
    return R.string.skew2;
676
    }
677

    
678
///////////////////////////////////////////////////////////////////////////////////////////////////
679

    
680
  public int getInventor(int numLayers)
681
    {
682
    switch(numLayers)
683
      {
684
      case 2: return R.string.skew2_inventor;
685
      case 3: return R.string.skew3_inventor;
686
      }
687
    return R.string.skew2_inventor;
688
    }
689

    
690
///////////////////////////////////////////////////////////////////////////////////////////////////
691

    
692
  public int getComplexity(int numLayers)
693
    {
694
    switch(numLayers)
695
      {
696
      case 2: return 5;
697
      case 3: return 9;
698
      }
699
    return 5;
700
    }
701
}
(28-28/28)