Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyRex.java @ b3c9061a

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
import org.distorted.main.RubikSurfaceView;
37

    
38
import java.util.Random;
39

    
40
import static org.distorted.helpers.FactoryCubit.REX_D;
41

    
42
///////////////////////////////////////////////////////////////////////////////////////////////////
43

    
44
public class TwistyRex extends TwistyObject
45
{
46
  private static final int FACES_PER_CUBIT =6;
47

    
48
  // the four rotation axis of a RubikRex. Must be normalized.
49
  static final Static3D[] ROT_AXIS = new Static3D[]
50
         {
51
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
52
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
53
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
54
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
55
         };
56

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

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

    
72
           new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
73
           new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
74
           new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
75
           new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
76
           new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
77
           new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
78
           new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
79
           new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
80
         };
81

    
82
  private static final int[][] mFaceMap =
83
         {
84
           {  0, 18,18,18,18,18 },
85
           {  0, 18,18,18,18,18 },
86
           {  0, 18,18,18,18,18 },
87
           {  0, 18,18,18,18,18 },
88
           {  1, 18,18,18,18,18 },
89
           {  1, 18,18,18,18,18 },
90
           {  1, 18,18,18,18,18 },
91
           {  1, 18,18,18,18,18 },
92
           {  2, 18,18,18,18,18 },
93
           {  2, 18,18,18,18,18 },
94
           {  2, 18,18,18,18,18 },
95
           {  2, 18,18,18,18,18 },
96
           {  3, 18,18,18,18,18 },
97
           {  3, 18,18,18,18,18 },
98
           {  3, 18,18,18,18,18 },
99
           {  3, 18,18,18,18,18 },
100
           {  4, 18,18,18,18,18 },
101
           {  4, 18,18,18,18,18 },
102
           {  4, 18,18,18,18,18 },
103
           {  4, 18,18,18,18,18 },
104
           {  5, 18,18,18,18,18 },
105
           {  5, 18,18,18,18,18 },
106
           {  5, 18,18,18,18,18 },
107
           {  5, 18,18,18,18,18 },
108

    
109
           {  6, 18,18,18,18,18 },
110
           {  7, 18,18,18,18,18 },
111
           {  8, 18,18,18,18,18 },
112
           {  9, 18,18,18,18,18 },
113
           { 10, 18,18,18,18,18 },
114
           { 11, 18,18,18,18,18 },
115

    
116
           { 16,14, 18,18,18,18 },
117
           { 16,12, 18,18,18,18 },
118
           { 16,15, 18,18,18,18 },
119
           { 16,13, 18,18,18,18 },
120
           { 12,14, 18,18,18,18 },
121
           { 15,12, 18,18,18,18 },
122
           { 15,13, 18,18,18,18 },
123
           { 13,14, 18,18,18,18 },
124
           { 14,17, 18,18,18,18 },
125
           { 12,17, 18,18,18,18 },
126
           { 17,15, 18,18,18,18 },
127
           { 13,17, 18,18,18,18 },
128
         };
129

    
130
  private static MeshBase mCornerMesh, mFaceMesh, mEdgeMesh;
131

    
132
///////////////////////////////////////////////////////////////////////////////////////////////////
133

    
134
  TwistyRex(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
135
            DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
136
    {
137
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.REX, res, scrWidth);
138
    }
139

    
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141
// don't use this
142

    
143
  double[][] getVertices(int cubitType)
144
    {
145
    return null;
146
    }
147

    
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149
// don't use this
150

    
151
  int[][] getVertIndexes(int cubitType)
152
    {
153
    return null;
154
    }
155

    
156
///////////////////////////////////////////////////////////////////////////////////////////////////
157

    
158
  int getNumCubitTypes(int numLayers)
159
    {
160
    return 2;
161
    }
162

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

    
165
  float getScreenRatio()
166
    {
167
    return 1.5f;
168
    }
169

    
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171

    
172
  Static4D[] getQuats()
173
    {
174
    return QUATS;
175
    }
176

    
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178

    
179
  int getNumFaces()
180
    {
181
    return FACE_COLORS.length;
182
    }
183

    
184
///////////////////////////////////////////////////////////////////////////////////////////////////
185

    
186
  boolean shouldResetTextureMaps()
187
    {
188
    return false;
189
    }
190

    
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192

    
193
  int getNumStickerTypes(int numLayers)
194
    {
195
    return 3;
196
    }
197

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

    
200
  float[] getCuts(int numLayers)
201
    {
202
    float C = SQ3*0.15f;   // bit less than 1/6 of the length of the main diagonal
203

    
204
    return new float[] {-C,+C};
205
    }
206

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

    
209
  int getNumCubitFaces()
210
    {
211
    return FACES_PER_CUBIT;
212
    }
213

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

    
216
  float[][] getCubitPositions(int numLayers)
217
    {
218
    final float DIST = 0.50f;
219
    final float DIST2= (1+2*REX_D)/6;
220

    
221
    final float[][] CENTERS = new float[42][];
222

    
223
    CENTERS[ 0] = new float[] { +DIST , +DIST2, +DIST2};
224
    CENTERS[ 1] = new float[] { +DIST , +DIST2, -DIST2};
225
    CENTERS[ 2] = new float[] { +DIST , -DIST2, -DIST2};
226
    CENTERS[ 3] = new float[] { +DIST , -DIST2, +DIST2};
227
    CENTERS[ 4] = new float[] { -DIST , +DIST2, +DIST2};
228
    CENTERS[ 5] = new float[] { -DIST , +DIST2, -DIST2};
229
    CENTERS[ 6] = new float[] { -DIST , -DIST2, -DIST2};
230
    CENTERS[ 7] = new float[] { -DIST , -DIST2, +DIST2};
231
    CENTERS[ 8] = new float[] { +DIST2, +DIST , +DIST2};
232
    CENTERS[ 9] = new float[] { +DIST2, +DIST , -DIST2};
233
    CENTERS[10] = new float[] { -DIST2, +DIST , -DIST2};
234
    CENTERS[11] = new float[] { -DIST2, +DIST , +DIST2};
235
    CENTERS[12] = new float[] { +DIST2, -DIST , +DIST2};
236
    CENTERS[13] = new float[] { +DIST2, -DIST , -DIST2};
237
    CENTERS[14] = new float[] { -DIST2, -DIST , -DIST2};
238
    CENTERS[15] = new float[] { -DIST2, -DIST , +DIST2};
239
    CENTERS[16] = new float[] { +DIST2, +DIST2, +DIST };
240
    CENTERS[17] = new float[] { +DIST2, -DIST2, +DIST };
241
    CENTERS[18] = new float[] { -DIST2, -DIST2, +DIST };
242
    CENTERS[19] = new float[] { -DIST2, +DIST2, +DIST };
243
    CENTERS[20] = new float[] { +DIST2, +DIST2, -DIST };
244
    CENTERS[21] = new float[] { +DIST2, -DIST2, -DIST };
245
    CENTERS[22] = new float[] { -DIST2, -DIST2, -DIST };
246
    CENTERS[23] = new float[] { -DIST2, +DIST2, -DIST };
247

    
248
    CENTERS[24] = new float[] { +DIST , +0.00f, +0.00f};
249
    CENTERS[25] = new float[] { -DIST , +0.00f, +0.00f};
250
    CENTERS[26] = new float[] { +0.00f, +DIST , +0.00f};
251
    CENTERS[27] = new float[] { +0.00f, -DIST , +0.00f};
252
    CENTERS[28] = new float[] { +0.00f, +0.00f, +DIST };
253
    CENTERS[29] = new float[] { +0.00f, +0.00f, -DIST };
254

    
255
    CENTERS[30] = new float[] { +0.00f, +DIST , +DIST };
256
    CENTERS[31] = new float[] { +DIST , +0.00f, +DIST };
257
    CENTERS[32] = new float[] { +0.00f, -DIST , +DIST };
258
    CENTERS[33] = new float[] { -DIST , +0.00f, +DIST };
259
    CENTERS[34] = new float[] { +DIST , +DIST , +0.00f};
260
    CENTERS[35] = new float[] { +DIST , -DIST , +0.00f};
261
    CENTERS[36] = new float[] { -DIST , -DIST , +0.00f};
262
    CENTERS[37] = new float[] { -DIST , +DIST , +0.00f};
263
    CENTERS[38] = new float[] { +0.00f, +DIST , -DIST };
264
    CENTERS[39] = new float[] { +DIST , +0.00f, -DIST };
265
    CENTERS[40] = new float[] { +0.00f, -DIST , -DIST };
266
    CENTERS[41] = new float[] { -DIST , +0.00f, -DIST };
267

    
268
    return CENTERS;
269
    }
270

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

    
273
  private Static4D getQuat(int cubit)
274
    {
275
    switch(cubit)
276
      {
277
      case  0: return new Static4D(+SQ2/2,     0,+SQ2/2,     0);
278
      case  1: return QUATS[5];
279
      case  2: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
280
      case  3: return QUATS[8];
281
      case  4: return QUATS[6];
282
      case  5: return new Static4D(-SQ2/2,     0,+SQ2/2,     0);
283
      case  6: return QUATS[11];
284
      case  7: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
285
      case  8: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
286
      case  9: return QUATS[10];
287
      case 10: return new Static4D(     0,+SQ2/2,+SQ2/2,     0);
288
      case 11: return QUATS[4];
289
      case 12: return QUATS[9];
290
      case 13: return new Static4D(-SQ2/2,     0,     0, SQ2/2);
291
      case 14: return QUATS[7];
292
      case 15: return new Static4D(     0,-SQ2/2,+SQ2/2,     0);
293
      case 16: return new Static4D(     0,     0,-SQ2/2, SQ2/2);
294
      case 17: return QUATS[0];
295
      case 18: return new Static4D(     0,     0,+SQ2/2, SQ2/2);
296
      case 19: return QUATS[3];
297
      case 20: return QUATS[1];
298
      case 21: return new Static4D(+SQ2/2,-SQ2/2,     0,     0);
299
      case 22: return QUATS[2];
300
      case 23: return new Static4D(+SQ2/2,+SQ2/2,     0,     0);
301

    
302
      case 24: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
303
      case 25: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
304
      case 26: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
305
      case 27: return new Static4D(-SQ2/2,     0,     0, SQ2/2);
306
      case 28: return QUATS[0];
307
      case 29: return QUATS[1];
308

    
309
      case 30: return QUATS[0];
310
      case 31: return new Static4D(     0,     0,+SQ2/2, SQ2/2);
311
      case 32: return QUATS[3];
312
      case 33: return new Static4D(     0,     0,-SQ2/2, SQ2/2);
313
      case 34: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
314
      case 35: return QUATS[7];
315
      case 36: return QUATS[9];
316
      case 37: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
317
      case 38: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
318
      case 39: return QUATS[8];
319
      case 40: return QUATS[1];
320
      case 41: return QUATS[6];
321
      }
322

    
323
    return QUATS[0];
324
    }
325

    
326
///////////////////////////////////////////////////////////////////////////////////////////////////
327

    
328
  MeshBase createCubitMesh(int cubit, int numLayers)
329
    {
330
    MeshBase mesh;
331

    
332
    if( cubit<24 )
333
      {
334
      if( mCornerMesh==null ) mCornerMesh = FactoryCubit.getInstance().createRexCornerMesh();
335
      mesh = mCornerMesh.copy(true);
336
      }
337
    else if( cubit<30 )
338
      {
339
      if( mFaceMesh==null ) mFaceMesh = FactoryCubit.getInstance().createRexFaceMesh();
340
      mesh = mFaceMesh.copy(true);
341
      }
342
    else
343
      {
344
      if( mEdgeMesh==null ) mEdgeMesh = FactoryCubit.getInstance().createRexEdgeMesh();
345
      mesh = mEdgeMesh.copy(true);
346
      }
347

    
348
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit), new Static3D(0,0,0) );
349
    mesh.apply(quat,0xffffffff,0);
350

    
351
    return mesh;
352
    }
353

    
354
///////////////////////////////////////////////////////////////////////////////////////////////////
355

    
356
  int getFaceColor(int cubit, int cubitface, int numLayers)
357
    {
358
    return mFaceMap[cubit][cubitface];
359
    }
360

    
361
///////////////////////////////////////////////////////////////////////////////////////////////////
362

    
363
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
364
    {
365
    int COLORS = FACE_COLORS.length;
366
    FactorySticker factory = FactorySticker.getInstance();
367
    float S1 = 0.050f;
368
    float S2 = 0.051f;
369
    float R1 = 0.07f;
370
    float R2 = 0.02f;
371
    float R3 = 0.06f;
372
    float R4 = 0.04f;
373

    
374
    if( face<COLORS )
375
      {
376
      factory.drawRexCornerSticker(canvas, paint, left, top, FACE_COLORS[face%COLORS], S1, R2, R3);
377
      }
378
    else if( face<2*COLORS )
379
      {
380
      float[] vertices = { -REX_D,0.0f, 0.0f, -REX_D, +REX_D, 0.0f, 0.0f, +REX_D};
381
      factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S1, FACE_COLORS[face%COLORS], R4);
382
      }
383
    else
384
      {
385
      factory.drawRexEdgeSticker(canvas, paint, left, top, FACE_COLORS[face%COLORS], S2, R1);
386
      }
387
    }
388

    
389
///////////////////////////////////////////////////////////////////////////////////////////////////
390

    
391
  float returnMultiplier()
392
    {
393
    return 2.0f;
394
    }
395

    
396
///////////////////////////////////////////////////////////////////////////////////////////////////
397

    
398
  float[] getRowChances(int numLayers)
399
    {
400
    return new float[] { 0.5f, 0.5f, 1.0f };
401
    }
402

    
403
///////////////////////////////////////////////////////////////////////////////////////////////////
404
// PUBLIC API
405

    
406
  public Static3D[] getRotationAxis()
407
    {
408
    return ROT_AXIS;
409
    }
410

    
411
///////////////////////////////////////////////////////////////////////////////////////////////////
412

    
413
  public int getBasicAngle()
414
    {
415
    return 3;
416
    }
417

    
418
///////////////////////////////////////////////////////////////////////////////////////////////////
419

    
420
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
421
    {
422
    if( num==0 )
423
      {
424
      scramble[num][0] = rnd.nextInt(ROTATION_AXIS.length);
425
      }
426
    else
427
      {
428
      int newVector = rnd.nextInt(ROTATION_AXIS.length-1);
429
      scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
430
      }
431

    
432
    float rowFloat = rnd.nextFloat();
433

    
434
    for(int row=0; row<mRowChances.length; row++)
435
      {
436
      if( rowFloat<=mRowChances[row] )
437
        {
438
        scramble[num][1] = row;
439
        break;
440
        }
441
      }
442

    
443
    switch( rnd.nextInt(2) )
444
      {
445
      case 0: scramble[num][2] = -1; break;
446
      case 1: scramble[num][2] =  1; break;
447
      }
448
    }
449

    
450
///////////////////////////////////////////////////////////////////////////////////////////////////
451
// remember about the double cover or unit quaternions!
452

    
453
  private int mulQuat(int q1, int q2)
454
    {
455
    Static4D result = RubikSurfaceView.quatMultiply(QUATS[q1],QUATS[q2]);
456

    
457
    float rX = result.get0();
458
    float rY = result.get1();
459
    float rZ = result.get2();
460
    float rW = result.get3();
461

    
462
    final float MAX_ERROR = 0.1f;
463
    float dX,dY,dZ,dW;
464

    
465
    for(int i=0; i<QUATS.length; i++)
466
      {
467
      dX = QUATS[i].get0() - rX;
468
      dY = QUATS[i].get1() - rY;
469
      dZ = QUATS[i].get2() - rZ;
470
      dW = QUATS[i].get3() - rW;
471

    
472
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
473
          dY<MAX_ERROR && dY>-MAX_ERROR &&
474
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
475
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
476

    
477
      dX = QUATS[i].get0() + rX;
478
      dY = QUATS[i].get1() + rY;
479
      dZ = QUATS[i].get2() + rZ;
480
      dW = QUATS[i].get3() + rW;
481

    
482
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
483
          dY<MAX_ERROR && dY>-MAX_ERROR &&
484
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
485
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
486
      }
487

    
488
    return -1;
489
    }
490

    
491
///////////////////////////////////////////////////////////////////////////////////////////////////
492
// The Rex is solved if and only if:
493
//
494
// 1) all 12 of its edge cubits are rotated with the same quat
495
// 2) all its face & corner cubits are rotated with the same quat like the edge ones,
496
//    and optionally they also might be upside down.
497
//
498
// i.e.
499
// corners ( 0, 1, 2, 3, 4, 5, 6, 7) and faces (24,25) - might be extra QUAT[1]
500
// corners ( 8, 9,10,11,12,13,14,15) and faces (26,27) - might be extra QUAT[2]
501
// corners (16,17,18,19,20,21,22,23) and faces (28,29) - might be extra QUAT[3]
502

    
503
  public boolean isSolved()
504
    {
505
    int q1,q = CUBITS[30].mQuatIndex;
506

    
507
    for(int i=31; i<42; i++)
508
      {
509
      if( CUBITS[i].mQuatIndex != q) return false;
510
      }
511

    
512
    q1 = mulQuat(q,1);
513

    
514
    for(int i=0; i<8; i++)
515
      {
516
      if( CUBITS[i].mQuatIndex != q && CUBITS[i].mQuatIndex != q1 ) return false;
517
      }
518

    
519
    if( CUBITS[24].mQuatIndex != q && CUBITS[24].mQuatIndex != q1 ) return false;
520
    if( CUBITS[25].mQuatIndex != q && CUBITS[25].mQuatIndex != q1 ) return false;
521

    
522
    q1 = mulQuat(q,2);
523

    
524
    for(int i=8; i<16; i++)
525
      {
526
      if( CUBITS[i].mQuatIndex != q && CUBITS[i].mQuatIndex != q1 ) return false;
527
      }
528

    
529
    if( CUBITS[26].mQuatIndex != q && CUBITS[26].mQuatIndex != q1 ) return false;
530
    if( CUBITS[27].mQuatIndex != q && CUBITS[27].mQuatIndex != q1 ) return false;
531

    
532
    q1 = mulQuat(q,3);
533

    
534
    for(int i=16; i<24; i++)
535
      {
536
      if( CUBITS[i].mQuatIndex != q && CUBITS[i].mQuatIndex != q1 ) return false;
537
      }
538

    
539
    if( CUBITS[28].mQuatIndex != q && CUBITS[28].mQuatIndex != q1 ) return false;
540
    if( CUBITS[29].mQuatIndex != q && CUBITS[29].mQuatIndex != q1 ) return false;
541

    
542
    return true;
543
    }
544

    
545
///////////////////////////////////////////////////////////////////////////////////////////////////
546
// only needed for solvers - there are no Rex solvers ATM
547

    
548
  public String retObjectString()
549
    {
550
    return "";
551
    }
552

    
553
///////////////////////////////////////////////////////////////////////////////////////////////////
554

    
555
  public int getObjectName(int numLayers)
556
    {
557
    return R.string.rex3;
558
    }
559

    
560
///////////////////////////////////////////////////////////////////////////////////////////////////
561

    
562
  public int getInventor(int numLayers)
563
    {
564
    return R.string.rex3_inventor;
565
    }
566

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

    
569
  public int getComplexity(int numLayers)
570
    {
571
    return 3;
572
    }
573
}
(32-32/33)