Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyKilominx.java @ 31cd7256

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 static org.distorted.helpers.FactoryCubit.COS18;
39
import static org.distorted.helpers.FactoryCubit.COS54;
40
import static org.distorted.helpers.FactoryCubit.SIN18;
41
import static org.distorted.helpers.FactoryCubit.SIN54;
42

    
43
///////////////////////////////////////////////////////////////////////////////////////////////////
44

    
45
public class TwistyKilominx extends TwistyMinx
46
{
47
  private static MeshBase[] mCenterMeshes, mCornerMeshes;
48
  private static MeshBase[][] mEdgeMeshes;
49

    
50
  private static final int[] mCenterFaceMap = new int[]
51
      {
52
        0,0,0,0,1,
53
        1,0,1,1,0,
54
        2,0,1,1,0,
55
        2,2,1,0,2,
56
        2,1,0,0,1,
57
        1,2,0,1,0,
58
        0,1,0,1,1,
59
        0,1,0,2,0,
60
        2,1,2,2,2,
61
        1,0,2,1,2,
62
        2,1,0,1,2,
63
        2,2,2,2,2
64
      };
65

    
66
  private static final int mNumCornerEdgeVariants;
67

    
68
  static
69
    {
70
    int[] sizes = ObjectList.KILO.getSizes();
71
    int variants = sizes.length;
72
    mNumCornerEdgeVariants = sizes[0]==3 ? variants-1 : variants;
73
    }
74

    
75
///////////////////////////////////////////////////////////////////////////////////////////////////
76

    
77
  TwistyKilominx(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
78
                 DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
79
    {
80
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.KILO, res, scrWidth);
81
    }
82

    
83
///////////////////////////////////////////////////////////////////////////////////////////////////
84
// TODO
85

    
86
  double[][] getVertices(int cubitType)
87
    {
88
    return null;
89
    }
90

    
91
///////////////////////////////////////////////////////////////////////////////////////////////////
92
// TODO
93

    
94
  int[][] getVertIndexes(int cubitType)
95
    {
96
    return null;
97
    }
98

    
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100
// 3 --> 1, 5 --> 4, 7 --> 5, 9 --> 6
101

    
102
  int getNumCubitTypes(int numLayers)
103
    {
104
    return numLayers==3 ? 1 : 2 + numLayers/2;
105
    }
106

    
107
///////////////////////////////////////////////////////////////////////////////////////////////////
108

    
109
  private int numCubitsPerCorner(int numLayers)
110
    {
111
    return 3*((numLayers-3)/2)*((numLayers-5)/2) + (numLayers<5 ? 0:1);
112
    }
113

    
114
///////////////////////////////////////////////////////////////////////////////////////////////////
115

    
116
  private int numCubitsPerEdge(int numLayers)
117
    {
118
    return numLayers<5 ? 0 : 2*(numLayers-4);
119
    }
120

    
121
///////////////////////////////////////////////////////////////////////////////////////////////////
122

    
123
  int getNumStickerTypes(int numLayers)
124
    {
125
    return numLayers<5 ? 1 : numLayers/2 + 1;
126
    }
127

    
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129

    
130
  float getScreenRatio()
131
    {
132
    return 1.00f;
133
    }
134

    
135
///////////////////////////////////////////////////////////////////////////////////////////////////
136

    
137
  float[] getCuts(int numLayers)
138
    {
139
    float[] cuts = new float[numLayers-1];
140
    float D = numLayers*MovementMinx.DIST3D;
141
    float E = 2*C1;           // 2*cos(36 deg)
142
    float X = 2*D*E/(1+2*E);  // height of the 'upper' part of a dodecahedron, i.e. put it on a table,
143
                              // its height is then D*2*DIST3D, it has one 'lower' part of height X, one
144
                              // 'middle' part of height Y and one upper part of height X again.
145
                              // It's edge length = numLayers/3.0f.
146
    int num = (numLayers-1)/2;
147
    float G = X*0.5f/num;     // height of one Layer
148

    
149
    for(int i=0; i<num; i++)
150
      {
151
      cuts[        i] = -D + (i+0.5f)*G;
152
      cuts[2*num-1-i] = -cuts[i];
153
      }
154

    
155
    return cuts;
156
    }
157

    
158
///////////////////////////////////////////////////////////////////////////////////////////////////
159
// Fill out mCurrCorner{X,Y,Z} by applying appropriate Quat to mBasicCorner{X,Y,Z}
160
// Appropriate one: QUATS[QUAT_INDICES[corner]].
161

    
162
  private void computeBasicCornerVectors(int corner)
163
    {
164
    Static4D quat = QUATS[QUAT_CORNER_INDICES[corner]];
165

    
166
    mCurrCornerV[0] = RubikSurfaceView.rotateVectorByQuat(mBasicCornerV[0],quat);
167
    mCurrCornerV[1] = RubikSurfaceView.rotateVectorByQuat(mBasicCornerV[1],quat);
168
    mCurrCornerV[2] = RubikSurfaceView.rotateVectorByQuat(mBasicCornerV[2],quat);
169
    }
170

    
171
///////////////////////////////////////////////////////////////////////////////////////////////////
172

    
173
  private float[] computeCorner(int numCubitsPerCorner, int numLayers, int corner, int part)
174
    {
175
    float D = numLayers/3.0f;
176
    float[] corn = CORNERS[corner];
177

    
178
    if( part==0 )
179
      {
180
      return new float[] { corn[0]*D, corn[1]*D, corn[2]*D };
181
      }
182
    else
183
      {
184
      float E = D/(0.5f*(numLayers-1));   // ?? maybe 0.5*
185
      int N = (numCubitsPerCorner-1)/3;
186
      int block = (part-1) % N;
187
      int index = (part-1) / N;
188
      Static4D pri = mCurrCornerV[index];
189
      Static4D sec = mCurrCornerV[(index+2)%3];
190

    
191
      int layers= (numLayers-5)/2;
192
      int multP = (block % layers) + 1;
193
      int multS = (block / layers);
194

    
195
      return new float[] {
196
                          corn[0]*D + (pri.get0()*multP + sec.get0()*multS)*E,
197
                          corn[1]*D + (pri.get1()*multP + sec.get1()*multS)*E,
198
                          corn[2]*D + (pri.get2()*multP + sec.get2()*multS)*E
199
                         };
200
      }
201
    }
202

    
203
///////////////////////////////////////////////////////////////////////////////////////////////////
204

    
205
  private float[] computeCenter(int numLayers, int center, int part)
206
    {
207
    int corner = mCenterMap[center][part];
208
    float[] cent = mCenterCoords[center];
209
    float[] corn = CORNERS[corner];
210
    float D = numLayers/3.0f;
211
    float F = 1.0f - (2.0f*numLayers-6.0f)/(numLayers-1)*COS54*COS54;
212

    
213
    return new float[]
214
      {
215
        D * ( cent[0] + (corn[0]-cent[0])*F),
216
        D * ( cent[1] + (corn[1]-cent[1])*F),
217
        D * ( cent[2] + (corn[2]-cent[2])*F)
218
      };
219
    }
220

    
221
///////////////////////////////////////////////////////////////////////////////////////////////////
222

    
223
  private int computeEdgeType(int cubit, int numCubitsPerCorner, int numCubitsPerEdge)
224
    {
225
    int part = (cubit - NUM_CORNERS*numCubitsPerCorner) % numCubitsPerEdge;
226
    return part - 2*(part/4);
227
    }
228

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

    
231
  private float[] computeEdge(int numLayers, int edge, int part)
232
    {
233
    float D = numLayers/3.0f;
234
    float[] c1 = CORNERS[ mEdgeMap[edge][0] ];
235
    float[] c2 = CORNERS[ mEdgeMap[edge][1] ];
236

    
237
    int leftRight = 2*(part%2) -1;
238
    part /= 2;
239

    
240
    if( part==0 )
241
      {
242
      float T = 0.5f + leftRight/(numLayers-1.0f);
243
      float x = D * (T*c1[0]+(1.0f-T)*c2[0]);
244
      float y = D * (T*c1[1]+(1.0f-T)*c2[1]);
245
      float z = D * (T*c1[2]+(1.0f-T)*c2[2]);
246

    
247
      return new float[] { x, y, z };
248
      }
249
    else
250
      {
251
      int mult = (part+1)/2;
252
      int dir  = (part+1)%2;
253
      float[] center = mCenterCoords[ mEdgeMap[edge][dir+2] ];
254
      float x = 0.5f * D * (c1[0]+c2[0]);
255
      float y = 0.5f * D * (c1[1]+c2[1]);
256
      float z = 0.5f * D * (c1[2]+c2[2]);
257

    
258
      float vX = D*center[0] - x;
259
      float vY = D*center[1] - y;
260
      float vZ = D*center[2] - z;
261

    
262
      float T = 0.5f + leftRight*(mult*SIN18 + 1.0f)/(numLayers-1);
263

    
264
      x = D * (T*c1[0]+(1.0f-T)*c2[0]);
265
      y = D * (T*c1[1]+(1.0f-T)*c2[1]);
266
      z = D * (T*c1[2]+(1.0f-T)*c2[2]);
267

    
268
      float H = mult*D*COS18/(numLayers-1);
269
      H /= (float)Math.sqrt(vX*vX+vY*vY+vZ*vZ);
270

    
271
      return new float[] { x + H*vX, y + H*vY, z + H*vZ };
272
      }
273
    }
274

    
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276

    
277
  float[][] getCubitPositions(int numLayers)
278
    {
279
    if( numLayers<5 ) return CORNERS;
280

    
281
    int numCubitsPerCorner = numCubitsPerCorner(numLayers);
282
    int numCubitsPerEdge   = numCubitsPerEdge(numLayers);
283
    int numCubitsPerCenter = 5;
284
    int numCubits = NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge + NUM_CENTERS*numCubitsPerCenter;
285
    int index=0;
286

    
287
    final float[][] CENTERS = new float[numCubits][];
288

    
289
    for(int corner=0; corner<NUM_CORNERS; corner++)
290
      {
291
      computeBasicCornerVectors(corner);
292

    
293
      for(int part=0; part<numCubitsPerCorner; part++, index++)
294
        {
295
        CENTERS[index] = computeCorner(numCubitsPerCorner,numLayers,corner,part);
296
        }
297
      }
298

    
299
    for(int edge=0; edge<NUM_EDGES; edge++)
300
      {
301
      for(int part=0; part<numCubitsPerEdge; part++, index++)
302
        {
303
        CENTERS[index] = computeEdge(numLayers, edge, part );
304
        }
305
      }
306

    
307
    for(int center=0; center<NUM_CENTERS; center++)
308
      {
309
      for(int part=0; part<numCubitsPerCenter; part++, index++)
310
        {
311
        CENTERS[index] = computeCenter(numLayers,center, part);
312
        }
313
      }
314

    
315
    return CENTERS;
316
    }
317

    
318
///////////////////////////////////////////////////////////////////////////////////////////////////
319

    
320
  private int getQuat(int cubit, int numCubitsPerCorner, int numCubitsPerEdge)
321
    {
322
    if( cubit < NUM_CORNERS*numCubitsPerCorner )
323
      {
324
      int corner = cubit/numCubitsPerCorner;
325
      return QUAT_CORNER_INDICES[corner];
326
      }
327

    
328
    if( cubit < NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge )
329
      {
330
      int edge = (cubit-NUM_CORNERS*numCubitsPerCorner)/numCubitsPerEdge;
331
      return QUAT_EDGE_INDICES[edge];
332
      }
333

    
334
    if( numCubitsPerCorner==0 )
335
      {
336
      return QUAT_CORNER_INDICES[cubit];
337
      }
338
    else
339
      {
340
      cubit -= (NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge);
341
      int numCubitsPerCenter = 5;
342
      int face = cubit/numCubitsPerCenter;
343
      int index= cubit%numCubitsPerCenter;
344
      int corner=mCenterMap[face][index];
345

    
346
      return QUAT_CORNER_INDICES[corner];
347
      }
348
    }
349

    
350
///////////////////////////////////////////////////////////////////////////////////////////////////
351

    
352
  MeshBase createCubitMesh(int cubit, int numLayers)
353
    {
354
    int numCubitsPerCorner = numCubitsPerCorner(numLayers);
355
    int numCubitsPerEdge   = numCubitsPerEdge(numLayers);
356
    int[] sizes = ObjectList.KILO.getSizes();
357
    int variants = sizes.length;
358
    int highestSize = sizes[variants-1];
359
    int lowestSize = sizes[0];
360
    int indexCornerEdge = (numLayers-lowestSize)/2 - (lowestSize==3 ? 1:0);
361
    MeshBase mesh;
362

    
363
    if( mNumCornerEdgeVariants>0 )
364
      {
365
      if( mCornerMeshes==null ) mCornerMeshes = new MeshBase[mNumCornerEdgeVariants];
366
      if( mEdgeMeshes  ==null ) mEdgeMeshes   = new MeshBase[mNumCornerEdgeVariants][highestSize-3];
367
      }
368

    
369
    if( mCenterMeshes==null ) mCenterMeshes = new MeshBase[variants];
370

    
371
    if( cubit < NUM_CORNERS*numCubitsPerCorner )
372
      {
373
      if( mCornerMeshes[indexCornerEdge]==null )
374
        {
375
        float width = (numLayers/3.0f)/(numLayers-1);
376
        mCornerMeshes[indexCornerEdge] = FactoryCubit.getInstance().createMinxCornerMesh(numLayers,width);
377
        }
378
      mesh = mCornerMeshes[indexCornerEdge].copy(true);
379
      }
380
    else if( cubit<NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge )
381
      {
382
      int type = computeEdgeType(cubit,numCubitsPerCorner,numCubitsPerEdge);  // left-top, right-top, left-second, right-second, left-third...
383

    
384
      if( mEdgeMeshes[indexCornerEdge][type]==null )
385
        {
386
        float tmp   = (numLayers/3.0f)/(numLayers-1);
387
        float height= tmp*COS18;
388
        float width = tmp + (type/2)*tmp*SIN18;
389

    
390
        mEdgeMeshes[indexCornerEdge][type] = FactoryCubit.getInstance().createKilominxEdgeMesh(numLayers,width,height, (type%2)==0 );
391
        }
392

    
393
      mesh = mEdgeMeshes[indexCornerEdge][type].copy(true);
394
      }
395
    else
396
      {
397
      int indexCenter = (numLayers-3)/2;
398

    
399
      if( mCenterMeshes[indexCenter]==null )
400
        {
401
        float width = (1+0.5f*(numLayers-3)*SIN18)*(numLayers/3.0f)/(numLayers-1);
402
        mCenterMeshes[indexCenter] = FactoryCubit.getInstance().createKilominxCenterMesh(width);
403
        }
404

    
405
      mesh = mCenterMeshes[indexCenter].copy(true);
406
      }
407

    
408
    Static4D q = QUATS[getQuat(cubit,numCubitsPerCorner,numCubitsPerEdge)];
409
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( q, new Static3D(0,0,0) );
410
    mesh.apply(quat,0xffffffff,0);
411

    
412
    return mesh;
413
    }
414

    
415
///////////////////////////////////////////////////////////////////////////////////////////////////
416

    
417
  int getCornerColor(int cubit, int cubitface, int numLayers, int numCubitsPerCorner)
418
    {
419
    if( cubitface<0 || cubitface>2 ) return NUM_TEXTURES;
420

    
421
    int part  = cubit % numCubitsPerCorner;
422
    int corner= cubit / numCubitsPerCorner;
423

    
424
    if( part==0 )
425
      {
426
      return mCornerFaceMap[corner][cubitface];
427
      }
428
    else
429
      {
430
      int N = (numCubitsPerCorner-1)/3;
431
      int block = (part-1) % N;
432
      int index = (part-1) / N;
433

    
434
      if( block< (numLayers-3)/2 )
435
        {
436
        switch(index)
437
          {
438
          case 0: return cubitface==1 ? NUM_TEXTURES : mCornerFaceMap[corner][cubitface];
439
          case 1: return cubitface==0 ? NUM_TEXTURES : mCornerFaceMap[corner][cubitface];
440
          case 2: return cubitface==2 ? NUM_TEXTURES : mCornerFaceMap[corner][cubitface];
441
          }
442
        }
443
      else
444
        {
445
        switch(index)
446
          {
447
          case 0: return cubitface==0 ? mCornerFaceMap[corner][cubitface] : NUM_TEXTURES;
448
          case 1: return cubitface==2 ? mCornerFaceMap[corner][cubitface] : NUM_TEXTURES;
449
          case 2: return cubitface==1 ? mCornerFaceMap[corner][cubitface] : NUM_TEXTURES;
450
          }
451
        }
452
      }
453

    
454
    return NUM_TEXTURES;
455
    }
456

    
457
///////////////////////////////////////////////////////////////////////////////////////////////////
458

    
459
  int getEdgeColor(int edge, int cubitface, int numCubitsPerEdge)
460
    {
461
    if( cubitface<0 || cubitface>1 ) return NUM_TEXTURES;
462

    
463
    int part    = edge % numCubitsPerEdge;
464
    int variant = edge / numCubitsPerEdge;
465

    
466
    part /=2;
467

    
468
    return (part==0 || cubitface==((part+1)%2)) ? mEdgeMap[variant][cubitface+2] + ((part+3)/2)*NUM_FACES : NUM_TEXTURES;
469
    }
470

    
471
///////////////////////////////////////////////////////////////////////////////////////////////////
472

    
473
  int getCenterColor(int center, int cubitface, int numLayers)
474
    {
475
     if( numLayers==3 )
476
      {
477
      return cubitface>=0 && cubitface<3 ? mCornerFaceMap[center][cubitface] : NUM_TEXTURES;
478
      }
479

    
480
    return cubitface==mCenterFaceMap[center] ? center/5 + NUM_FACES*(numLayers-1)/2 : NUM_TEXTURES;
481
    }
482

    
483
///////////////////////////////////////////////////////////////////////////////////////////////////
484

    
485
  int getFaceColor(int cubit, int cubitface, int numLayers)
486
    {
487
    int numCubitsPerCorner = numCubitsPerCorner(numLayers);
488
    int numCubitsPerEdge   = numCubitsPerEdge(numLayers);
489

    
490
    if( cubit < NUM_CORNERS*numCubitsPerCorner )
491
      {
492
      return getCornerColor(cubit,cubitface,numLayers,numCubitsPerCorner);
493
      }
494
    else if( cubit<NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge )
495
      {
496
      int edge = cubit - NUM_CORNERS*numCubitsPerCorner;
497
      return getEdgeColor(edge,cubitface,numCubitsPerEdge);
498
      }
499
    else
500
      {
501
      int center = cubit-NUM_CORNERS*numCubitsPerCorner-NUM_EDGES*numCubitsPerEdge;
502
      return getCenterColor( center, cubitface, numLayers);
503
      }
504
    }
505

    
506
///////////////////////////////////////////////////////////////////////////////////////////////////
507

    
508
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
509
    {
510
    int COLORS = FACE_COLORS.length;
511
    int variant = face/COLORS;
512
    int numLayers = getNumLayers();
513

    
514
    if( variant == (numLayers-1)/2 || numLayers==3 )
515
      {
516
      float S = 0.07f;
517
      float R = 0.09f;
518

    
519
      float A = 0.86f;
520
      float X1= (SQ5+1)/8;
521
      float Y1= (float)(Math.sqrt(2+0.4f*SQ5)/4);
522
      float Y2= Y1 - (float)(Math.sqrt(10-2*SQ5)/8);
523

    
524
      float[] vertices = { -X1, Y2, 0, -A*Y1, X1, Y2, 0, Y1 };
525

    
526
      FactorySticker factory = FactorySticker.getInstance();
527
      factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[face%NUM_FACES], R);
528

    
529
      float MID = TEXTURE_HEIGHT*0.5f;
530
      float WID = TEXTURE_HEIGHT*0.1f;
531
      float HEI = TEXTURE_HEIGHT*(0.47f+Y1);
532
      canvas.drawLine(left+MID-WID,top+HEI,left+MID+WID,top+HEI,paint);
533
      }
534
    else if( variant==0 )
535
      {
536
      float Y = COS54/(2*SIN54);
537
      float R = 0.09f;
538
      float S = 0.09f;
539
      float[] vertices = { -0.5f, 0.0f, 0.0f, -Y, 0.5f, 0.0f, 0.0f, Y };
540

    
541
      FactorySticker factory = FactorySticker.getInstance();
542
      factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[face%COLORS], R);
543
      }
544
    else
545
      {
546
      float R = 0.07f;
547
      float S = 0.07f;
548

    
549
      float tmp   = (numLayers/3.0f)/(numLayers-1);
550
      float height= tmp*COS18;
551
      float width = tmp + (variant-1)*tmp*SIN18;
552
      float D = height/COS18;
553
      float W = D*SIN18;
554
      float X1 = height/2;
555
      float Y1 = width/2;
556
      float[] vertices = { -X1,-Y1, X1, -Y1, X1, Y1+W,-X1, Y1 };
557

    
558
      FactorySticker factory = FactorySticker.getInstance();
559
      factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[face%COLORS], R);
560
      }
561
    }
562

    
563
///////////////////////////////////////////////////////////////////////////////////////////////////
564
// PUBLIC API
565

    
566
  public boolean isSolved()
567
    {
568
    int index = CUBITS[0].mQuatIndex;
569

    
570
    for(int i=1; i<NUM_CUBITS; i++)
571
      {
572
      if( thereIsVisibleDifference(CUBITS[i], index) ) return false;
573
      }
574

    
575
    return true;
576
    }
577

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

    
580
  public int getObjectName(int numLayers)
581
    {
582
    if( numLayers==3 ) return R.string.minx2;
583
    if( numLayers==5 ) return R.string.minx4;
584

    
585
    return 0;
586
    }
587

    
588
///////////////////////////////////////////////////////////////////////////////////////////////////
589

    
590
  public int getInventor(int numLayers)
591
    {
592
    if( numLayers==3 ) return R.string.minx2_inventor;
593
    if( numLayers==5 ) return R.string.minx4_inventor;
594

    
595
    return 0;
596
    }
597

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

    
600
  public int getComplexity(int numLayers)
601
    {
602
    return 3;
603
    }
604
}
(26-26/33)