Project

General

Profile

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

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

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

    
24
import org.distorted.helpers.FactoryCubit;
25
import org.distorted.helpers.ObjectShape;
26
import org.distorted.helpers.ObjectSticker;
27
import org.distorted.library.effect.MatrixEffectQuaternion;
28
import org.distorted.library.main.DistortedEffects;
29
import org.distorted.library.main.DistortedTexture;
30
import org.distorted.library.mesh.MeshBase;
31
import org.distorted.library.mesh.MeshSquare;
32
import org.distorted.library.type.Static3D;
33
import org.distorted.library.type.Static4D;
34
import org.distorted.main.R;
35

    
36
import java.util.Random;
37

    
38
///////////////////////////////////////////////////////////////////////////////////////////////////
39

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

    
44
  // the four rotation axis of a RubikSkewb. Must be normalized.
45
  static final Static3D[] ROT_AXIS = new Static3D[]
46
         {
47
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
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
         };
52

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
177
  private static final ObjectSticker[] mStickers;
178

    
179
  static
180
    {
181
    mStickers = new ObjectSticker[STICKERS.length+1];
182
    final float R1 = 0.025f;
183
    final float R2 = 0.025f;
184
    final float R3 = 0.055f;
185
    final float[][] radii  = { { R1,R1,R1 },{ R2,R2,R2 },{ R3,R3,R3,R3 } };
186
    final float[] strokes = { 0.045f, 0.035f, 0.035f };
187

    
188
    for(int s=0; s<STICKERS.length+1; s++)
189
      {
190
      int index = s<2 ? 0:1;
191
      mStickers[s] = new ObjectSticker(STICKERS[index],null,radii[s],strokes[s]);
192
      }
193
    }
194

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

    
197
  TwistySkewb(int size, Static4D quat, DistortedTexture texture,
198
              MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
199
    {
200
    super(size, 2*size-2, quat, texture, mesh, effects, moves, ObjectList.SKEW, res, scrWidth);
201
    }
202

    
203
///////////////////////////////////////////////////////////////////////////////////////////////////
204

    
205
  private int getNumCorners()
206
    {
207
    return 8;
208
    }
209

    
210
///////////////////////////////////////////////////////////////////////////////////////////////////
211

    
212
  private int getNumEdges(int layers)
213
    {
214
    return (layers-2)*12;
215
    }
216

    
217
///////////////////////////////////////////////////////////////////////////////////////////////////
218

    
219
  private int getNumCentersPerFace(int layers)
220
    {
221
    return ((layers-2)*(layers-2) + (layers-1)*(layers-1));
222
    }
223

    
224
///////////////////////////////////////////////////////////////////////////////////////////////////
225

    
226
  float getScreenRatio()
227
    {
228
    return 1.0f;
229
    }
230

    
231
///////////////////////////////////////////////////////////////////////////////////////////////////
232

    
233
  Static4D[] getQuats()
234
    {
235
    return QUATS;
236
    }
237

    
238
///////////////////////////////////////////////////////////////////////////////////////////////////
239

    
240
  int getNumFaces()
241
    {
242
    return FACE_COLORS.length;
243
    }
244

    
245
///////////////////////////////////////////////////////////////////////////////////////////////////
246

    
247
  boolean shouldResetTextureMaps()
248
    {
249
    return false;
250
    }
251

    
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253

    
254
  int getNumStickerTypes(int numLayers)
255
    {
256
    return 3;
257
    }
258

    
259
///////////////////////////////////////////////////////////////////////////////////////////////////
260

    
261
  float[][] getCuts(int numLayers)
262
    {
263
    switch(numLayers)
264
      {
265
      case 2: float[] c2 = new float[] {0.0f};
266
              return new float[][] { c2,c2,c2,c2 };
267
      case 3: float[] c3 = new float[] {-SQ3/12,+SQ3/12};
268
              return new float[][] { c3,c3,c3,c3 };
269
      }
270
    return null;
271
    }
272

    
273
///////////////////////////////////////////////////////////////////////////////////////////////////
274

    
275
  int getNumCubitFaces()
276
    {
277
    return FACES_PER_CUBIT;
278
    }
279

    
280
///////////////////////////////////////////////////////////////////////////////////////////////////
281

    
282
  float[][] getCubitPositions(int numLayers)
283
    {
284
    final float DIST_CORNER = (numLayers-1)*0.50f;
285
    final float DIST_EDGE   = (numLayers-1)*0.50f;
286
    final float DIST_CENTER = (numLayers-1)*0.50f;
287

    
288
    final int numCorners = getNumCorners();
289
    final int numEdges   = getNumEdges(numLayers);
290
    final int numCenters = 6*getNumCentersPerFace(numLayers);
291

    
292
    final float[][] CENTERS = new float[numCorners+numEdges+numCenters][];
293

    
294
    /// CORNERS //////////////////////////////////////////////
295

    
296
    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
297
    CENTERS[1] = new float[] { DIST_CORNER, DIST_CORNER,-DIST_CORNER };
298
    CENTERS[2] = new float[] { DIST_CORNER,-DIST_CORNER, DIST_CORNER };
299
    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
300
    CENTERS[4] = new float[] {-DIST_CORNER, DIST_CORNER, DIST_CORNER };
301
    CENTERS[5] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
302
    CENTERS[6] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
303
    CENTERS[7] = new float[] {-DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
304

    
305
    /// EDGES ///////////////////////////////////////////////
306

    
307
    final float[][]  edgeTable =
308
        {
309
            {0,+DIST_EDGE,+DIST_EDGE},
310
            {+DIST_EDGE,0,+DIST_EDGE},
311
            {0,-DIST_EDGE,+DIST_EDGE},
312
            {-DIST_EDGE,0,+DIST_EDGE},
313
            {+DIST_EDGE,+DIST_EDGE,0},
314
            {+DIST_EDGE,-DIST_EDGE,0},
315
            {-DIST_EDGE,-DIST_EDGE,0},
316
            {-DIST_EDGE,+DIST_EDGE,0},
317
            {0,+DIST_EDGE,-DIST_EDGE},
318
            {+DIST_EDGE,0,-DIST_EDGE},
319
            {0,-DIST_EDGE,-DIST_EDGE},
320
            {-DIST_EDGE,0,-DIST_EDGE}
321
        };
322

    
323
    int index=8;
324

    
325
    for (float[] edges : edgeTable)
326
      {
327
      float c = (3-numLayers)*0.5f;
328

    
329
      for (int j=0; j<numLayers-2; j++, c+=1.0f, index++)
330
        {
331
        CENTERS[index] = new float[] { edges[0]==0 ? c : edges[0] ,
332
                                       edges[1]==0 ? c : edges[1] ,
333
                                       edges[2]==0 ? c : edges[2] };
334
        }
335
      }
336

    
337
    /// CENTERS //////////////////////////////////////////////
338

    
339
    final float X= -1000.0f;
340
    final float Y= -1001.0f;
341

    
342
    final float[][]  centerTable =
343
        {
344
            {+DIST_CENTER,X,Y},
345
            {-DIST_CENTER,X,Y},
346
            {X,+DIST_CENTER,Y},
347
            {X,-DIST_CENTER,Y},
348
            {X,Y,+DIST_CENTER},
349
            {X,Y,-DIST_CENTER}
350
        };
351

    
352
    float x,y, cen0, cen1, cen2;
353

    
354
    for( float[] centers : centerTable )
355
      {
356
      x = (2-numLayers)*0.5f;
357

    
358
      for(int i=0; i<numLayers-1; i++, x+=1.0f)
359
        {
360
        y = (2-numLayers)*0.5f;
361

    
362
        for(int j=0; j<numLayers-1; j++, y+=1.0f, index++)
363
          {
364
               if( centers[0]==Y ) cen0 = y;
365
          else if( centers[0]==X ) cen0 = x;
366
          else                     cen0 = centers[0];
367

    
368
               if( centers[1]==Y ) cen1 = y;
369
          else if( centers[1]==X ) cen1 = x;
370
          else                     cen1 = centers[1];
371

    
372
               if( centers[2]==Y ) cen2 = y;
373
          else if( centers[2]==X ) cen2 = x;
374
          else                     cen2 = centers[2];
375

    
376
          CENTERS[index] = new float[] {cen0,cen1,cen2};
377
          }
378
        }
379

    
380
      x = (3-numLayers)*0.5f;
381

    
382
      for(int i=0; i<numLayers-2; i++, x+=1.0f)
383
        {
384
        y = (3-numLayers)*0.5f;
385

    
386
        for(int j=0; j<numLayers-2; j++, y+=1.0f, index++)
387
          {
388
               if( centers[0]==Y ) cen0 = y;
389
          else if( centers[0]==X ) cen0 = x;
390
          else                     cen0 = centers[0];
391

    
392
               if( centers[1]==Y ) cen1 = y;
393
          else if( centers[1]==X ) cen1 = x;
394
          else                     cen1 = centers[1];
395

    
396
               if( centers[2]==Y ) cen2 = y;
397
          else if( centers[2]==X ) cen2 = x;
398
          else                     cen2 = centers[2];
399

    
400
          CENTERS[index] = new float[] {cen0,cen1,cen2};
401
          }
402
        }
403
      }
404

    
405
    return CENTERS;
406
    }
407

    
408
///////////////////////////////////////////////////////////////////////////////////////////////////
409

    
410
  private Static4D getQuat(int cubit, int numLayers)
411
    {
412
    int numCorners = getNumCorners();
413
    int numEdges   = getNumEdges(numLayers);
414

    
415
    if( cubit<numCorners )
416
      {
417
      switch(cubit)
418
        {
419
        case  0: return QUATS[0];                          //  unit quat
420
        case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
421
        case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
422
        case  3: return QUATS[1];                          // 180 along X
423
        case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
424
        case  5: return QUATS[2];                          // 180 along Y
425
        case  6: return QUATS[3];                          // 180 along Z
426
        case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
427
        }
428
      }
429
    else if( cubit<numCorners+numEdges )
430
      {
431
      int edge = (cubit-numCorners)/(numLayers-2);
432

    
433
      switch(edge)
434
        {
435
        case  0: return QUATS[ 0];
436
        case  1: return QUATS[ 5];
437
        case  2: return QUATS[ 3];
438
        case  3: return QUATS[11];
439
        case  4: return QUATS[ 4];
440
        case  5: return QUATS[ 7];
441
        case  6: return QUATS[ 9];
442
        case  7: return QUATS[10];
443
        case  8: return QUATS[ 2];
444
        case  9: return QUATS[ 8];
445
        case 10: return QUATS[ 1];
446
        case 11: return QUATS[ 6];
447
        }
448
      }
449
    else
450
      {
451
      int center = (cubit-numCorners-numEdges)/getNumCentersPerFace(numLayers);
452

    
453
      switch(center)
454
        {
455
        case 0: return new Static4D(0,-SQ2/2,0,SQ2/2);    // -90 along Y
456
        case 1: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
457
        case 2: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
458
        case 3: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
459
        case 4: return QUATS[0];                          //  unit quaternion
460
        case 5: return QUATS[1];                          // 180 along X
461
        }
462
      }
463

    
464
    return null;
465
    }
466

    
467
///////////////////////////////////////////////////////////////////////////////////////////////////
468

    
469
  ObjectShape getObjectShape(int cubit, int numLayers)
470
    {
471
    int variant = getCubitVariant(cubit,numLayers);
472

    
473
    if( variant==0 )
474
      {
475
      int N = numLayers==2 ? 7:5;
476
      int E1= numLayers==2 ? 3:2;
477
      int E2= numLayers==2 ? 5:3;
478
      float[][] bands= new float[][]
479
          {
480
             {0.028f,35,0.16f,0.7f,N,E1,E1},
481
             {0.000f, 0,1.00f,0.0f,3, 1,E2}
482
          };
483
      int[] bandIndices   = new int[] { 0,0,0,1,1,1 };
484
      float[][] corners   = new float[][] { {0.08f,0.15f}, {0.08f,0.20f} };
485
      int[] cornerIndices = new int[] { 1,1,1,0,0 };
486
      float[][] centers   = new float[][] { {-0.25f, -0.25f, -0.25f} };
487
      int[] centerIndices = new int[] { 0,0,0,-1,0 };
488

    
489
      return new ObjectShape(VERTICES_CORNER,VERT_INDEXES_CORNER,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
490
      }
491
    else if( variant==1 )
492
      {
493
      int N = numLayers==2 ? 7:5;
494
      int E = numLayers==2 ? 5:2;
495
      float[][] bands= new float[][]
496
          {
497
             {0.035f,30,0.16f,0.8f,N,2,E},
498
             {0.020f,45,0.16f,0.2f,3,1,2}
499
          };
500
      int[] bandIndices   = new int[] { 0,0,1,1 };
501
      float[][] corners   = new float[][] { {0.07f,0.20f}, {0.02f,0.30f} };
502
      int[] cornerIndices = new int[] { 0,0,1,1 };
503
      float[][] centers   = new float[][] { {0.0f, -0.25f, -0.25f} };
504
      int[] centerIndices = new int[] { 0,0,0,0 };
505

    
506
      return new ObjectShape(VERTICES_EDGE,VERT_INDEXES_EDGE,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
507
      }
508
    else
509
      {
510
      int N = numLayers==2 ? 7:6;
511
      int E = numLayers==2 ? 3:1;
512
      float[][] bands= new float[][]
513
          {
514
             {0.051f,35,SQ2/8,0.9f, N,E,E},
515
             {0.000f, 0,    1,0.0f, 3,0,0}
516
          };
517
      int[] bandIndices   = new int[] { 0,1,1,1,1 };
518
      float[][] corners   = new float[][] { {0.06f,0.10f} };
519
      int[] cornerIndices = new int[] { 0,0,0,0,0 };
520
      float[][] centers   = new float[][] { {0,0,-0.2f} };
521
      int[] centerIndices = new int[] { 0,0,0,0,-1 };
522

    
523
      return new ObjectShape(VERTICES_FACE,VERT_INDEXES_FACE,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
524
      }
525
    }
526

    
527
///////////////////////////////////////////////////////////////////////////////////////////////////
528

    
529
  private int getNumCubitVariants(int numLayers)
530
    {
531
    return 3;
532
    }
533

    
534
///////////////////////////////////////////////////////////////////////////////////////////////////
535

    
536
  int getCubitVariant(int cubit, int numLayers)
537
    {
538
    int numCorners = getNumCorners();
539
    if( cubit<numCorners ) return 0;
540
    int numEdges = getNumEdges(numLayers);
541
    return cubit<numCorners+numEdges ? 1:2;
542
    }
543

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

    
546
  MeshBase createCubitMesh(int cubit, int numLayers)
547
    {
548
    int variant = getCubitVariant(cubit,numLayers);
549

    
550
    if( mMeshes==null )
551
      {
552
      FactoryCubit factory = FactoryCubit.getInstance();
553
      factory.clear();
554
      mMeshes = new MeshBase[getNumCubitVariants(numLayers)];
555
      }
556

    
557
    if( mMeshes[variant]==null )
558
      {
559
      ObjectShape shape = getObjectShape(cubit,numLayers);
560
      FactoryCubit factory = FactoryCubit.getInstance();
561
      factory.createNewFaceTransform(shape);
562
      mMeshes[variant] = factory.createRoundedSolid(shape);
563
      }
564

    
565
    MeshBase mesh = mMeshes[variant].copy(true);
566
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit,numLayers), new Static3D(0,0,0) );
567
    mesh.apply(quat,0xffffffff,0);
568

    
569
    return mesh;
570
    }
571

    
572
///////////////////////////////////////////////////////////////////////////////////////////////////
573

    
574
  int getFaceColor(int cubit, int cubitface, int numLayers)
575
    {
576
    int numCorners = getNumCorners();
577
    int numEdges   = getNumEdges(numLayers);
578

    
579
    if( cubit<numCorners )
580
      {
581
      return mCornerMap[cubit][cubitface];
582
      }
583
    else if( cubit<numCorners+numEdges )
584
      {
585
      int edge = (cubit-numCorners)/(numLayers-2);
586
      return mEdgeMap[edge][cubitface];
587
      }
588
    else
589
      {
590
      int center = (cubit-numCorners-numEdges)/getNumCentersPerFace(numLayers);
591
      return mCenterMap[center][cubitface];
592
      }
593
    }
594

    
595
///////////////////////////////////////////////////////////////////////////////////////////////////
596

    
597
  int getColor(int face)
598
    {
599
    return FACE_COLORS[face];
600
    }
601

    
602
///////////////////////////////////////////////////////////////////////////////////////////////////
603

    
604
  ObjectSticker retSticker(int face)
605
    {
606
    return mStickers[face/NUM_FACES];
607
    }
608

    
609
///////////////////////////////////////////////////////////////////////////////////////////////////
610

    
611
  float returnMultiplier()
612
    {
613
    return 2.0f;
614
    }
615

    
616
///////////////////////////////////////////////////////////////////////////////////////////////////
617
// PUBLIC API
618

    
619
  public Static3D[] getRotationAxis()
620
    {
621
    return ROT_AXIS;
622
    }
623

    
624
///////////////////////////////////////////////////////////////////////////////////////////////////
625

    
626
  public int[] getBasicAngle()
627
    {
628
    return BASIC_ANGLE;
629
    }
630

    
631
///////////////////////////////////////////////////////////////////////////////////////////////////
632

    
633
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total)
634
    {
635
    if( curr==0 )
636
      {
637
      scramble[curr][0] = rnd.nextInt(NUM_AXIS);
638
      }
639
    else
640
      {
641
      int newVector = rnd.nextInt(NUM_AXIS -1);
642
      scramble[curr][0] = (newVector>=scramble[curr-1][0] ? newVector+1 : newVector);
643
      }
644

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

    
647
    switch( rnd.nextInt(2) )
648
      {
649
      case 0: scramble[curr][2] = -1; break;
650
      case 1: scramble[curr][2] =  1; break;
651
      }
652
    }
653

    
654
///////////////////////////////////////////////////////////////////////////////////////////////////
655
// The Skewb is solved if and only if:
656
//
657
// 1) all of its corner and edge cubits are rotated with the same quat
658
// 2) all its face cubits are rotated with the same quat like the corner ones,
659
//    and optionally they also might be upside down.
660
//
661
// i.e.
662
// cubits [ 8] and [ 9] - might be extra QUAT[1]
663
// cubits [10] and [11] - might be extra QUAT[2]
664
// cubits [12] and [13] - might be extra QUAT[3]
665

    
666
  public boolean isSolved()
667
    {
668
    int q = CUBITS[0].mQuatIndex;
669

    
670
    int numLayers      = getNumLayers();
671
    int numCorners     = getNumCorners();
672
    int numEdges       = getNumEdges(numLayers);
673
    int cornersAndEdges= numCorners + numEdges;
674
    int centersPerFace = getNumCentersPerFace(numLayers);
675
    int cubit, q1=q;
676

    
677
    for(cubit=0; cubit<cornersAndEdges; cubit++)
678
      {
679
      if( CUBITS[cubit].mQuatIndex != q ) return false;
680
      }
681

    
682
    for(int face=0; face<6; face++)
683
      {
684
      if( face%2==0 ) q1 = mulQuat(q, (face/2)+1);
685

    
686
      for(int center=0; center<centersPerFace; center++)
687
        {
688
        if( CUBITS[cubit].mQuatIndex != q && CUBITS[cubit].mQuatIndex != q1 ) return false;
689
        cubit++;
690
        }
691
      }
692

    
693
    return true;
694
    }
695

    
696
///////////////////////////////////////////////////////////////////////////////////////////////////
697

    
698
  public int getObjectName(int numLayers)
699
    {
700
    switch(numLayers)
701
      {
702
      case 2: return R.string.skew2;
703
      case 3: return R.string.skew3;
704
      }
705
    return R.string.skew2;
706
    }
707

    
708
///////////////////////////////////////////////////////////////////////////////////////////////////
709

    
710
  public int getInventor(int numLayers)
711
    {
712
    switch(numLayers)
713
      {
714
      case 2: return R.string.skew2_inventor;
715
      case 3: return R.string.skew3_inventor;
716
      }
717
    return R.string.skew2_inventor;
718
    }
719

    
720
///////////////////////////////////////////////////////////////////////////////////////////////////
721

    
722
  public int getComplexity(int numLayers)
723
    {
724
    switch(numLayers)
725
      {
726
      case 2: return 4;
727
      case 3: return 8;
728
      }
729
    return 5;
730
    }
731
}
(37-37/41)