Project

General

Profile

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

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

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.ObjectShape;
25
import org.distorted.helpers.ObjectSticker;
26
import org.distorted.helpers.ScrambleState;
27
import org.distorted.library.main.DistortedEffects;
28
import org.distorted.library.main.DistortedTexture;
29
import org.distorted.library.mesh.MeshSquare;
30
import org.distorted.library.type.Static3D;
31
import org.distorted.library.type.Static4D;
32
import org.distorted.main.R;
33

    
34
import java.util.Random;
35

    
36
///////////////////////////////////////////////////////////////////////////////////////////////////
37

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

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

    
51
  private static final int[] BASIC_ANGLE = new int[] { 3,3,3,3 };
52

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

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

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

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

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

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

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

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

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

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

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

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

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

    
175
  private static final ObjectSticker[] mStickers;
176

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

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

    
193
  private int mCurrState;
194
  private int mIndexExcluded;
195
  private final ScrambleState[] mStates;
196
  private int[][] mScrambleTable;
197
  private int[] mNumOccurences;
198

    
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200

    
201
  TwistySkewb(int size, Static4D quat, DistortedTexture texture,
202
              MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
203
    {
204
    super(size, 2*size-2, quat, texture, mesh, effects, moves, ObjectList.SKEW, res, scrWidth);
205

    
206
    int[] tmp = {0,-1,0, 0,1,0, size-1,-1,0, size-1,1,0 };
207

    
208
    mStates = new ScrambleState[]
209
      {
210
      new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
211
      };
212
    }
213

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

    
216
  int[] getSolvedQuats(int cubit, int numLayers)
217
    {
218
    int status = retCubitSolvedStatus(cubit,numLayers);
219
    return status<0 ? null : buildSolvedQuats(MovementSkewb.FACE_AXIS[status],QUATS);
220
    }
221

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

    
224
  private int getNumCorners()
225
    {
226
    return 8;
227
    }
228

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

    
231
  private int getNumEdges(int layers)
232
    {
233
    return (layers-2)*12;
234
    }
235

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

    
238
  private int getNumCentersPerFace(int layers)
239
    {
240
    return ((layers-2)*(layers-2) + (layers-1)*(layers-1));
241
    }
242

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

    
245
  float getScreenRatio()
246
    {
247
    return 1.0f;
248
    }
249

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

    
252
  Static4D[] getQuats()
253
    {
254
    return QUATS;
255
    }
256

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

    
259
  int getNumFaces()
260
    {
261
    return FACE_COLORS.length;
262
    }
263

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

    
266
  int getSolvedFunctionIndex()
267
    {
268
    return 0;
269
    }
270

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

    
273
  boolean shouldResetTextureMaps()
274
    {
275
    return false;
276
    }
277

    
278
///////////////////////////////////////////////////////////////////////////////////////////////////
279

    
280
  int getNumStickerTypes(int numLayers)
281
    {
282
    return 3;
283
    }
284

    
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286

    
287
  float[][] getCuts(int numLayers)
288
    {
289
    switch(numLayers)
290
      {
291
      case 2: float[] c2 = new float[] {0.0f};
292
              return new float[][] { c2,c2,c2,c2 };
293
      case 3: float[] c3 = new float[] {-SQ3/12,+SQ3/12};
294
              return new float[][] { c3,c3,c3,c3 };
295
      }
296
    return null;
297
    }
298

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

    
301
  int getNumCubitFaces()
302
    {
303
    return FACES_PER_CUBIT;
304
    }
305

    
306
///////////////////////////////////////////////////////////////////////////////////////////////////
307

    
308
  float[][] getCubitPositions(int numLayers)
309
    {
310
    final float DIST_CORNER = (numLayers-1)*0.50f;
311
    final float DIST_EDGE   = (numLayers-1)*0.50f;
312
    final float DIST_CENTER = (numLayers-1)*0.50f;
313

    
314
    final int numCorners = getNumCorners();
315
    final int numEdges   = getNumEdges(numLayers);
316
    final int numCenters = 6*getNumCentersPerFace(numLayers);
317

    
318
    final float[][] CENTERS = new float[numCorners+numEdges+numCenters][];
319

    
320
    /// CORNERS //////////////////////////////////////////////
321

    
322
    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
323
    CENTERS[1] = new float[] { DIST_CORNER, DIST_CORNER,-DIST_CORNER };
324
    CENTERS[2] = new float[] { DIST_CORNER,-DIST_CORNER, DIST_CORNER };
325
    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
326
    CENTERS[4] = new float[] {-DIST_CORNER, DIST_CORNER, DIST_CORNER };
327
    CENTERS[5] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
328
    CENTERS[6] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
329
    CENTERS[7] = new float[] {-DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
330

    
331
    /// EDGES ///////////////////////////////////////////////
332

    
333
    final float[][]  edgeTable =
334
        {
335
            {0,+DIST_EDGE,+DIST_EDGE},
336
            {+DIST_EDGE,0,+DIST_EDGE},
337
            {0,-DIST_EDGE,+DIST_EDGE},
338
            {-DIST_EDGE,0,+DIST_EDGE},
339
            {+DIST_EDGE,+DIST_EDGE,0},
340
            {+DIST_EDGE,-DIST_EDGE,0},
341
            {-DIST_EDGE,-DIST_EDGE,0},
342
            {-DIST_EDGE,+DIST_EDGE,0},
343
            {0,+DIST_EDGE,-DIST_EDGE},
344
            {+DIST_EDGE,0,-DIST_EDGE},
345
            {0,-DIST_EDGE,-DIST_EDGE},
346
            {-DIST_EDGE,0,-DIST_EDGE}
347
        };
348

    
349
    int index=8;
350

    
351
    for (float[] edges : edgeTable)
352
      {
353
      float c = (3-numLayers)*0.5f;
354

    
355
      for (int j=0; j<numLayers-2; j++, c+=1.0f, index++)
356
        {
357
        CENTERS[index] = new float[] { edges[0]==0 ? c : edges[0] ,
358
                                       edges[1]==0 ? c : edges[1] ,
359
                                       edges[2]==0 ? c : edges[2] };
360
        }
361
      }
362

    
363
    /// CENTERS //////////////////////////////////////////////
364

    
365
    final float X= -1000.0f;
366
    final float Y= -1001.0f;
367

    
368
    final float[][]  centerTable =
369
        {
370
            {+DIST_CENTER,X,Y},
371
            {-DIST_CENTER,X,Y},
372
            {X,+DIST_CENTER,Y},
373
            {X,-DIST_CENTER,Y},
374
            {X,Y,+DIST_CENTER},
375
            {X,Y,-DIST_CENTER}
376
        };
377

    
378
    float x,y, cen0, cen1, cen2;
379

    
380
    for( float[] centers : centerTable )
381
      {
382
      x = (2-numLayers)*0.5f;
383

    
384
      for(int i=0; i<numLayers-1; i++, x+=1.0f)
385
        {
386
        y = (2-numLayers)*0.5f;
387

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

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

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

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

    
406
      x = (3-numLayers)*0.5f;
407

    
408
      for(int i=0; i<numLayers-2; i++, x+=1.0f)
409
        {
410
        y = (3-numLayers)*0.5f;
411

    
412
        for(int j=0; j<numLayers-2; j++, y+=1.0f, index++)
413
          {
414
               if( centers[0]==Y ) cen0 = y;
415
          else if( centers[0]==X ) cen0 = x;
416
          else                     cen0 = centers[0];
417

    
418
               if( centers[1]==Y ) cen1 = y;
419
          else if( centers[1]==X ) cen1 = x;
420
          else                     cen1 = centers[1];
421

    
422
               if( centers[2]==Y ) cen2 = y;
423
          else if( centers[2]==X ) cen2 = x;
424
          else                     cen2 = centers[2];
425

    
426
          CENTERS[index] = new float[] {cen0,cen1,cen2};
427
          }
428
        }
429
      }
430

    
431
    return CENTERS;
432
    }
433

    
434
///////////////////////////////////////////////////////////////////////////////////////////////////
435

    
436
  Static4D getQuat(int cubit, int numLayers)
437
    {
438
    int numCorners = getNumCorners();
439
    int numEdges   = getNumEdges(numLayers);
440

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

    
459
      switch(edge)
460
        {
461
        case  0: return QUATS[ 0];
462
        case  1: return QUATS[ 5];
463
        case  2: return QUATS[ 3];
464
        case  3: return QUATS[11];
465
        case  4: return QUATS[ 4];
466
        case  5: return QUATS[ 7];
467
        case  6: return QUATS[ 9];
468
        case  7: return QUATS[10];
469
        case  8: return QUATS[ 2];
470
        case  9: return QUATS[ 8];
471
        case 10: return QUATS[ 1];
472
        case 11: return QUATS[ 6];
473
        }
474
      }
475
    else
476
      {
477
      int center = (cubit-numCorners-numEdges)/getNumCentersPerFace(numLayers);
478

    
479
      switch(center)
480
        {
481
        case 0: return new Static4D(0,-SQ2/2,0,SQ2/2);    // -90 along Y
482
        case 1: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
483
        case 2: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
484
        case 3: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
485
        case 4: return QUATS[0];                          //  unit quaternion
486
        case 5: return QUATS[1];                          // 180 along X
487
        }
488
      }
489

    
490
    return null;
491
    }
492

    
493
///////////////////////////////////////////////////////////////////////////////////////////////////
494

    
495
  ObjectShape getObjectShape(int cubit, int numLayers)
496
    {
497
    int variant = getCubitVariant(cubit,numLayers);
498

    
499
    if( variant==0 )
500
      {
501
      int N = numLayers==2 ? 7:5;
502
      int E1= numLayers==2 ? 3:2;
503
      int E2= numLayers==2 ? 5:3;
504
      float[][] bands     = new float[][] { {0.028f,35,0.16f,0.7f,N,E1,E1}, {0.000f, 0,1.00f,0.0f,3,1,E2} };
505
      int[] bandIndices   = new int[] { 0,0,0,1,1,1 };
506
      float[][] corners   = new float[][] { {0.08f,0.15f}, {0.08f,0.20f} };
507
      int[] cornerIndices = new int[] { 1,1,1,0,0 };
508
      float[][] centers   = new float[][] { {-0.25f, -0.25f, -0.25f} };
509
      int[] centerIndices = new int[] { 0,0,0,-1,0 };
510
      return new ObjectShape(VERTICES_CORNER,VERT_INDEXES_CORNER,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
511
      }
512
    else if( variant==1 )
513
      {
514
      int N = numLayers==2 ? 7:5;
515
      int E = numLayers==2 ? 5:2;
516
      float[][] bands     = new float[][] { {0.035f,30,0.16f,0.8f,N,2,E}, {0.020f,45,0.16f,0.2f,3,1,2} };
517
      int[] bandIndices   = new int[] { 0,0,1,1 };
518
      float[][] corners   = new float[][] { {0.07f,0.20f}, {0.02f,0.30f} };
519
      int[] cornerIndices = new int[] { 0,0,1,1 };
520
      float[][] centers   = new float[][] { {0.0f, -0.25f, -0.25f} };
521
      int[] centerIndices = new int[] { 0,0,0,0 };
522
      return new ObjectShape(VERTICES_EDGE,VERT_INDEXES_EDGE,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
523
      }
524
    else
525
      {
526
      int N = numLayers==2 ? 7:6;
527
      int E = numLayers==2 ? 3:1;
528
      float[][] bands     = new float[][] { {0.051f,35,SQ2/8,0.9f,N,E,E}, {0.000f,0,1,0.0f,3,0,0} };
529
      int[] bandIndices   = new int[] { 0,1,1,1,1 };
530
      float[][] corners   = new float[][] { {0.06f,0.10f} };
531
      int[] cornerIndices = new int[] { 0,0,0,0,0 };
532
      float[][] centers   = new float[][] { {0,0,-0.2f} };
533
      int[] centerIndices = new int[] { 0,0,0,0,-1 };
534
      return new ObjectShape(VERTICES_FACE,VERT_INDEXES_FACE,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
535
      }
536
    }
537

    
538
///////////////////////////////////////////////////////////////////////////////////////////////////
539

    
540
  int getNumCubitVariants(int numLayers)
541
    {
542
    return 3;
543
    }
544

    
545
///////////////////////////////////////////////////////////////////////////////////////////////////
546

    
547
  int getCubitVariant(int cubit, int numLayers)
548
    {
549
    int numCorners = getNumCorners();
550
    if( cubit<numCorners ) return 0;
551
    int numEdges = getNumEdges(numLayers);
552
    return cubit<numCorners+numEdges ? 1:2;
553
    }
554

    
555
///////////////////////////////////////////////////////////////////////////////////////////////////
556

    
557
  int getFaceColor(int cubit, int cubitface, int numLayers)
558
    {
559
    int numCorners = getNumCorners();
560
    int numEdges   = getNumEdges(numLayers);
561

    
562
    if( cubit<numCorners )
563
      {
564
      return mCornerMap[cubit][cubitface];
565
      }
566
    else if( cubit<numCorners+numEdges )
567
      {
568
      int edge = (cubit-numCorners)/(numLayers-2);
569
      return mEdgeMap[edge][cubitface];
570
      }
571
    else
572
      {
573
      int center = (cubit-numCorners-numEdges)/getNumCentersPerFace(numLayers);
574
      return mCenterMap[center][cubitface];
575
      }
576
    }
577

    
578
///////////////////////////////////////////////////////////////////////////////////////////////////
579

    
580
  int getColor(int face)
581
    {
582
    return FACE_COLORS[face];
583
    }
584

    
585
///////////////////////////////////////////////////////////////////////////////////////////////////
586

    
587
  ObjectSticker retSticker(int face)
588
    {
589
    return mStickers[face/NUM_FACES];
590
    }
591

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

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

    
599
///////////////////////////////////////////////////////////////////////////////////////////////////
600

    
601
  private void initializeScrambling()
602
    {
603
    int numLayers = getNumLayers();
604

    
605
    if( mScrambleTable ==null )
606
      {
607
      mScrambleTable = new int[NUM_AXIS][numLayers];
608
      }
609
    if( mNumOccurences ==null )
610
      {
611
      int max=0;
612

    
613
      for (ScrambleState mState : mStates)
614
        {
615
        int tmp = mState.getTotal(-1);
616
        if (max < tmp) max = tmp;
617
        }
618

    
619
      mNumOccurences = new int[max];
620
      }
621

    
622
    for(int i=0; i<NUM_AXIS; i++)
623
      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
624
    }
625

    
626
///////////////////////////////////////////////////////////////////////////////////////////////////
627
// PUBLIC API
628

    
629
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
630
    {
631
    if( curr==0 )
632
      {
633
      mCurrState     = 0;
634
      mIndexExcluded =-1;
635
      initializeScrambling();
636
      }
637

    
638
    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
639

    
640
    scramble[curr][0] = info[0];
641
    scramble[curr][1] = info[1];
642
    scramble[curr][2] = info[2];
643

    
644
    mCurrState     = info[3];
645
    mIndexExcluded = info[0];
646
    }
647

    
648
///////////////////////////////////////////////////////////////////////////////////////////////////
649

    
650
  public Static3D[] getRotationAxis()
651
    {
652
    return ROT_AXIS;
653
    }
654

    
655
///////////////////////////////////////////////////////////////////////////////////////////////////
656

    
657
  public int[] getBasicAngle()
658
    {
659
    return BASIC_ANGLE;
660
    }
661

    
662
///////////////////////////////////////////////////////////////////////////////////////////////////
663

    
664
  public int getObjectName(int numLayers)
665
    {
666
    switch(numLayers)
667
      {
668
      case 2: return R.string.skew2;
669
      case 3: return R.string.skew3;
670
      }
671
    return R.string.skew2;
672
    }
673

    
674
///////////////////////////////////////////////////////////////////////////////////////////////////
675

    
676
  public int getInventor(int numLayers)
677
    {
678
    switch(numLayers)
679
      {
680
      case 2: return R.string.skew2_inventor;
681
      case 3: return R.string.skew3_inventor;
682
      }
683
    return R.string.skew2_inventor;
684
    }
685

    
686
///////////////////////////////////////////////////////////////////////////////////////////////////
687

    
688
  public int getComplexity(int numLayers)
689
    {
690
    switch(numLayers)
691
      {
692
      case 2: return 4;
693
      case 3: return 8;
694
      }
695
    return 5;
696
    }
697
}
(37-37/41)