Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistySkewb.java @ d5ca9927

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.helpers.FactoryCubit;
27
import org.distorted.helpers.FactorySticker;
28
import org.distorted.library.effect.MatrixEffectQuaternion;
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

    
37
import java.util.Random;
38

    
39
///////////////////////////////////////////////////////////////////////////////////////////////////
40

    
41
public class TwistySkewb extends TwistyObject
42
{
43
  private static final int FACES_PER_CUBIT =6;
44

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

    
54
  private static final int[] BASIC_ANGLE = new int[] { 3,3,3,3 };
55

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

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

    
71
           new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
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
         };
80

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

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

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

    
119
  private static final double[][] VERTICES_CORNER = new double[][]
120
          {
121
              {-0.5f, 0.0f, 0.0f},
122
              { 0.0f,-0.5f, 0.0f},
123
              { 0.0f, 0.0f,-0.5f},
124
              {-0.5f,-0.5f,-0.5f},
125
              { 0.0f, 0.0f, 0.0f}
126
          };
127

    
128
  private static final int[][] VERT_INDEXES_CORNER = new int[][]
129
          {
130
              {0,1,4},
131
              {2,0,4},
132
              {1,2,4},
133
              {3,1,0},
134
              {3,2,1},
135
              {3,0,2}
136
          };
137

    
138
  private static final double[][] VERTICES_EDGE = new double[][]
139
          {
140
             {-0.5, 0.0, 0.0},
141
             { 0.5, 0.0, 0.0},
142
             { 0.0,-0.5, 0.0},
143
             { 0.0, 0.0,-0.5}
144
          };
145

    
146
  private static final int[][] VERT_INDEXES_EDGE = new int[][]
147
          {
148
             {2,1,0},   // counterclockwise!
149
             {3,0,1},
150
             {2,3,1},
151
             {3,2,0},
152
          };
153

    
154
  private static final double[][] VERTICES_FACE = new double[][]
155
          {
156
             {-0.5f, 0.0f, 0.0f },
157
             { 0.0f,-0.5f, 0.0f },
158
             { 0.5f, 0.0f, 0.0f },
159
             { 0.0f, 0.5f, 0.0f },
160
             { 0.0f, 0.0f,-0.5f }
161
          };
162

    
163
  private static final int[][] VERT_INDEXES_FACE = new int[][]
164
          {
165
             {0,1,2,3},
166
             {4,1,0},
167
             {4,2,1},
168
             {4,3,2},
169
             {4,0,3}
170
          };
171

    
172
  private static final float[][] STICKERS = new float[][]
173
          {
174
             { -0.5f, 0.25f, 0.25f,  -0.5f, 0.25f, 0.25f  },
175
             { -0.5f, 0.00f, 0.00f,  -0.5f, 0.50f, 0.0f, 0.0f, 0.5f }
176
          };
177

    
178
  private static MeshBase[] mMeshes;
179

    
180
///////////////////////////////////////////////////////////////////////////////////////////////////
181

    
182
  TwistySkewb(int size, Static4D quat, DistortedTexture texture,
183
              MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
184
    {
185
    super(size, 2*size-2, quat, texture, mesh, effects, moves, ObjectList.SKEW, res, scrWidth);
186
    }
187

    
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189

    
190
  private int getNumCorners()
191
    {
192
    return 8;
193
    }
194

    
195
///////////////////////////////////////////////////////////////////////////////////////////////////
196

    
197
  private int getNumEdges(int layers)
198
    {
199
    return (layers-2)*12;
200
    }
201

    
202
///////////////////////////////////////////////////////////////////////////////////////////////////
203

    
204
  private int getNumCentersPerFace(int layers)
205
    {
206
    return ((layers-2)*(layers-2) + (layers-1)*(layers-1));
207
    }
208

    
209
///////////////////////////////////////////////////////////////////////////////////////////////////
210

    
211
  float getScreenRatio()
212
    {
213
    return 1.0f;
214
    }
215

    
216
///////////////////////////////////////////////////////////////////////////////////////////////////
217

    
218
  Static4D[] getQuats()
219
    {
220
    return QUATS;
221
    }
222

    
223
///////////////////////////////////////////////////////////////////////////////////////////////////
224

    
225
  int getNumFaces()
226
    {
227
    return FACE_COLORS.length;
228
    }
229

    
230
///////////////////////////////////////////////////////////////////////////////////////////////////
231

    
232
  boolean shouldResetTextureMaps()
233
    {
234
    return false;
235
    }
236

    
237
///////////////////////////////////////////////////////////////////////////////////////////////////
238

    
239
  int getNumStickerTypes(int numLayers)
240
    {
241
    return 3;
242
    }
243

    
244
///////////////////////////////////////////////////////////////////////////////////////////////////
245

    
246
  float[][] getCuts(int numLayers)
247
    {
248
    switch(numLayers)
249
      {
250
      case 2: float[] c2 = new float[] {0.0f};
251
              return new float[][] { c2,c2,c2,c2 };
252
      case 3: float[] c3 = new float[] {-SQ3/12,+SQ3/12};
253
              return new float[][] { c3,c3,c3,c3 };
254
      }
255
    return null;
256
    }
257

    
258
///////////////////////////////////////////////////////////////////////////////////////////////////
259

    
260
  int getNumCubitFaces()
261
    {
262
    return FACES_PER_CUBIT;
263
    }
264

    
265
///////////////////////////////////////////////////////////////////////////////////////////////////
266

    
267
  float[][] getCubitPositions(int numLayers)
268
    {
269
    final float DIST_CORNER = (numLayers-1)*0.50f;
270
    final float DIST_EDGE   = (numLayers-1)*0.50f;
271
    final float DIST_CENTER = (numLayers-1)*0.50f;
272

    
273
    final int numCorners = getNumCorners();
274
    final int numEdges   = getNumEdges(numLayers);
275
    final int numCenters = 6*getNumCentersPerFace(numLayers);
276

    
277
    final float[][] CENTERS = new float[numCorners+numEdges+numCenters][];
278

    
279
    /// CORNERS //////////////////////////////////////////////
280

    
281
    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
282
    CENTERS[1] = new float[] { DIST_CORNER, DIST_CORNER,-DIST_CORNER };
283
    CENTERS[2] = new float[] { DIST_CORNER,-DIST_CORNER, DIST_CORNER };
284
    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
285
    CENTERS[4] = new float[] {-DIST_CORNER, DIST_CORNER, DIST_CORNER };
286
    CENTERS[5] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
287
    CENTERS[6] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
288
    CENTERS[7] = new float[] {-DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
289

    
290
    /// EDGES ///////////////////////////////////////////////
291

    
292
    final float[][]  edgeTable =
293
        {
294
            {0,+DIST_EDGE,+DIST_EDGE},
295
            {+DIST_EDGE,0,+DIST_EDGE},
296
            {0,-DIST_EDGE,+DIST_EDGE},
297
            {-DIST_EDGE,0,+DIST_EDGE},
298
            {+DIST_EDGE,+DIST_EDGE,0},
299
            {+DIST_EDGE,-DIST_EDGE,0},
300
            {-DIST_EDGE,-DIST_EDGE,0},
301
            {-DIST_EDGE,+DIST_EDGE,0},
302
            {0,+DIST_EDGE,-DIST_EDGE},
303
            {+DIST_EDGE,0,-DIST_EDGE},
304
            {0,-DIST_EDGE,-DIST_EDGE},
305
            {-DIST_EDGE,0,-DIST_EDGE}
306
        };
307

    
308
    int index=8;
309

    
310
    for (float[] edges : edgeTable)
311
      {
312
      float c = (3-numLayers)*0.5f;
313

    
314
      for (int j=0; j<numLayers-2; j++, c+=1.0f, index++)
315
        {
316
        CENTERS[index] = new float[] { edges[0]==0 ? c : edges[0] ,
317
                                       edges[1]==0 ? c : edges[1] ,
318
                                       edges[2]==0 ? c : edges[2] };
319
        }
320
      }
321

    
322
    /// CENTERS //////////////////////////////////////////////
323

    
324
    final float X= -1000.0f;
325
    final float Y= -1001.0f;
326

    
327
    final float[][]  centerTable =
328
        {
329
            {+DIST_CENTER,X,Y},
330
            {-DIST_CENTER,X,Y},
331
            {X,+DIST_CENTER,Y},
332
            {X,-DIST_CENTER,Y},
333
            {X,Y,+DIST_CENTER},
334
            {X,Y,-DIST_CENTER}
335
        };
336

    
337
    float x,y, cen0, cen1, cen2;
338

    
339
    for( float[] centers : centerTable )
340
      {
341
      x = (2-numLayers)*0.5f;
342

    
343
      for(int i=0; i<numLayers-1; i++, x+=1.0f)
344
        {
345
        y = (2-numLayers)*0.5f;
346

    
347
        for(int j=0; j<numLayers-1; j++, y+=1.0f, index++)
348
          {
349
               if( centers[0]==Y ) cen0 = y;
350
          else if( centers[0]==X ) cen0 = x;
351
          else                     cen0 = centers[0];
352

    
353
               if( centers[1]==Y ) cen1 = y;
354
          else if( centers[1]==X ) cen1 = x;
355
          else                     cen1 = centers[1];
356

    
357
               if( centers[2]==Y ) cen2 = y;
358
          else if( centers[2]==X ) cen2 = x;
359
          else                     cen2 = centers[2];
360

    
361
          CENTERS[index] = new float[] {cen0,cen1,cen2};
362
          }
363
        }
364

    
365
      x = (3-numLayers)*0.5f;
366

    
367
      for(int i=0; i<numLayers-2; i++, x+=1.0f)
368
        {
369
        y = (3-numLayers)*0.5f;
370

    
371
        for(int j=0; j<numLayers-2; j++, y+=1.0f, index++)
372
          {
373
               if( centers[0]==Y ) cen0 = y;
374
          else if( centers[0]==X ) cen0 = x;
375
          else                     cen0 = centers[0];
376

    
377
               if( centers[1]==Y ) cen1 = y;
378
          else if( centers[1]==X ) cen1 = x;
379
          else                     cen1 = centers[1];
380

    
381
               if( centers[2]==Y ) cen2 = y;
382
          else if( centers[2]==X ) cen2 = x;
383
          else                     cen2 = centers[2];
384

    
385
          CENTERS[index] = new float[] {cen0,cen1,cen2};
386
          }
387
        }
388
      }
389

    
390
    return CENTERS;
391
    }
392

    
393
///////////////////////////////////////////////////////////////////////////////////////////////////
394

    
395
  private Static4D getQuat(int cubit, int numLayers)
396
    {
397
    int numCorners = getNumCorners();
398
    int numEdges   = getNumEdges(numLayers);
399

    
400
    if( cubit<numCorners )
401
      {
402
      switch(cubit)
403
        {
404
        case  0: return QUATS[0];                          //  unit quat
405
        case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
406
        case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
407
        case  3: return QUATS[1];                          // 180 along X
408
        case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
409
        case  5: return QUATS[2];                          // 180 along Y
410
        case  6: return QUATS[3];                          // 180 along Z
411
        case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
412
        }
413
      }
414
    else if( cubit<numCorners+numEdges )
415
      {
416
      int edge = (cubit-numCorners)/(numLayers-2);
417

    
418
      switch(edge)
419
        {
420
        case  0: return QUATS[ 0];
421
        case  1: return QUATS[ 5];
422
        case  2: return QUATS[ 3];
423
        case  3: return QUATS[11];
424
        case  4: return QUATS[ 4];
425
        case  5: return QUATS[ 7];
426
        case  6: return QUATS[ 9];
427
        case  7: return QUATS[10];
428
        case  8: return QUATS[ 2];
429
        case  9: return QUATS[ 8];
430
        case 10: return QUATS[ 1];
431
        case 11: return QUATS[ 6];
432
        }
433
      }
434
    else
435
      {
436
      int center = (cubit-numCorners-numEdges)/getNumCentersPerFace(numLayers);
437

    
438
      switch(center)
439
        {
440
        case 0: return new Static4D(0,-SQ2/2,0,SQ2/2);    // -90 along Y
441
        case 1: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
442
        case 2: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
443
        case 3: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
444
        case 4: return QUATS[0];                          //  unit quaternion
445
        case 5: return QUATS[1];                          // 180 along X
446
        }
447
      }
448

    
449
    return null;
450
    }
451

    
452
///////////////////////////////////////////////////////////////////////////////////////////////////
453

    
454
  MeshBase createCubitMesh(int cubit, int numLayers)
455
    {
456
    if( mMeshes==null )
457
      {
458
      FactoryCubit factory = FactoryCubit.getInstance();
459
      factory.clear();
460
      mMeshes = new MeshBase[3];
461
      }
462

    
463
    MeshBase mesh;
464

    
465
    int numCorners = getNumCorners();
466
    int numEdges   = getNumEdges(numLayers);
467

    
468
    if( cubit<numCorners )
469
      {
470
      if( mMeshes[0]==null )
471
        {
472
        float[][] bands= new float[][]
473
          {
474
             {0.028f,35,0.16f,0.7f,7,3,3},
475
             {0.000f, 0,1.00f,0.0f,3,1,5}
476
          };
477
        int[] bandIndexes   = new int[] { 0,0,0,1,1,1 };
478
        float[][] corners   = new float[][] { {0.08f,0.15f}, {0.08f,0.20f} };
479
        int[] cornerIndexes = new int[] { 1,1,1,0,0 };
480
        float[][] centers   = new float[][] { {-0.25f, -0.25f, -0.25f} };
481
        int[] centerIndexes = new int[] { 0,0,0,-1,0 };
482

    
483
        FactoryCubit factory = FactoryCubit.getInstance();
484
        factory.createNewFaceTransform(VERTICES_CORNER,VERT_INDEXES_CORNER);
485
        mMeshes[0] = factory.createRoundedSolid(VERTICES_CORNER, VERT_INDEXES_CORNER,
486
                                                bands, bandIndexes,
487
                                                corners, cornerIndexes,
488
                                                centers, centerIndexes,
489
                                                getNumCubitFaces() );
490
        }
491
      mesh = mMeshes[0].copy(true);
492
      }
493
    else if( cubit<numCorners+numEdges )
494
      {
495
      if( mMeshes[1]==null )
496
        {
497
        float[][] bands= new float[][]
498
          {
499
             {0.035f,30,0.16f,0.8f,7,2,5},
500
             {0.020f,45,0.16f,0.2f,3,1,2}
501
          };
502
        int[] bandIndexes   = new int[] { 0,0,1,1 };
503
        float[][] corners   = new float[][] { {0.07f,0.20f}, {0.02f,0.30f} };
504
        int[] cornerIndexes = new int[] { 0,0,1,1 };
505
        float[][] centers   = new float[][] { {0.0f, -0.25f, -0.25f} };
506
        int[] centerIndexes = new int[] { 0,0,0,0 };
507

    
508
        FactoryCubit factory = FactoryCubit.getInstance();
509
        factory.createNewFaceTransform(VERTICES_EDGE,VERT_INDEXES_EDGE);
510
        mMeshes[1] = factory.createRoundedSolid(VERTICES_EDGE, VERT_INDEXES_EDGE,
511
                                                bands, bandIndexes,
512
                                                corners, cornerIndexes,
513
                                                centers, centerIndexes,
514
                                                getNumCubitFaces() );
515
        }
516
      mesh = mMeshes[1].copy(true);
517
      }
518
    else
519
      {
520
      if( mMeshes[2]==null )
521
        {
522
        float[][] bands= new float[][]
523
          {
524
             {0.051f,35,SQ2/8,0.9f, 7,3,3},
525
             {0.000f, 0,    1,0.0f, 3,0,0}
526
          };
527
        int[] bandIndexes   = new int[] { 0,1,1,1,1 };
528
        float[][] corners   = new float[][] { {0.06f,0.10f} };
529
        int[] cornerIndexes = new int[] { 0,0,0,0,0 };
530
        float[][] centers   = new float[][] { {0,0,-0.2f} };
531
        int[] centerIndexes = new int[] { 0,0,0,0,-1 };
532

    
533
        FactoryCubit factory = FactoryCubit.getInstance();
534
        factory.createNewFaceTransform(VERTICES_FACE,VERT_INDEXES_FACE);
535
        mMeshes[2] = factory.createRoundedSolid(VERTICES_FACE, VERT_INDEXES_FACE,
536
                                                bands, bandIndexes,
537
                                                corners, cornerIndexes,
538
                                                centers, centerIndexes,
539
                                                getNumCubitFaces() );
540
        }
541
      mesh = mMeshes[2].copy(true);
542
      }
543

    
544
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit,numLayers), new Static3D(0,0,0) );
545
    mesh.apply(quat,0xffffffff,0);
546

    
547
    return mesh;
548
    }
549

    
550
///////////////////////////////////////////////////////////////////////////////////////////////////
551

    
552
  int getFaceColor(int cubit, int cubitface, int numLayers)
553
    {
554
    int numCorners = getNumCorners();
555
    int numEdges   = getNumEdges(numLayers);
556

    
557
    if( cubit<numCorners )
558
      {
559
      return mCornerMap[cubit][cubitface];
560
      }
561
    else if( cubit<numCorners+numEdges )
562
      {
563
      int edge = (cubit-numCorners)/(numLayers-2);
564
      return mEdgeMap[edge][cubitface];
565
      }
566
    else
567
      {
568
      int center = (cubit-numCorners-numEdges)/getNumCentersPerFace(numLayers);
569
      return mCenterMap[center][cubitface];
570
      }
571
    }
572

    
573
///////////////////////////////////////////////////////////////////////////////////////////////////
574

    
575
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
576
    {
577
    int COLORS = FACE_COLORS.length;
578
    float R=0.0f,S=0.0f;
579
    int index=0, cubitType = face/COLORS;
580

    
581
    switch(cubitType)
582
      {
583
      case 0: R = 0.025f; S = 0.045f; index= 0; break;
584
      case 1: R = 0.025f; S = 0.035f; index= 0; break;
585
      case 2: R = 0.055f; S = 0.035f; index= 1; break;
586
      }
587

    
588
    FactorySticker factory = FactorySticker.getInstance();
589
    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[index], S, FACE_COLORS[face%COLORS], R);
590
    }
591

    
592
///////////////////////////////////////////////////////////////////////////////////////////////////
593

    
594
  float returnMultiplier()
595
    {
596
    return 2.0f;
597
    }
598

    
599
///////////////////////////////////////////////////////////////////////////////////////////////////
600
// PUBLIC API
601

    
602
  public Static3D[] getRotationAxis()
603
    {
604
    return ROT_AXIS;
605
    }
606

    
607
///////////////////////////////////////////////////////////////////////////////////////////////////
608

    
609
  public int[] getBasicAngle()
610
    {
611
    return BASIC_ANGLE;
612
    }
613

    
614
///////////////////////////////////////////////////////////////////////////////////////////////////
615

    
616
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total)
617
    {
618
    if( curr==0 )
619
      {
620
      scramble[curr][0] = rnd.nextInt(NUM_AXIS);
621
      }
622
    else
623
      {
624
      int newVector = rnd.nextInt(NUM_AXIS -1);
625
      scramble[curr][0] = (newVector>=scramble[curr-1][0] ? newVector+1 : newVector);
626
      }
627

    
628
    scramble[curr][1] = rnd.nextFloat()<=0.5f ? 0 : getNumLayers()-1;
629

    
630
    switch( rnd.nextInt(2) )
631
      {
632
      case 0: scramble[curr][2] = -1; break;
633
      case 1: scramble[curr][2] =  1; break;
634
      }
635
    }
636

    
637
///////////////////////////////////////////////////////////////////////////////////////////////////
638
// The Skewb is solved if and only if:
639
//
640
// 1) all of its corner and edge cubits are rotated with the same quat
641
// 2) all its face cubits are rotated with the same quat like the corner ones,
642
//    and optionally they also might be upside down.
643
//
644
// i.e.
645
// cubits [ 8] and [ 9] - might be extra QUAT[1]
646
// cubits [10] and [11] - might be extra QUAT[2]
647
// cubits [12] and [13] - might be extra QUAT[3]
648

    
649
  public boolean isSolved()
650
    {
651
    int q = CUBITS[0].mQuatIndex;
652

    
653
    int numLayers      = getNumLayers();
654
    int numCorners     = getNumCorners();
655
    int numEdges       = getNumEdges(numLayers);
656
    int cornersAndEdges= numCorners + numEdges;
657
    int centersPerFace = getNumCentersPerFace(numLayers);
658
    int cubit, q1=q;
659

    
660
    for(cubit=0; cubit<cornersAndEdges; cubit++)
661
      {
662
      if( CUBITS[cubit].mQuatIndex != q ) return false;
663
      }
664

    
665
    for(int face=0; face<6; face++)
666
      {
667
      if( face%2==0 ) q1 = mulQuat(q, (face/2)+1);
668

    
669
      for(int center=0; center<centersPerFace; center++)
670
        {
671
        if( CUBITS[cubit].mQuatIndex != q && CUBITS[cubit].mQuatIndex != q1 ) return false;
672
        cubit++;
673
        }
674
      }
675

    
676
    return true;
677
    }
678

    
679
///////////////////////////////////////////////////////////////////////////////////////////////////
680
// only needed for solvers - there are no Skewb solvers ATM)
681

    
682
  public String retObjectString()
683
    {
684
    return "";
685
    }
686

    
687
///////////////////////////////////////////////////////////////////////////////////////////////////
688

    
689
  public int getObjectName(int numLayers)
690
    {
691
    switch(numLayers)
692
      {
693
      case 2: return R.string.skew2;
694
      case 3: return R.string.skew3;
695
      }
696
    return R.string.skew2;
697
    }
698

    
699
///////////////////////////////////////////////////////////////////////////////////////////////////
700

    
701
  public int getInventor(int numLayers)
702
    {
703
    switch(numLayers)
704
      {
705
      case 2: return R.string.skew2_inventor;
706
      case 3: return R.string.skew3_inventor;
707
      }
708
    return R.string.skew2_inventor;
709
    }
710

    
711
///////////////////////////////////////////////////////////////////////////////////////////////////
712

    
713
  public int getComplexity(int numLayers)
714
    {
715
    switch(numLayers)
716
      {
717
      case 2: return 4;
718
      case 3: return 8;
719
      }
720
    return 5;
721
    }
722
}
(37-37/41)