Project

General

Profile

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

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

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
             // TODO
120
          };
121

    
122
  private static final int[][] VERT_INDEXES_CORNER = new int[][]
123
          {
124
             // TODO
125
          };
126

    
127
  private static final double[][] VERTICES_EDGE = new double[][]
128
          {
129
             {-0.5, 0.0, 0.0},
130
             { 0.5, 0.0, 0.0},
131
             { 0.0,-0.5, 0.0},
132
             { 0.0, 0.0,-0.5}
133
          };
134

    
135
  private static final int[][] VERT_INDEXES_EDGE = new int[][]
136
          {
137
             {2,1,0},   // counterclockwise!
138
             {3,0,1},
139
             {2,3,1},
140
             {3,2,0},
141
          };
142

    
143
  private static final double[][] VERTICES_FACE = new double[][]
144
          {
145
             // TODO
146
          };
147

    
148
  private static final int[][] VERT_INDEXES_FACE = new int[][]
149
          {
150
             // TODO
151
          };
152

    
153
  private static MeshBase[] mMeshes;
154

    
155
///////////////////////////////////////////////////////////////////////////////////////////////////
156

    
157
  TwistySkewb(int size, Static4D quat, DistortedTexture texture,
158
              MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
159
    {
160
    super(size, 2*size-2, quat, texture, mesh, effects, moves, ObjectList.SKEW, res, scrWidth);
161
    }
162

    
163
///////////////////////////////////////////////////////////////////////////////////////////////////
164

    
165
  double[][] getVertices(int cubitType)
166
    {
167
    if( cubitType==0 ) return VERTICES_CORNER;
168
    if( cubitType==1 ) return VERTICES_EDGE;
169
    if( cubitType==2 ) return VERTICES_FACE;
170
    return null;
171
    }
172

    
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174

    
175
  int[][] getVertIndexes(int cubitType)
176
    {
177
    if( cubitType==0 ) return VERT_INDEXES_CORNER;
178
    if( cubitType==1 ) return VERT_INDEXES_EDGE;
179
    if( cubitType==2 ) return VERT_INDEXES_FACE;
180
    return null;
181
    }
182

    
183
///////////////////////////////////////////////////////////////////////////////////////////////////
184

    
185
  int getNumCubitTypes(int numLayers)
186
    {
187
    return numLayers==2 ? 2 : 3;
188
    }
189

    
190
///////////////////////////////////////////////////////////////////////////////////////////////////
191

    
192
  private int getNumCorners()
193
    {
194
    return 8;
195
    }
196

    
197
///////////////////////////////////////////////////////////////////////////////////////////////////
198

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

    
204
///////////////////////////////////////////////////////////////////////////////////////////////////
205

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

    
211
///////////////////////////////////////////////////////////////////////////////////////////////////
212

    
213
  float getScreenRatio()
214
    {
215
    return 1.0f;
216
    }
217

    
218
///////////////////////////////////////////////////////////////////////////////////////////////////
219

    
220
  Static4D[] getQuats()
221
    {
222
    return QUATS;
223
    }
224

    
225
///////////////////////////////////////////////////////////////////////////////////////////////////
226

    
227
  int getNumFaces()
228
    {
229
    return FACE_COLORS.length;
230
    }
231

    
232
///////////////////////////////////////////////////////////////////////////////////////////////////
233

    
234
  boolean shouldResetTextureMaps()
235
    {
236
    return false;
237
    }
238

    
239
///////////////////////////////////////////////////////////////////////////////////////////////////
240

    
241
  int getNumStickerTypes(int numLayers)
242
    {
243
    return 3;
244
    }
245

    
246
///////////////////////////////////////////////////////////////////////////////////////////////////
247

    
248
  float[] getCuts(int numLayers)
249
    {
250
    float[] cuts = new float[numLayers-1];
251

    
252
    switch(numLayers)
253
      {
254
      case 2: cuts[0] = 0;
255
              break;
256
      case 3: cuts[0] = -SQ3/12;
257
              cuts[1] = +SQ3/12;
258
              break;
259
      case 4: cuts[0] = -SQ3/9;
260
              cuts[1] = 0;
261
              cuts[2] = +SQ3/9;
262
              break;
263
      }
264
    return cuts;
265
    }
266

    
267
///////////////////////////////////////////////////////////////////////////////////////////////////
268

    
269
  int getNumCubitFaces()
270
    {
271
    return FACES_PER_CUBIT;
272
    }
273

    
274
///////////////////////////////////////////////////////////////////////////////////////////////////
275

    
276
  float[][] getCubitPositions(int numLayers)
277
    {
278
    final float DIST_CORNER = (numLayers-1)*0.50f;
279
    final float DIST_EDGE   = (numLayers-1)*0.50f;
280
    final float DIST_CENTER = (numLayers-1)*0.50f;
281

    
282
    final int numCorners = getNumCorners();
283
    final int numEdges   = getNumEdges(numLayers);
284
    final int numCenters = 6*getNumCentersPerFace(numLayers);
285

    
286
    final float[][] CENTERS = new float[numCorners+numEdges+numCenters][];
287

    
288
    /// CORNERS //////////////////////////////////////////////
289

    
290
    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
291
    CENTERS[1] = new float[] { DIST_CORNER, DIST_CORNER,-DIST_CORNER };
292
    CENTERS[2] = new float[] { DIST_CORNER,-DIST_CORNER, DIST_CORNER };
293
    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
294
    CENTERS[4] = new float[] {-DIST_CORNER, DIST_CORNER, DIST_CORNER };
295
    CENTERS[5] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
296
    CENTERS[6] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
297
    CENTERS[7] = new float[] {-DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
298

    
299
    /// EDGES ///////////////////////////////////////////////
300

    
301
    final float[][]  edgeTable =
302
        {
303
            {0,+DIST_EDGE,+DIST_EDGE},
304
            {+DIST_EDGE,0,+DIST_EDGE},
305
            {0,-DIST_EDGE,+DIST_EDGE},
306
            {-DIST_EDGE,0,+DIST_EDGE},
307
            {+DIST_EDGE,+DIST_EDGE,0},
308
            {+DIST_EDGE,-DIST_EDGE,0},
309
            {-DIST_EDGE,-DIST_EDGE,0},
310
            {-DIST_EDGE,+DIST_EDGE,0},
311
            {0,+DIST_EDGE,-DIST_EDGE},
312
            {+DIST_EDGE,0,-DIST_EDGE},
313
            {0,-DIST_EDGE,-DIST_EDGE},
314
            {-DIST_EDGE,0,-DIST_EDGE}
315
        };
316

    
317
    int index=8;
318

    
319
    for (float[] edges : edgeTable)
320
      {
321
      float c = (3-numLayers)*0.5f;
322

    
323
      for (int j=0; j<numLayers-2; j++, c+=1.0f, index++)
324
        {
325
        CENTERS[index] = new float[] { edges[0]==0 ? c : edges[0] ,
326
                                       edges[1]==0 ? c : edges[1] ,
327
                                       edges[2]==0 ? c : edges[2] };
328
        }
329
      }
330

    
331
    /// CENTERS //////////////////////////////////////////////
332

    
333
    final float X= -1000.0f;
334
    final float Y= -1001.0f;
335

    
336
    final float[][]  centerTable =
337
        {
338
            {+DIST_CENTER,X,Y},
339
            {-DIST_CENTER,X,Y},
340
            {X,+DIST_CENTER,Y},
341
            {X,-DIST_CENTER,Y},
342
            {X,Y,+DIST_CENTER},
343
            {X,Y,-DIST_CENTER}
344
        };
345

    
346
    float x,y, cen0, cen1, cen2;
347

    
348
    for( float[] centers : centerTable )
349
      {
350
      x = (2-numLayers)*0.5f;
351

    
352
      for(int i=0; i<numLayers-1; i++, x+=1.0f)
353
        {
354
        y = (2-numLayers)*0.5f;
355

    
356
        for(int j=0; j<numLayers-1; j++, y+=1.0f, index++)
357
          {
358
               if( centers[0]==Y ) cen0 = y;
359
          else if( centers[0]==X ) cen0 = x;
360
          else                     cen0 = centers[0];
361

    
362
               if( centers[1]==Y ) cen1 = y;
363
          else if( centers[1]==X ) cen1 = x;
364
          else                     cen1 = centers[1];
365

    
366
               if( centers[2]==Y ) cen2 = y;
367
          else if( centers[2]==X ) cen2 = x;
368
          else                     cen2 = centers[2];
369

    
370
          CENTERS[index] = new float[] {cen0,cen1,cen2};
371
          }
372
        }
373

    
374
      x = (3-numLayers)*0.5f;
375

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

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

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

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

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

    
399
    return CENTERS;
400
    }
401

    
402
///////////////////////////////////////////////////////////////////////////////////////////////////
403

    
404
  private Static4D getQuat(int cubit, int numLayers)
405
    {
406
    int numCorners = getNumCorners();
407
    int numEdges   = getNumEdges(numLayers);
408

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

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

    
447
      switch(center)
448
        {
449
        case 0: return new Static4D(0,-SQ2/2,0,SQ2/2);    // -90 along Y
450
        case 1: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
451
        case 2: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
452
        case 3: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
453
        case 4: return QUATS[0];                          //  unit quaternion
454
        case 5: return QUATS[1];                          // 180 along X
455
        }
456
      }
457

    
458
    return null;
459
    }
460

    
461
///////////////////////////////////////////////////////////////////////////////////////////////////
462

    
463
  MeshBase createCubitMesh(int cubit, int numLayers)
464
    {
465
    if( mMeshes==null )
466
      {
467
      FactoryCubit factory = FactoryCubit.getInstance();
468
      factory.clear();
469
      mMeshes = new MeshBase[3];
470
      }
471

    
472
    MeshBase mesh;
473

    
474
    int numCorners = getNumCorners();
475
    int numEdges   = getNumEdges(numLayers);
476

    
477
    if( cubit<numCorners )
478
      {
479
      if( mMeshes[0]==null )
480
        {
481
        mMeshes[0] = FactoryCubit.getInstance().createSkewbCornerMesh();
482
        }
483
      mesh = mMeshes[0].copy(true);
484
      }
485
    else if( cubit<numCorners+numEdges )
486
      {
487
      if( mMeshes[1]==null )
488
        {
489
        float[][] bands= new float[][]
490
          {
491
             {0.035f,30,0.16f,0.8f,7,2,5},
492
             {0.020f,45,0.16f,0.2f,3,1,2}
493
          };
494
        int[] bandIndexes   = new int[] { 0,0,1,1 };
495
        float[][] corners   = new float[][] { {0.07f,0.20f}, {0.02f,0.30f} };
496
        int[] cornerIndexes = new int[] { 0,0,1,1 };
497
        float[][] centers   = new float[][] { {0.0f, -0.25f, -0.25f} };
498
        int[] centerIndexes = new int[] { 0,0,0,0 };
499

    
500
        FactoryCubit factory = FactoryCubit.getInstance();
501
        factory.createNewFaceTransform(VERTICES_EDGE,VERT_INDEXES_EDGE);
502
        mMeshes[1] = factory.createRoundedSolid(VERTICES_EDGE, VERT_INDEXES_EDGE,
503
                                                bands, bandIndexes,
504
                                                corners, cornerIndexes,
505
                                                centers, centerIndexes,
506
                                                getNumCubitFaces() );
507
        }
508
      mesh = mMeshes[1].copy(true);
509
      }
510
    else
511
      {
512
      if( mMeshes[2]==null )
513
        {
514
        mMeshes[2] = FactoryCubit.getInstance().createSkewbFaceMesh();
515
        }
516
      mesh = mMeshes[2].copy(true);
517
      }
518

    
519
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit,numLayers), new Static3D(0,0,0) );
520
    mesh.apply(quat,0xffffffff,0);
521

    
522
    return mesh;
523
    }
524

    
525
///////////////////////////////////////////////////////////////////////////////////////////////////
526

    
527
  int getFaceColor(int cubit, int cubitface, int numLayers)
528
    {
529
    int numCorners = getNumCorners();
530
    int numEdges   = getNumEdges(numLayers);
531

    
532
    if( cubit<numCorners )
533
      {
534
      return mCornerMap[cubit][cubitface];
535
      }
536
    else if( cubit<numCorners+numEdges )
537
      {
538
      int edge = (cubit-numCorners)/(numLayers-2);
539
      return mEdgeMap[edge][cubitface];
540
      }
541
    else
542
      {
543
      int center = (cubit-numCorners-numEdges)/getNumCentersPerFace(numLayers);
544
      return mCenterMap[center][cubitface];
545
      }
546
    }
547

    
548
///////////////////////////////////////////////////////////////////////////////////////////////////
549

    
550
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
551
    {
552
    int COLORS = FACE_COLORS.length;
553
    float R,S;
554
    float[] vertices;
555

    
556
    if( face<COLORS )
557
      {
558
      float E = 0.5f;
559
      R = 0.023f;
560
      S = 0.035f;
561
      vertices = new float[] { -E+E/4,E/4, E/4,-E+E/4, E/4,E/4};
562
      }
563
    else if( face<2*COLORS )
564
      {
565
      float E = 0.5f;
566
      R = 0.025f;
567
      S = 0.05f;
568
      vertices = new float[] { -E,E/3, 0,-2*E/3, +E,E/3 };
569
      }
570
    else
571
      {
572
      float E = SQ2/4;
573
      R = 0.055f;
574
      S = 0.035f;
575
      vertices = new float[] { -E,-E, +E,-E, +E,+E, -E,+E };
576
      }
577

    
578
    FactorySticker factory = FactorySticker.getInstance();
579
    factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[face%COLORS], R);
580
    }
581

    
582
///////////////////////////////////////////////////////////////////////////////////////////////////
583

    
584
  float returnMultiplier()
585
    {
586
    return 2.0f;
587
    }
588

    
589
///////////////////////////////////////////////////////////////////////////////////////////////////
590

    
591
  float[] getRowChances(int numLayers)
592
    {
593
    float[] chances = new float[numLayers];
594

    
595
    switch(numLayers)
596
      {
597
      case 2: chances[0] = 0.5f;
598
              chances[1] = 1.0f;
599
              break;
600
      case 3: chances[0] = 0.5f;
601
              chances[1] = 0.5f;
602
              chances[2] = 1.0f;
603
              break;
604
      default:for(int i=0; i<numLayers; i++)
605
                {
606
                chances[i] = (float)(i+1)/numLayers;
607
                }
608
      }
609

    
610
    return chances;
611
    }
612

    
613
///////////////////////////////////////////////////////////////////////////////////////////////////
614
// PUBLIC API
615

    
616
  public Static3D[] getRotationAxis()
617
    {
618
    return ROT_AXIS;
619
    }
620

    
621
///////////////////////////////////////////////////////////////////////////////////////////////////
622

    
623
  public int getBasicAngle()
624
    {
625
    return 3;
626
    }
627

    
628
///////////////////////////////////////////////////////////////////////////////////////////////////
629

    
630
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
631
    {
632
    if( num==0 )
633
      {
634
      scramble[num][0] = rnd.nextInt(ROTATION_AXIS.length);
635
      }
636
    else
637
      {
638
      int newVector = rnd.nextInt(ROTATION_AXIS.length-1);
639
      scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
640
      }
641

    
642
    float rowFloat = rnd.nextFloat();
643

    
644
    for(int row=0; row<mRowChances.length; row++)
645
      {
646
      if( rowFloat<=mRowChances[row] )
647
        {
648
        scramble[num][1] = row;
649
        break;
650
        }
651
      }
652

    
653
    switch( rnd.nextInt(2) )
654
      {
655
      case 0: scramble[num][2] = -1; break;
656
      case 1: scramble[num][2] =  1; break;
657
      }
658
    }
659

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

    
672
  public boolean isSolved()
673
    {
674
    int q = CUBITS[0].mQuatIndex;
675

    
676
    int numLayers      = getNumLayers();
677
    int numCorners     = getNumCorners();
678
    int numEdges       = getNumEdges(numLayers);
679
    int cornersAndEdges= numCorners + numEdges;
680
    int centersPerFace = getNumCentersPerFace(numLayers);
681
    int cubit, q1=q;
682

    
683
    for(cubit=0; cubit<cornersAndEdges; cubit++)
684
      {
685
      if( CUBITS[cubit].mQuatIndex != q ) return false;
686
      }
687

    
688
    for(int face=0; face<6; face++)
689
      {
690
      if( face%2==0 ) q1 = mulQuat(q, (face/2)+1);
691

    
692
      for(int center=0; center<centersPerFace; center++)
693
        {
694
        if( CUBITS[cubit].mQuatIndex != q && CUBITS[cubit].mQuatIndex != q1 ) return false;
695
        cubit++;
696
        }
697
      }
698

    
699
    return true;
700
    }
701

    
702
///////////////////////////////////////////////////////////////////////////////////////////////////
703
// only needed for solvers - there are no Skewb solvers ATM)
704

    
705
  public String retObjectString()
706
    {
707
    return "";
708
    }
709

    
710
///////////////////////////////////////////////////////////////////////////////////////////////////
711

    
712
  public int getObjectName(int numLayers)
713
    {
714
    switch(numLayers)
715
      {
716
      case 2: return R.string.skew2;
717
      case 3: return R.string.skew3;
718
      }
719
    return R.string.skew2;
720
    }
721

    
722
///////////////////////////////////////////////////////////////////////////////////////////////////
723

    
724
  public int getInventor(int numLayers)
725
    {
726
    switch(numLayers)
727
      {
728
      case 2: return R.string.skew2_inventor;
729
      case 3: return R.string.skew3_inventor;
730
      }
731
    return R.string.skew2_inventor;
732
    }
733

    
734
///////////////////////////////////////////////////////////////////////////////////////////////////
735

    
736
  public int getComplexity(int numLayers)
737
    {
738
    switch(numLayers)
739
      {
740
      case 2: return 5;
741
      case 3: return 9;
742
      }
743
    return 5;
744
    }
745
}
(33-33/33)