Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyCuboid.java @ 3f7fad4f

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 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.objectlib.objects;
21

    
22
import static org.distorted.objectlib.main.Movement.MOVEMENT_SHAPECHANGE;
23
import static org.distorted.objectlib.main.Movement.TYPE_NOT_SPLIT;
24

    
25
import java.io.InputStream;
26

    
27
import org.distorted.library.type.Static3D;
28
import org.distorted.library.type.Static4D;
29

    
30
import org.distorted.objectlib.main.MovementC;
31
import org.distorted.objectlib.main.ObjectControl;
32
import org.distorted.objectlib.main.ObjectType;
33
import org.distorted.objectlib.helpers.ObjectShape;
34
import org.distorted.objectlib.helpers.ObjectSticker;
35
import org.distorted.objectlib.helpers.ScrambleState;
36
import org.distorted.objectlib.main.Twisty6;
37

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

    
40
public class TwistyCuboid extends Twisty6
41
{
42
  static final Static3D[] ROT_AXIS = new Static3D[]
43
         {
44
           new Static3D(1,0,0),
45
           new Static3D(0,1,0),
46
           new Static3D(0,0,1)
47
         };
48

    
49
  private ScrambleState[] mStates;
50
  private Static4D[] mQuats;
51
  private float[][] mCuts;
52
  private int[] mBasicAngle;
53
  private ObjectSticker[] mStickers;
54

    
55
///////////////////////////////////////////////////////////////////////////////////////////////////
56

    
57
  public TwistyCuboid(int[] numL, Static4D quat, Static3D move, InputStream stream)
58
    {
59
    super(numL, (numL[0]+numL[1]+numL[2])/3.0f, quat, move, stream);
60
    }
61

    
62
///////////////////////////////////////////////////////////////////////////////////////////////////
63

    
64
  private int[] createEdges(int size, boolean full, int vertex)
65
    {
66
    if( size==1 ) return null;
67

    
68
    if( full )
69
      {
70
      int[] ret = new int[9*size];
71

    
72
      for(int l=0; l<size; l++)
73
        {
74
        ret[9*l  ] = l;
75
        ret[9*l+1] =-1;
76
        ret[9*l+2] = vertex;
77
        ret[9*l+3] = l;
78
        ret[9*l+4] = 1;
79
        ret[9*l+5] = vertex;
80
        ret[9*l+6] = l;
81
        ret[9*l+7] = 2;
82
        ret[9*l+8] = vertex;
83
        }
84

    
85
      return ret;
86
      }
87
    else
88
      {
89
      int[] ret = new int[6*size];
90

    
91
      for(int l=0; l<size; l++)
92
        {
93
        ret[6*l  ] = l;
94
        ret[6*l+1] = 1;
95
        ret[6*l+2] = vertex;
96
        ret[6*l+3] = l;
97
        ret[6*l+4] =-1;
98
        ret[6*l+5] = vertex;
99
        }
100

    
101
      return ret;
102
      }
103
    }
104

    
105
///////////////////////////////////////////////////////////////////////////////////////////////////
106

    
107
  public ScrambleState[] getScrambleStates()
108
    {
109
    if( mStates==null )
110
      {
111
      int[] numLayers = getNumLayers();
112

    
113
      int X = numLayers[0];
114
      int Y = numLayers[1];
115
      int Z = numLayers[2];
116

    
117
      int[][] mX = new int[16][];
118
      int[][] mY = new int[16][];
119
      int[][] mZ = new int[16][];
120

    
121
      for(int i=0; i<16; i++)
122
        {
123
        mX[i] = createEdges(X,Y==Z,i);
124
        mY[i] = createEdges(Y,X==Z,i);
125
        mZ[i] = createEdges(Z,X==Y,i);
126
        }
127

    
128
      if( X>1 && Y>1 && Z>1 )
129
        {
130
        mStates = new ScrambleState[]
131
          {
132
          new ScrambleState( new int[][] { mX[ 1], mY[ 2], mZ[ 3] } ),  //  0 0
133
          new ScrambleState( new int[][] {   null, mY[ 4], mZ[ 5] } ),  //  1 x
134
          new ScrambleState( new int[][] { mX[ 6],   null, mZ[ 7] } ),  //  2 y
135
          new ScrambleState( new int[][] { mX[ 8], mY[ 9],   null } ),  //  3 z
136
          new ScrambleState( new int[][] { mX[10],   null, mZ[ 7] } ),  //  4 xy
137
          new ScrambleState( new int[][] { mX[11], mY[ 9],   null } ),  //  5 xz
138
          new ScrambleState( new int[][] {   null, mY[12], mZ[ 5] } ),  //  6 yx
139
          new ScrambleState( new int[][] { mX[ 8], mY[13],   null } ),  //  7 yz
140
          new ScrambleState( new int[][] {   null, mY[ 4], mZ[14] } ),  //  8 zx
141
          new ScrambleState( new int[][] { mX[ 6],   null, mZ[15] } ),  //  9 zy
142
          new ScrambleState( new int[][] {   null,   null, mZ[ 5] } ),  // 10 xyx
143
          new ScrambleState( new int[][] {   null, mY[ 4],   null } ),  // 11 xzx
144
          new ScrambleState( new int[][] {   null,   null, mZ[ 7] } ),  // 12 yxy
145
          new ScrambleState( new int[][] { mX[ 6],   null,   null } ),  // 13 yzy
146
          new ScrambleState( new int[][] {   null, mY[ 9],   null } ),  // 14 zxz
147
          new ScrambleState( new int[][] { mX[ 8],   null,   null } ),  // 15 zyz
148
          };
149
        }
150
      else if( X==1 && Y==1 && Z==1 )
151
        {
152
        int[] state = new int[] {0,-1,0,0,1,0,0,2,0};
153

    
154
        mStates = new ScrambleState[]
155
          {
156
          new ScrambleState( new int[][] { state, state, state } )
157
          };
158
        }
159
      else
160
        {
161
        mStates = new ScrambleState[]
162
          {
163
          new ScrambleState( new int[][] { mX[ 0], mY[ 0], mZ[ 0] } )
164
          };
165
        }
166

    
167
      }
168

    
169
    return mStates;
170
    }
171

    
172
///////////////////////////////////////////////////////////////////////////////////////////////////
173

    
174
  private void initializeQuats()
175
    {
176
    mQuats = new Static4D[]
177
         {
178
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
179
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
180
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
181
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
182

    
183
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
184
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
185
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
186
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
187
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
188
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
189
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
190
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
191
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
192
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
193
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
194
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
195

    
196
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
197
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
198
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
199
         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
200
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
201
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
202
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
203
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
204
         };
205
    }
206

    
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208

    
209
  public int[] getSolvedQuats(int cubit, int[] numLayers)
210
    {
211
    if( mQuats ==null ) initializeQuats();
212
    int status = retCubitSolvedStatus(cubit,numLayers);
213
    return status<0 ? null : buildSolvedQuats(MovementC.FACE_AXIS[status], mQuats);
214
    }
215

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

    
218
  public ObjectShape getObjectShape(int variant)
219
    {
220
    int extraI, extraV, num, numL = getNumLayers()[0];
221
    float height;
222

    
223
    switch(numL)
224
        {
225
        case 2 : num = 6; extraI = 2; extraV = 2; height = 0.045f; break;
226
        case 3 : num = 5; extraI = 2; extraV = 2; height = 0.045f; break;
227
        case 4 : num = 5; extraI = 1; extraV = 1; height = 0.045f; break;
228
        default: num = 5; extraI = 0; extraV = 0; height = 0.045f; break;
229
        }
230

    
231
    double[][] vertices = new double[][]
232
          {
233
              { 0.5, 0.5, 0.5 },
234
              { 0.5, 0.5,-0.5 },
235
              { 0.5,-0.5, 0.5 },
236
              { 0.5,-0.5,-0.5 },
237
              {-0.5, 0.5, 0.5 },
238
              {-0.5, 0.5,-0.5 },
239
              {-0.5,-0.5, 0.5 },
240
              {-0.5,-0.5,-0.5 },
241
          };
242

    
243
    int[][] vert_indices = new int[][]
244
          {
245
              {2,3,1,0},
246
              {7,6,4,5},
247
              {4,0,1,5},
248
              {7,3,2,6},
249
              {6,2,0,4},
250
              {3,7,5,1}
251
          };
252

    
253
    float[][] corners   = new float[][] { {0.036f,0.12f} };
254
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
255
    float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
256
    int[] centerIndices = new int[] { 0,0,0,0,0,0,0,0 };
257

    
258
    if( variant==0 )
259
      {
260
      float[][] bands   = new float[][] { {height,35,0.5f,0.7f,num,extraI,extraV} };
261
      int[] bandIndices = new int[] { 0,0,0,0,0,0};
262
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
263
      }
264
    else
265
      {
266
      int extraI2 = numL<=3 ? num-2 : 0;
267

    
268
      float[][] bands   = new float[][]
269
        {
270
          {height,35,0.5f,0.7f,num,extraI ,extraV},
271
          {height,35,0.5f,0.7f,  2,extraI2,     0},
272
          {height,35,0.5f,0.7f,  2,      0,     0},
273
        };
274
      int[] bandIndices = new int[] { 1,1,1,1,0,2};
275
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
276
      }
277
    }
278

    
279
///////////////////////////////////////////////////////////////////////////////////////////////////
280

    
281
  private int getCenterNum(int cubit, int[] numLayers)
282
    {
283
    int num = cubit - getNumCornersAndEdges(numLayers);
284

    
285
    if( num>=0 )
286
      {
287
      int numLR = (numLayers[1]-2)*(numLayers[2]-2);
288
      if( num<  numLR ) return 0;
289
      if( num<2*numLR ) return 1;
290
      num -= 2*numLR;
291

    
292
      int numTD = (numLayers[0]-2)*(numLayers[2]-2);
293
      if( num<  numTD ) return 2;
294
      if( num<2*numTD ) return 3;
295
      num -= 2*numTD;
296

    
297
      int numFB = (numLayers[0]-2)*(numLayers[1]-2);
298
      if( num<  numFB ) return 4;
299
      if( num<2*numFB ) return 5;
300
      }
301

    
302
    return -1;
303
    }
304

    
305
///////////////////////////////////////////////////////////////////////////////////////////////////
306

    
307
  private int getNumCornersAndEdges(int[] numLayers)
308
    {
309
    int x = numLayers[0];
310
    int y = numLayers[1];
311
    int z = numLayers[2];
312

    
313
    return ( x==1 || y==1 || z==1 ) ? x*y*z : 4*( (x-2)+(y-2)+(z-2) ) + 8;
314
    }
315

    
316
///////////////////////////////////////////////////////////////////////////////////////////////////
317

    
318
  public float[][] getCubitPositions(int[] numLayers)
319
    {
320
    final int X = numLayers[0];
321
    final int Y = numLayers[1];
322
    final int Z = numLayers[2];
323

    
324
    final float lenX = 0.5f*(X-1);
325
    final float lenY = 0.5f*(Y-1);
326
    final float lenZ = 0.5f*(Z-1);
327

    
328
    int curPos = 0;
329

    
330
    if( X==1 )
331
      {
332
      float[][] pos = new float[X*Y*Z][];
333

    
334
      for(int y=0; y<Y; y++)
335
        for(int z=0; z<Z; z++) pos[curPos++] = new float[] {+lenX,y-lenY,z-lenZ};
336

    
337
      return pos;
338
      }
339

    
340
    if( Y==1 )
341
      {
342
      float[][] pos = new float[X*Y*Z][];
343

    
344
      for(int x=0; x<X; x++)
345
        for(int z=0; z<Z; z++) pos[curPos++] = new float[] {x-lenX,+lenY,z-lenZ};
346

    
347
      return pos;
348
      }
349

    
350
    if( Z==1 )
351
      {
352
      float[][] pos = new float[X*Y*Z][];
353

    
354
      for(int x=0; x<X; x++)
355
        for(int y=0; y<Y; y++) pos[curPos++] = new float[] {x-lenX,y-lenY,+lenZ};
356

    
357
      return pos;
358
      }
359

    
360
    int numCubits = X*Y*Z - (X-2)*(Y-2)*(Z-2);
361
    float[][] pos = new float[numCubits][];
362

    
363
    pos[curPos++] = new float[] {-lenX,-lenY,-lenZ};
364
    pos[curPos++] = new float[] {-lenX,-lenY,+lenZ};
365
    pos[curPos++] = new float[] {-lenX,+lenY,-lenZ};
366
    pos[curPos++] = new float[] {-lenX,+lenY,+lenZ};
367
    pos[curPos++] = new float[] {+lenX,-lenY,-lenZ};
368
    pos[curPos++] = new float[] {+lenX,-lenY,+lenZ};
369
    pos[curPos++] = new float[] {+lenX,+lenY,-lenZ};
370
    pos[curPos++] = new float[] {+lenX,+lenY,+lenZ};
371

    
372
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  -lenY,  -lenZ };
373
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  -lenY,  +lenZ };
374
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  +lenY,  -lenZ };
375
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  +lenY,  +lenZ };
376
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  -lenX, i-lenY,  -lenZ };
377
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  -lenX, i-lenY,  +lenZ };
378
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  +lenX, i-lenY,  -lenZ };
379
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  +lenX, i-lenY,  +lenZ };
380
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  -lenX,  -lenY, i-lenZ };
381
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  -lenX,  +lenY, i-lenZ };
382
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  +lenX,  -lenY, i-lenZ };
383
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  +lenX,  +lenY, i-lenZ };
384

    
385
    for(int y=1; y<Y-1; y++)
386
      for(int z=1; z<Z-1; z++) pos[curPos++] = new float[] {+lenX,y-lenY,z-lenZ};
387

    
388
    for(int y=1; y<Y-1; y++)
389
      for(int z=1; z<Z-1; z++) pos[curPos++] = new float[] {-lenX,y-lenY,z-lenZ};
390

    
391
    for(int x=1; x<X-1; x++)
392
      for(int z=1; z<Z-1; z++) pos[curPos++] = new float[] {x-lenX,+lenY,z-lenZ};
393

    
394
    for(int x=1; x<X-1; x++)
395
      for(int z=1; z<Z-1; z++) pos[curPos++] = new float[] {x-lenX,-lenY,z-lenZ};
396

    
397
    for(int x=1; x<X-1; x++)
398
      for(int y=1; y<Y-1; y++) pos[curPos++] = new float[] {x-lenX,y-lenY,+lenZ};
399

    
400
    for(int x=1; x<X-1; x++)
401
      for(int y=1; y<Y-1; y++) pos[curPos++] = new float[] {x-lenX,y-lenY,-lenZ};
402

    
403
    return pos;
404
    }
405

    
406
///////////////////////////////////////////////////////////////////////////////////////////////////
407

    
408
  public Static4D getQuat(int cubit, int[] numLayers)
409
    {
410
    if( mQuats ==null ) initializeQuats();
411

    
412
    int centerNum = getCenterNum(cubit,numLayers);
413

    
414
    switch(centerNum)
415
      {
416
      case 0 : return mQuats[13];
417
      case 1 : return mQuats[12];
418
      case 2 : return mQuats[ 8];
419
      case 3 : return mQuats[ 9];
420
      case 4 : return mQuats[ 0];
421
      case 5 : return mQuats[ 1];
422
      default: return mQuats[ 0];
423
      }
424
    }
425

    
426
///////////////////////////////////////////////////////////////////////////////////////////////////
427

    
428
  public int getNumCubitVariants(int[] numLayers)
429
    {
430
    return numLayers[0]>2 ? 2:1;
431
    }
432

    
433
///////////////////////////////////////////////////////////////////////////////////////////////////
434

    
435
  public int getCubitVariant(int cubit, int[] numLayers)
436
    {
437
    return cubit < getNumCornersAndEdges(numLayers) ? 0 : 1;
438
    }
439

    
440
///////////////////////////////////////////////////////////////////////////////////////////////////
441

    
442
  public int getVariantFaceColor(int variant, int face, int[] numLayers)
443
    {
444
    return 0;
445
    }
446

    
447
///////////////////////////////////////////////////////////////////////////////////////////////////
448

    
449
  public int getCubitFaceColor(int cubit, int face, int[] numLayers)
450
    {
451
    int centerNum = getCenterNum(cubit,numLayers);
452

    
453
    if( centerNum<0 )
454
      {
455
      int axis = face/2;
456
      return CUBITS[cubit].getRotRow(axis) == (face%2==0 ? (1<<(numLayers[axis]-1)):1) ? face : -1;
457
      }
458
    else
459
      {
460
      return face==4 ? centerNum : -1;
461
      }
462
    }
463

    
464
///////////////////////////////////////////////////////////////////////////////////////////////////
465

    
466
  public ObjectSticker retSticker(int sticker)
467
    {
468
    if( mStickers==null )
469
      {
470
      final float[][] STICKERS = new float[][]  { { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f } };
471
      final float radius = 0.10f;
472
      final float[] radii = {radius,radius,radius,radius};
473
      mStickers = new ObjectSticker[STICKERS.length];
474
      float stroke = 0.08f;
475

    
476
      if( ObjectControl.isInIconMode() )
477
        {
478
        int[] numLayers = getNumLayers();
479

    
480
        switch(numLayers[0])
481
          {
482
          case 2: stroke*=1.8f; break;
483
          case 3: stroke*=2.0f; break;
484
          case 4: stroke*=2.1f; break;
485
          default:stroke*=2.2f; break;
486
          }
487
        }
488

    
489
      mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke );
490
      }
491

    
492
    return mStickers[sticker];
493
    }
494

    
495
///////////////////////////////////////////////////////////////////////////////////////////////////
496

    
497
  public Static4D[] getQuats()
498
    {
499
    if( mQuats ==null ) initializeQuats();
500
    return mQuats;
501
    }
502

    
503
///////////////////////////////////////////////////////////////////////////////////////////////////
504

    
505
  public float[][] getCuts(int[] numLayers)
506
    {
507
    if( mCuts==null )
508
      {
509
      mCuts = new float[3][];
510

    
511
      for(int axis=0; axis<3; axis++)
512
        {
513
        int len = numLayers[axis];
514
        float start = (2-len)*0.5f;
515

    
516
        if( len>=2 )
517
          {
518
          mCuts[axis] = new float[len-1];
519
          for(int i=0; i<len-1; i++) mCuts[axis][i] = start+i;
520
          }
521
        }
522
      }
523

    
524
    return mCuts;
525
    }
526

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

    
529
  public boolean[][] getLayerRotatable(int[] numLayers)
530
    {
531
    int numAxis = ROT_AXIS.length;
532
    boolean[][] layerRotatable = new boolean[numAxis][];
533

    
534
    for(int i=0; i<numAxis; i++)
535
      {
536
      layerRotatable[i] = new boolean[numLayers[i]];
537
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
538
      }
539

    
540
    return layerRotatable;
541
    }
542

    
543
///////////////////////////////////////////////////////////////////////////////////////////////////
544

    
545
  public int getMovementType()
546
    {
547
    return MOVEMENT_SHAPECHANGE;
548
    }
549

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

    
552
  public int getMovementSplit()
553
    {
554
    return TYPE_NOT_SPLIT;
555
    }
556

    
557
///////////////////////////////////////////////////////////////////////////////////////////////////
558

    
559
  public int[][][] getEnabled()
560
    {
561
    return new int[][][]
562
      {
563
          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
564
      };
565
    }
566

    
567
///////////////////////////////////////////////////////////////////////////////////////////////////
568

    
569
  public float[] getDist3D(int[] numLayers)
570
    {
571
    float avg = (numLayers[0]+numLayers[1]+numLayers[2])/3.0f;
572

    
573
    return new float[]
574
        {
575
        0.5f*numLayers[0]/avg,
576
        0.5f*numLayers[0]/avg,
577
        0.5f*numLayers[1]/avg,
578
        0.5f*numLayers[1]/avg,
579
        0.5f*numLayers[2]/avg,
580
        0.5f*numLayers[2]/avg,
581
        };
582
    }
583

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

    
586
  public int getSolvedFunctionIndex()
587
    {
588
    return 0;
589
    }
590

    
591
///////////////////////////////////////////////////////////////////////////////////////////////////
592

    
593
  public int getNumStickerTypes(int[] numLayers)
594
    {
595
    return 1;
596
    }
597

    
598
///////////////////////////////////////////////////////////////////////////////////////////////////
599

    
600
  public int getNumCubitFaces()
601
    {
602
    return 6;
603
    }
604

    
605
///////////////////////////////////////////////////////////////////////////////////////////////////
606
// PUBLIC API
607

    
608
  public Static3D[] getRotationAxis()
609
    {
610
    return ROT_AXIS;
611
    }
612

    
613
///////////////////////////////////////////////////////////////////////////////////////////////////
614

    
615
  public int[] getBasicAngle()
616
    {
617
    if( mBasicAngle==null )
618
      {
619
      int[] num = getNumLayers();
620
      int x = num[1]==num[2] ? 4 : 2;
621
      int y = num[0]==num[2] ? 4 : 2;
622
      int z = num[0]==num[1] ? 4 : 2;
623

    
624
      mBasicAngle = new int[] { x,y,z };
625
      }
626
    return mBasicAngle;
627
    }
628

    
629
///////////////////////////////////////////////////////////////////////////////////////////////////
630

    
631
  public ObjectType intGetObjectType(int[] numLayers)
632
    {
633
    int x = numLayers[0];
634
    int y = numLayers[1];
635

    
636
    switch(x)
637
      {
638
      case 2: switch(y)
639
                {
640
                case 2: return ObjectType.CUBE_2;
641
                case 3: return ObjectType.CU_232;
642
                }
643
      case 3: switch(y)
644
                {
645
                case 2: return ObjectType.CU_323;
646
                case 3: return ObjectType.CUBE_3;
647
                case 4: return ObjectType.CU_343;
648
                }
649
      case 4: return ObjectType.CUBE_4;
650
      case 5: return ObjectType.CUBE_5;
651
      }
652

    
653
    return ObjectType.CUBE_3;
654
    }
655

    
656
///////////////////////////////////////////////////////////////////////////////////////////////////
657

    
658
  public String getObjectName()
659
    {
660
    switch(getNumLayers()[0])
661
      {
662
      case 2: return "Pocket Cube";
663
      case 3: return "Rubik Cube";
664
      case 4: return "Rubik's Revenge";
665
      case 5: return "Professor's Cube";
666
      }
667
    return "Rubik Cube";
668
    }
669

    
670
///////////////////////////////////////////////////////////////////////////////////////////////////
671

    
672
  public String getInventor()
673
    {
674
    switch(getNumLayers()[0])
675
      {
676
      case 2: return "Larry Nichols";
677
      case 3: return "Ernő Rubik";
678
      case 4: return "Péter Sebestény";
679
      case 5: return "Udo Krell";
680
      }
681
    return "Ernő Rubik";
682
    }
683

    
684
///////////////////////////////////////////////////////////////////////////////////////////////////
685

    
686
  public int getYearOfInvention()
687
    {
688
    switch(getNumLayers()[0])
689
      {
690
      case 2: return 1970;
691
      case 3: return 1974;
692
      case 4: return 1981;
693
      case 5: return 1981;
694
      }
695
    return 1974;
696
    }
697

    
698
///////////////////////////////////////////////////////////////////////////////////////////////////
699

    
700
  public int getComplexity()
701
    {
702
    switch(getNumLayers()[0])
703
      {
704
      case 2: return 4;
705
      case 3: return 6;
706
      case 4: return 8;
707
      case 5: return 10;
708
      }
709
    return 6;
710
    }
711
}
(6-6/25)