Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistySkewb.java @ 0919eba7

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[] FACE_COLORS = new int[]
55
         {
56
           COLOR_YELLOW, COLOR_WHITE,
57
           COLOR_BLUE  , COLOR_GREEN,
58
           COLOR_RED   , COLOR_ORANGE
59
         };
60

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

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

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

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

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

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

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

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

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

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

    
161
  private static final int[][] VERT_INDEXES_FACE = new int[][]
162
          {
163
             {0,1,2,3},
164
             {4,1,0},
165
             {4,2,1},
166
             {4,3,2},
167
             {4,0,3}
168
          };
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.0f, -1.0f/3, 0.50f, 1.0f/6, -0.5f, 1.0f/6 },
175
             { -0.5f,    0.0f, 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
  double[][] getVertices(int cubitType)
191
    {
192
    if( cubitType==0 ) return VERTICES_CORNER;
193
    if( cubitType==1 ) return VERTICES_EDGE;
194
    if( cubitType==2 ) return VERTICES_FACE;
195
    return null;
196
    }
197

    
198
///////////////////////////////////////////////////////////////////////////////////////////////////
199

    
200
  int[][] getVertIndexes(int cubitType)
201
    {
202
    if( cubitType==0 ) return VERT_INDEXES_CORNER;
203
    if( cubitType==1 ) return VERT_INDEXES_EDGE;
204
    if( cubitType==2 ) return VERT_INDEXES_FACE;
205
    return null;
206
    }
207

    
208
///////////////////////////////////////////////////////////////////////////////////////////////////
209

    
210
  int getNumCubitTypes(int numLayers)
211
    {
212
    return numLayers==2 ? 2 : 3;
213
    }
214

    
215
///////////////////////////////////////////////////////////////////////////////////////////////////
216

    
217
  private int getNumCorners()
218
    {
219
    return 8;
220
    }
221

    
222
///////////////////////////////////////////////////////////////////////////////////////////////////
223

    
224
  private int getNumEdges(int layers)
225
    {
226
    return (layers-2)*12;
227
    }
228

    
229
///////////////////////////////////////////////////////////////////////////////////////////////////
230

    
231
  private int getNumCentersPerFace(int layers)
232
    {
233
    return ((layers-2)*(layers-2) + (layers-1)*(layers-1));
234
    }
235

    
236
///////////////////////////////////////////////////////////////////////////////////////////////////
237

    
238
  float getScreenRatio()
239
    {
240
    return 1.0f;
241
    }
242

    
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244

    
245
  Static4D[] getQuats()
246
    {
247
    return QUATS;
248
    }
249

    
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251

    
252
  int getNumFaces()
253
    {
254
    return FACE_COLORS.length;
255
    }
256

    
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258

    
259
  boolean shouldResetTextureMaps()
260
    {
261
    return false;
262
    }
263

    
264
///////////////////////////////////////////////////////////////////////////////////////////////////
265

    
266
  int getNumStickerTypes(int numLayers)
267
    {
268
    return 3;
269
    }
270

    
271
///////////////////////////////////////////////////////////////////////////////////////////////////
272

    
273
  float[] getCuts(int numLayers)
274
    {
275
    float[] cuts = new float[numLayers-1];
276

    
277
    switch(numLayers)
278
      {
279
      case 2: cuts[0] = 0;
280
              break;
281
      case 3: cuts[0] = -SQ3/12;
282
              cuts[1] = +SQ3/12;
283
              break;
284
      case 4: cuts[0] = -SQ3/9;
285
              cuts[1] = 0;
286
              cuts[2] = +SQ3/9;
287
              break;
288
      }
289
    return cuts;
290
    }
291

    
292
///////////////////////////////////////////////////////////////////////////////////////////////////
293

    
294
  int getNumCubitFaces()
295
    {
296
    return FACES_PER_CUBIT;
297
    }
298

    
299
///////////////////////////////////////////////////////////////////////////////////////////////////
300

    
301
  float[][] getCubitPositions(int numLayers)
302
    {
303
    final float DIST_CORNER = (numLayers-1)*0.50f;
304
    final float DIST_EDGE   = (numLayers-1)*0.50f;
305
    final float DIST_CENTER = (numLayers-1)*0.50f;
306

    
307
    final int numCorners = getNumCorners();
308
    final int numEdges   = getNumEdges(numLayers);
309
    final int numCenters = 6*getNumCentersPerFace(numLayers);
310

    
311
    final float[][] CENTERS = new float[numCorners+numEdges+numCenters][];
312

    
313
    /// CORNERS //////////////////////////////////////////////
314

    
315
    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
316
    CENTERS[1] = new float[] { DIST_CORNER, DIST_CORNER,-DIST_CORNER };
317
    CENTERS[2] = new float[] { DIST_CORNER,-DIST_CORNER, DIST_CORNER };
318
    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
319
    CENTERS[4] = new float[] {-DIST_CORNER, DIST_CORNER, DIST_CORNER };
320
    CENTERS[5] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
321
    CENTERS[6] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
322
    CENTERS[7] = new float[] {-DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
323

    
324
    /// EDGES ///////////////////////////////////////////////
325

    
326
    final float[][]  edgeTable =
327
        {
328
            {0,+DIST_EDGE,+DIST_EDGE},
329
            {+DIST_EDGE,0,+DIST_EDGE},
330
            {0,-DIST_EDGE,+DIST_EDGE},
331
            {-DIST_EDGE,0,+DIST_EDGE},
332
            {+DIST_EDGE,+DIST_EDGE,0},
333
            {+DIST_EDGE,-DIST_EDGE,0},
334
            {-DIST_EDGE,-DIST_EDGE,0},
335
            {-DIST_EDGE,+DIST_EDGE,0},
336
            {0,+DIST_EDGE,-DIST_EDGE},
337
            {+DIST_EDGE,0,-DIST_EDGE},
338
            {0,-DIST_EDGE,-DIST_EDGE},
339
            {-DIST_EDGE,0,-DIST_EDGE}
340
        };
341

    
342
    int index=8;
343

    
344
    for (float[] edges : edgeTable)
345
      {
346
      float c = (3-numLayers)*0.5f;
347

    
348
      for (int j=0; j<numLayers-2; j++, c+=1.0f, index++)
349
        {
350
        CENTERS[index] = new float[] { edges[0]==0 ? c : edges[0] ,
351
                                       edges[1]==0 ? c : edges[1] ,
352
                                       edges[2]==0 ? c : edges[2] };
353
        }
354
      }
355

    
356
    /// CENTERS //////////////////////////////////////////////
357

    
358
    final float X= -1000.0f;
359
    final float Y= -1001.0f;
360

    
361
    final float[][]  centerTable =
362
        {
363
            {+DIST_CENTER,X,Y},
364
            {-DIST_CENTER,X,Y},
365
            {X,+DIST_CENTER,Y},
366
            {X,-DIST_CENTER,Y},
367
            {X,Y,+DIST_CENTER},
368
            {X,Y,-DIST_CENTER}
369
        };
370

    
371
    float x,y, cen0, cen1, cen2;
372

    
373
    for( float[] centers : centerTable )
374
      {
375
      x = (2-numLayers)*0.5f;
376

    
377
      for(int i=0; i<numLayers-1; i++, x+=1.0f)
378
        {
379
        y = (2-numLayers)*0.5f;
380

    
381
        for(int j=0; j<numLayers-1; j++, y+=1.0f, index++)
382
          {
383
               if( centers[0]==Y ) cen0 = y;
384
          else if( centers[0]==X ) cen0 = x;
385
          else                     cen0 = centers[0];
386

    
387
               if( centers[1]==Y ) cen1 = y;
388
          else if( centers[1]==X ) cen1 = x;
389
          else                     cen1 = centers[1];
390

    
391
               if( centers[2]==Y ) cen2 = y;
392
          else if( centers[2]==X ) cen2 = x;
393
          else                     cen2 = centers[2];
394

    
395
          CENTERS[index] = new float[] {cen0,cen1,cen2};
396
          }
397
        }
398

    
399
      x = (3-numLayers)*0.5f;
400

    
401
      for(int i=0; i<numLayers-2; i++, x+=1.0f)
402
        {
403
        y = (3-numLayers)*0.5f;
404

    
405
        for(int j=0; j<numLayers-2; j++, y+=1.0f, index++)
406
          {
407
               if( centers[0]==Y ) cen0 = y;
408
          else if( centers[0]==X ) cen0 = x;
409
          else                     cen0 = centers[0];
410

    
411
               if( centers[1]==Y ) cen1 = y;
412
          else if( centers[1]==X ) cen1 = x;
413
          else                     cen1 = centers[1];
414

    
415
               if( centers[2]==Y ) cen2 = y;
416
          else if( centers[2]==X ) cen2 = x;
417
          else                     cen2 = centers[2];
418

    
419
          CENTERS[index] = new float[] {cen0,cen1,cen2};
420
          }
421
        }
422
      }
423

    
424
    return CENTERS;
425
    }
426

    
427
///////////////////////////////////////////////////////////////////////////////////////////////////
428

    
429
  private Static4D getQuat(int cubit, int numLayers)
430
    {
431
    int numCorners = getNumCorners();
432
    int numEdges   = getNumEdges(numLayers);
433

    
434
    if( cubit<numCorners )
435
      {
436
      switch(cubit)
437
        {
438
        case  0: return QUATS[0];                          //  unit quat
439
        case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
440
        case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
441
        case  3: return QUATS[1];                          // 180 along X
442
        case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
443
        case  5: return QUATS[2];                          // 180 along Y
444
        case  6: return QUATS[3];                          // 180 along Z
445
        case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
446
        }
447
      }
448
    else if( cubit<numCorners+numEdges )
449
      {
450
      int edge = (cubit-numCorners)/(numLayers-2);
451

    
452
      switch(edge)
453
        {
454
        case  0: return QUATS[ 0];
455
        case  1: return QUATS[ 5];
456
        case  2: return QUATS[ 3];
457
        case  3: return QUATS[11];
458
        case  4: return QUATS[ 4];
459
        case  5: return QUATS[ 7];
460
        case  6: return QUATS[ 9];
461
        case  7: return QUATS[10];
462
        case  8: return QUATS[ 2];
463
        case  9: return QUATS[ 8];
464
        case 10: return QUATS[ 1];
465
        case 11: return QUATS[ 6];
466
        }
467
      }
468
    else
469
      {
470
      int center = (cubit-numCorners-numEdges)/getNumCentersPerFace(numLayers);
471

    
472
      switch(center)
473
        {
474
        case 0: return new Static4D(0,-SQ2/2,0,SQ2/2);    // -90 along Y
475
        case 1: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
476
        case 2: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
477
        case 3: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
478
        case 4: return QUATS[0];                          //  unit quaternion
479
        case 5: return QUATS[1];                          // 180 along X
480
        }
481
      }
482

    
483
    return null;
484
    }
485

    
486
///////////////////////////////////////////////////////////////////////////////////////////////////
487

    
488
  MeshBase createCubitMesh(int cubit, int numLayers)
489
    {
490
    if( mMeshes==null )
491
      {
492
      FactoryCubit factory = FactoryCubit.getInstance();
493
      factory.clear();
494
      mMeshes = new MeshBase[3];
495
      }
496

    
497
    MeshBase mesh;
498

    
499
    int numCorners = getNumCorners();
500
    int numEdges   = getNumEdges(numLayers);
501

    
502
    if( cubit<numCorners )
503
      {
504
      if( mMeshes[0]==null )
505
        {
506
        float[][] bands= new float[][]
507
          {
508
             {0.028f,35,0.16f,0.7f,7,3,3},
509
             {0.000f, 0,1.00f,0.0f,3,1,5}
510
          };
511
        int[] bandIndexes   = new int[] { 0,0,0,1,1,1 };
512
        float[][] corners   = new float[][] { {0.08f,0.15f}, {0.08f,0.20f} };
513
        int[] cornerIndexes = new int[] { 1,1,1,0,0 };
514
        float[][] centers   = new float[][] { {-0.25f, -0.25f, -0.25f} };
515
        int[] centerIndexes = new int[] { 0,0,0,-1,0 };
516

    
517
        FactoryCubit factory = FactoryCubit.getInstance();
518
        factory.createNewFaceTransform(VERTICES_CORNER,VERT_INDEXES_CORNER);
519
        mMeshes[0] = factory.createRoundedSolid(VERTICES_CORNER, VERT_INDEXES_CORNER,
520
                                                bands, bandIndexes,
521
                                                corners, cornerIndexes,
522
                                                centers, centerIndexes,
523
                                                getNumCubitFaces() );
524
        }
525
      mesh = mMeshes[0].copy(true);
526
      }
527
    else if( cubit<numCorners+numEdges )
528
      {
529
      if( mMeshes[1]==null )
530
        {
531
        float[][] bands= new float[][]
532
          {
533
             {0.035f,30,0.16f,0.8f,7,2,5},
534
             {0.020f,45,0.16f,0.2f,3,1,2}
535
          };
536
        int[] bandIndexes   = new int[] { 0,0,1,1 };
537
        float[][] corners   = new float[][] { {0.07f,0.20f}, {0.02f,0.30f} };
538
        int[] cornerIndexes = new int[] { 0,0,1,1 };
539
        float[][] centers   = new float[][] { {0.0f, -0.25f, -0.25f} };
540
        int[] centerIndexes = new int[] { 0,0,0,0 };
541

    
542
        FactoryCubit factory = FactoryCubit.getInstance();
543
        factory.createNewFaceTransform(VERTICES_EDGE,VERT_INDEXES_EDGE);
544
        mMeshes[1] = factory.createRoundedSolid(VERTICES_EDGE, VERT_INDEXES_EDGE,
545
                                                bands, bandIndexes,
546
                                                corners, cornerIndexes,
547
                                                centers, centerIndexes,
548
                                                getNumCubitFaces() );
549
        }
550
      mesh = mMeshes[1].copy(true);
551
      }
552
    else
553
      {
554
      if( mMeshes[2]==null )
555
        {
556
        float[][] bands= new float[][]
557
          {
558
             {0.051f,35,SQ2/8,0.9f, 7,3,3},
559
             {0.000f, 0,    1,0.0f, 3,0,0}
560
          };
561
        int[] bandIndexes   = new int[] { 0,1,1,1,1 };
562
        float[][] corners   = new float[][] { {0.06f,0.10f} };
563
        int[] cornerIndexes = new int[] { 0,0,0,0,0 };
564
        float[][] centers   = new float[][] { {0,0,-0.2f} };
565
        int[] centerIndexes = new int[] { 0,0,0,0,-1 };
566

    
567
        FactoryCubit factory = FactoryCubit.getInstance();
568
        factory.createNewFaceTransform(VERTICES_FACE,VERT_INDEXES_FACE);
569
        mMeshes[2] = factory.createRoundedSolid(VERTICES_FACE, VERT_INDEXES_FACE,
570
                                                bands, bandIndexes,
571
                                                corners, cornerIndexes,
572
                                                centers, centerIndexes,
573
                                                getNumCubitFaces() );
574
        }
575
      mesh = mMeshes[2].copy(true);
576
      }
577

    
578
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit,numLayers), new Static3D(0,0,0) );
579
    mesh.apply(quat,0xffffffff,0);
580

    
581
    return mesh;
582
    }
583

    
584
///////////////////////////////////////////////////////////////////////////////////////////////////
585

    
586
  int getFaceColor(int cubit, int cubitface, int numLayers)
587
    {
588
    int numCorners = getNumCorners();
589
    int numEdges   = getNumEdges(numLayers);
590

    
591
    if( cubit<numCorners )
592
      {
593
      return mCornerMap[cubit][cubitface];
594
      }
595
    else if( cubit<numCorners+numEdges )
596
      {
597
      int edge = (cubit-numCorners)/(numLayers-2);
598
      return mEdgeMap[edge][cubitface];
599
      }
600
    else
601
      {
602
      int center = (cubit-numCorners-numEdges)/getNumCentersPerFace(numLayers);
603
      return mCenterMap[center][cubitface];
604
      }
605
    }
606

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

    
609
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
610
    {
611
    int COLORS = FACE_COLORS.length;
612
    float R=0.0f,S=0.0f;
613
    int cubitType = face/COLORS;
614

    
615
    switch(cubitType)
616
      {
617
      case 0: R = 0.025f; S = 0.045f; break;
618
      case 1: R = 0.025f; S = 0.035f; break;
619
      case 2: R = 0.055f; S = 0.035f; break;
620
      }
621

    
622
    FactorySticker factory = FactorySticker.getInstance();
623
    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[cubitType], S, FACE_COLORS[face%COLORS], R);
624
    }
625

    
626
///////////////////////////////////////////////////////////////////////////////////////////////////
627

    
628
  float returnMultiplier()
629
    {
630
    return 2.0f;
631
    }
632

    
633
///////////////////////////////////////////////////////////////////////////////////////////////////
634

    
635
  float[] getRowChances(int numLayers)
636
    {
637
    float[] chances = new float[numLayers];
638

    
639
    switch(numLayers)
640
      {
641
      case 2: chances[0] = 0.5f;
642
              chances[1] = 1.0f;
643
              break;
644
      case 3: chances[0] = 0.5f;
645
              chances[1] = 0.5f;
646
              chances[2] = 1.0f;
647
              break;
648
      default:for(int i=0; i<numLayers; i++)
649
                {
650
                chances[i] = (float)(i+1)/numLayers;
651
                }
652
      }
653

    
654
    return chances;
655
    }
656

    
657
///////////////////////////////////////////////////////////////////////////////////////////////////
658
// PUBLIC API
659

    
660
  public Static3D[] getRotationAxis()
661
    {
662
    return ROT_AXIS;
663
    }
664

    
665
///////////////////////////////////////////////////////////////////////////////////////////////////
666

    
667
  public int getBasicAngle()
668
    {
669
    return 3;
670
    }
671

    
672
///////////////////////////////////////////////////////////////////////////////////////////////////
673

    
674
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
675
    {
676
    if( num==0 )
677
      {
678
      scramble[num][0] = rnd.nextInt(ROTATION_AXIS.length);
679
      }
680
    else
681
      {
682
      int newVector = rnd.nextInt(ROTATION_AXIS.length-1);
683
      scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
684
      }
685

    
686
    float rowFloat = rnd.nextFloat();
687

    
688
    for(int row=0; row<mRowChances.length; row++)
689
      {
690
      if( rowFloat<=mRowChances[row] )
691
        {
692
        scramble[num][1] = row;
693
        break;
694
        }
695
      }
696

    
697
    switch( rnd.nextInt(2) )
698
      {
699
      case 0: scramble[num][2] = -1; break;
700
      case 1: scramble[num][2] =  1; break;
701
      }
702
    }
703

    
704
///////////////////////////////////////////////////////////////////////////////////////////////////
705
// The Skewb is solved if and only if:
706
//
707
// 1) all of its corner and edge cubits are rotated with the same quat
708
// 2) all its face cubits are rotated with the same quat like the corner ones,
709
//    and optionally they also might be upside down.
710
//
711
// i.e.
712
// cubits [ 8] and [ 9] - might be extra QUAT[1]
713
// cubits [10] and [11] - might be extra QUAT[2]
714
// cubits [12] and [13] - might be extra QUAT[3]
715

    
716
  public boolean isSolved()
717
    {
718
    int q = CUBITS[0].mQuatIndex;
719

    
720
    int numLayers      = getNumLayers();
721
    int numCorners     = getNumCorners();
722
    int numEdges       = getNumEdges(numLayers);
723
    int cornersAndEdges= numCorners + numEdges;
724
    int centersPerFace = getNumCentersPerFace(numLayers);
725
    int cubit, q1=q;
726

    
727
    for(cubit=0; cubit<cornersAndEdges; cubit++)
728
      {
729
      if( CUBITS[cubit].mQuatIndex != q ) return false;
730
      }
731

    
732
    for(int face=0; face<6; face++)
733
      {
734
      if( face%2==0 ) q1 = mulQuat(q, (face/2)+1);
735

    
736
      for(int center=0; center<centersPerFace; center++)
737
        {
738
        if( CUBITS[cubit].mQuatIndex != q && CUBITS[cubit].mQuatIndex != q1 ) return false;
739
        cubit++;
740
        }
741
      }
742

    
743
    return true;
744
    }
745

    
746
///////////////////////////////////////////////////////////////////////////////////////////////////
747
// only needed for solvers - there are no Skewb solvers ATM)
748

    
749
  public String retObjectString()
750
    {
751
    return "";
752
    }
753

    
754
///////////////////////////////////////////////////////////////////////////////////////////////////
755

    
756
  public int getObjectName(int numLayers)
757
    {
758
    switch(numLayers)
759
      {
760
      case 2: return R.string.skew2;
761
      case 3: return R.string.skew3;
762
      }
763
    return R.string.skew2;
764
    }
765

    
766
///////////////////////////////////////////////////////////////////////////////////////////////////
767

    
768
  public int getInventor(int numLayers)
769
    {
770
    switch(numLayers)
771
      {
772
      case 2: return R.string.skew2_inventor;
773
      case 3: return R.string.skew3_inventor;
774
      }
775
    return R.string.skew2_inventor;
776
    }
777

    
778
///////////////////////////////////////////////////////////////////////////////////////////////////
779

    
780
  public int getComplexity(int numLayers)
781
    {
782
    switch(numLayers)
783
      {
784
      case 2: return 5;
785
      case 3: return 9;
786
      }
787
    return 5;
788
    }
789
}
(33-33/33)