Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyCube.java @ 6e7146df

1 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4 fdec60a3 Leszek Koltunski
// This file is part of Magic Cube.                                                              //
5 0c52af30 Leszek Koltunski
//                                                                                               //
6 fdec60a3 Leszek Koltunski
// Magic Cube is free software: you can redistribute it and/or modify                            //
7 0c52af30 Leszek Koltunski
// 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 fdec60a3 Leszek Koltunski
// Magic Cube is distributed in the hope that it will be useful,                                 //
12 0c52af30 Leszek Koltunski
// 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 fdec60a3 Leszek Koltunski
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20 1f9772f3 Leszek Koltunski
package org.distorted.objects;
21 0c52af30 Leszek Koltunski
22 ccf9fec5 Leszek Koltunski
import android.content.res.Resources;
23 0c52af30 Leszek Koltunski
import android.graphics.Canvas;
24
import android.graphics.Paint;
25
26
import org.distorted.library.main.DistortedEffects;
27
import org.distorted.library.main.DistortedTexture;
28 b32444ee Leszek Koltunski
import org.distorted.library.mesh.MeshBase;
29 efa8aa48 Leszek Koltunski
import org.distorted.library.mesh.MeshSquare;
30 0c52af30 Leszek Koltunski
import org.distorted.library.type.Static3D;
31
import org.distorted.library.type.Static4D;
32 6fd4a72c Leszek Koltunski
import org.distorted.main.R;
33 1ebc4767 Leszek Koltunski
import org.distorted.main.RubikSurfaceView;
34 0c52af30 Leszek Koltunski
35 7c969a6d Leszek Koltunski
import java.util.Random;
36
37
import static org.distorted.effects.scramble.ScrambleEffect.START_AXIS;
38
39 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
40
41 9c2f0c91 Leszek Koltunski
class TwistyCube extends TwistyObject
42 0c52af30 Leszek Koltunski
{
43 e844c116 Leszek Koltunski
  // the three rotation axis of a RubikCube. Must be normalized.
44 ad38d800 Leszek Koltunski
  static final Static3D[] ROT_AXIS = new Static3D[]
45 efef689c Leszek Koltunski
         {
46
           new Static3D(1,0,0),
47
           new Static3D(0,1,0),
48
           new Static3D(0,0,1)
49
         };
50
51 37a25788 Leszek Koltunski
  private static final int[] FACE_COLORS = new int[]
52 efef689c Leszek Koltunski
         {
53 ece1b58d Leszek Koltunski
           COLOR_YELLOW, COLOR_WHITE,
54
           COLOR_BLUE  , COLOR_GREEN,
55 323b217c Leszek Koltunski
           COLOR_RED   , COLOR_ORANGE
56 efef689c Leszek Koltunski
         };
57
58 10585385 Leszek Koltunski
  // All legal rotation quats of a RubikCube of any size.
59 efef689c Leszek Koltunski
  // Here's how to compute this:
60
  // 1) compute how many rotations there are (RubikCube of any size = 24)
61
  // 2) take the AXIS, angles of rotation (90 in RubikCube's case) compute the basic quaternions
62
  // (i.e. rotations of 1 basic angle along each of the axis) and from there start semi-randomly
63
  // multiplying them and eventually you'll find all (24) legal rotations.
64 9f4c44fe Leszek Koltunski
  // Example program in C, res/raw/compute_quats.c , is included.
65 10585385 Leszek Koltunski
  private static final Static4D[] QUATS = new Static4D[]
66 efef689c Leszek Koltunski
         {
67 10585385 Leszek Koltunski
         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( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
73
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
74
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
75
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
76
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
77
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
78
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
79
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
80
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
81
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
82
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
83
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
84
85
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
86
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
87
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
88
         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
89
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
90
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
91
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
92
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
93 efef689c Leszek Koltunski
         };
94 411c6285 Leszek Koltunski
95 fbca0033 Leszek Koltunski
  private static MeshBase[] mMeshes;
96 40ab026e Leszek Koltunski
97 411c6285 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
98
99 9c2f0c91 Leszek Koltunski
  TwistyCube(int size, Static4D quat, DistortedTexture texture,
100
             MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
101 411c6285 Leszek Koltunski
    {
102 d99f3a48 Leszek Koltunski
    super(size, size, 60, quat, texture, mesh, effects, moves, ObjectList.CUBE, res, scrWidth);
103 411c6285 Leszek Koltunski
    }
104
105 ac940e24 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
106
107 a64e07d0 Leszek Koltunski
  MeshBase createCubitMesh(int cubit, int numLayers)
108 ac940e24 Leszek Koltunski
    {
109
    if( mMeshes==null )
110
      {
111
      mMeshes = new MeshBase[ObjectList.CUBE.getNumVariants()];
112
      }
113
114
    int ordinal= ObjectList.CUBE.ordinal();
115 d99f3a48 Leszek Koltunski
    int index  = ObjectList.getSizeIndex(ordinal,getNumLayers());
116 ac940e24 Leszek Koltunski
117
    if( mMeshes[index]==null )
118
      {
119 b89898c5 Leszek Koltunski
      mMeshes[index] = FactoryCubit.getInstance().createCubeMesh(index);
120 ac940e24 Leszek Koltunski
      }
121
122
    return mMeshes[index].copy(true);
123
    }
124
125 7289fd6c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
126
127 ae755eda Leszek Koltunski
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
128 7289fd6c Leszek Koltunski
    {
129 76c2bd07 Leszek Koltunski
    float F =  0.5f;
130
    float R = 0.10f;
131 2fcfce81 Leszek Koltunski
    float S = 0.08f;
132 76c2bd07 Leszek Koltunski
    float[] vertices = { -F,-F, +F,-F, +F,+F, -F,+F};
133 7289fd6c Leszek Koltunski
134 b89898c5 Leszek Koltunski
    FactorySticker factory = FactorySticker.getInstance();
135 ae755eda Leszek Koltunski
    factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[face], R);
136 7289fd6c Leszek Koltunski
    }
137
138 411c6285 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
139
140 10a2e360 Leszek Koltunski
  Static3D[] getCubitPositions(int size)
141 a10ada2a Leszek Koltunski
    {
142 10a2e360 Leszek Koltunski
    int numCubits = size>1 ? 6*size*size - 12*size + 8 : 1;
143
    Static3D[] tmp = new Static3D[numCubits];
144 beb325a0 Leszek Koltunski
145 49f67f9b Leszek Koltunski
    float diff = 0.5f*(size-1);
146 a10ada2a Leszek Koltunski
    int currentPosition = 0;
147 beb325a0 Leszek Koltunski
148 a10ada2a Leszek Koltunski
    for(int x = 0; x<size; x++)
149
      for(int y = 0; y<size; y++)
150
        for(int z = 0; z<size; z++)
151
          if( x==0 || x==size-1 || y==0 || y==size-1 || z==0 || z==size-1 )
152 beb325a0 Leszek Koltunski
            {
153 49f67f9b Leszek Koltunski
            tmp[currentPosition++] = new Static3D(x-diff,y-diff,z-diff);
154 a10ada2a Leszek Koltunski
            }
155 47ba5ddc Leszek Koltunski
156 a10ada2a Leszek Koltunski
    return tmp;
157
    }
158 47ba5ddc Leszek Koltunski
159 beb325a0 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
160
161 10585385 Leszek Koltunski
  Static4D[] getQuats()
162 a10ada2a Leszek Koltunski
    {
163 10585385 Leszek Koltunski
    return QUATS;
164 a10ada2a Leszek Koltunski
    }
165 47ba5ddc Leszek Koltunski
166 eaee1ddc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
167
168
  boolean shouldResetTextureMaps()
169
    {
170
    return false;
171
    }
172
173 47ba5ddc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
174
175 411c6285 Leszek Koltunski
  int getNumFaces()
176 a10ada2a Leszek Koltunski
    {
177 411c6285 Leszek Koltunski
    return FACE_COLORS.length;
178 8f53e513 Leszek Koltunski
    }
179
180 7403cdfa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
181
182 a64e07d0 Leszek Koltunski
  float[] getCuts(int numLayers)
183 7403cdfa Leszek Koltunski
    {
184 a64e07d0 Leszek Koltunski
    float[] cuts = new float[numLayers-1];
185 a97e02b7 Leszek Koltunski
186 a64e07d0 Leszek Koltunski
    for(int i=0; i<numLayers-1; i++)
187 a97e02b7 Leszek Koltunski
      {
188 a64e07d0 Leszek Koltunski
      cuts[i] = (2-numLayers)*0.5f + i;
189 a97e02b7 Leszek Koltunski
      }
190
191
    return cuts;
192 7403cdfa Leszek Koltunski
    }
193
194 eab9d8f8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
195
196 a64e07d0 Leszek Koltunski
  int getNumStickerTypes(int numLayers)
197 eab9d8f8 Leszek Koltunski
    {
198
    return 1;
199
    }
200
201 8f53e513 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
202
203
  int getNumCubitFaces()
204
    {
205
    return FACE_COLORS.length;
206 411c6285 Leszek Koltunski
    }
207 47ba5ddc Leszek Koltunski
208 f0fa83ae Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
209
210
  float getScreenRatio()
211
    {
212
    return 0.5f;
213
    }
214
215 f6d06256 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
216
217
  int getFaceColor(int cubit, int cubitface, int size)
218
    {
219 f18e8fae Leszek Koltunski
    float diff = CUBITS[cubit].mRotationRow[cubitface/2] - (cubitface%2==0 ? size-1:0);
220
    return diff*diff < 0.0001f ? cubitface : NUM_FACES;
221 f6d06256 Leszek Koltunski
    }
222
223 fb377dae Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
224
225
  float returnMultiplier()
226
    {
227 d99f3a48 Leszek Koltunski
    return getNumLayers();
228 fb377dae Leszek Koltunski
    }
229
230 7c969a6d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
231
232 a64e07d0 Leszek Koltunski
  float[] getRowChances(int numLayers)
233 7c969a6d Leszek Koltunski
    {
234 d99f3a48 Leszek Koltunski
    float[] chances = new float[numLayers];
235 7c969a6d Leszek Koltunski
236 d99f3a48 Leszek Koltunski
    for(int i=0; i<numLayers; i++)
237 7c969a6d Leszek Koltunski
      {
238 d99f3a48 Leszek Koltunski
      chances[i] = (i+1.0f) / numLayers;
239 7c969a6d Leszek Koltunski
      }
240
241
    return chances;
242
    }
243
244 e844c116 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
245
// PUBLIC API
246
247 12ad3fca Leszek Koltunski
  public Static3D[] getRotationAxis()
248
    {
249 ad38d800 Leszek Koltunski
    return ROT_AXIS;
250 12ad3fca Leszek Koltunski
    }
251
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253
254 e844c116 Leszek Koltunski
  public int getBasicAngle()
255
    {
256
    return 4;
257
    }
258 39e74052 Leszek Koltunski
259 7c969a6d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
260
261
  public int randomizeNewRotAxis(Random rnd, int oldRotAxis)
262
    {
263
    int numAxis = ROTATION_AXIS.length;
264
265
    if( oldRotAxis == START_AXIS )
266 5cf34c5f Leszek Koltunski
      {
267 7c969a6d Leszek Koltunski
      return rnd.nextInt(numAxis);
268
      }
269
    else
270
      {
271
      int newVector = rnd.nextInt(numAxis-1);
272
      return (newVector>=oldRotAxis ? newVector+1 : newVector);
273 5cf34c5f Leszek Koltunski
      }
274
    }
275
276 e46e17fb Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
277
278 7c969a6d Leszek Koltunski
  public int randomizeNewRow(Random rnd, int oldRotAxis, int oldRow, int newRotAxis)
279 e46e17fb Leszek Koltunski
    {
280 7c969a6d Leszek Koltunski
    float rowFloat = rnd.nextFloat();
281
282
    for(int row=0; row<mRowChances.length; row++)
283
      {
284
      if( rowFloat<=mRowChances[row] ) return row;
285
      }
286
287
    return 0;
288 e46e17fb Leszek Koltunski
    }
289 f0336037 Leszek Koltunski
290 6b6504fe Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
291
292
  public boolean isSolved()
293
    {
294
    int index = CUBITS[0].mQuatIndex;
295
296
    for(int i=1; i<NUM_CUBITS; i++)
297
      {
298
      if( !thereIsNoVisibleDifference(CUBITS[i], index) ) return false;
299
      }
300
301
    return true;
302
    }
303
304 1ebc4767 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
305
// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different
306
// then if it were rotated by quaternion 'quat'.
307
// No it is not so simple as the quats need to be the same - imagine a 4x4x4 cube where the two
308
// middle squares get interchanged. No visible difference!
309
//
310
// So: this is true iff the cubit
311
// a) is a corner or edge and the quaternions are the same
312
// b) is inside one of the faces and after rotations by both quats it ends up on the same face.
313
314 6b6504fe Leszek Koltunski
  private boolean thereIsNoVisibleDifference(Cubit cubit, int quatIndex)
315 1ebc4767 Leszek Koltunski
    {
316
    if ( cubit.mQuatIndex == quatIndex ) return true;
317
318
    int belongsToHowManyFaces = 0;
319 d99f3a48 Leszek Koltunski
    int lastLayer = getNumLayers()-1;
320 1ebc4767 Leszek Koltunski
    float row;
321
    final float MAX_ERROR = 0.01f;
322
323
    for(int i=0; i<NUM_AXIS; i++)
324
      {
325
      row = cubit.mRotationRow[i];
326 d99f3a48 Leszek Koltunski
      if( (row          <MAX_ERROR && row          >-MAX_ERROR) ||
327
          (row-lastLayer<MAX_ERROR && row-lastLayer>-MAX_ERROR)  ) belongsToHowManyFaces++;
328 1ebc4767 Leszek Koltunski
      }
329
330
    switch(belongsToHowManyFaces)
331
      {
332
      case 0 : return true ;  // 'inside' cubit that does not lie on any face
333
      case 1 :                // cubit that lies inside one of the faces
334
               Static3D orig = cubit.getOrigPosition();
335
               Static4D quat1 = QUATS[quatIndex];
336
               Static4D quat2 = QUATS[cubit.mQuatIndex];
337
338
               Static4D cubitCenter = new Static4D( orig.get0(), orig.get1(), orig.get2(), 0);
339
               Static4D rotated1 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat1 );
340
               Static4D rotated2 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat2 );
341
342 eb389a97 Leszek Koltunski
               float row1, row2;
343 1ebc4767 Leszek Koltunski
               float x1 = rotated1.get0();
344
               float y1 = rotated1.get1();
345
               float z1 = rotated1.get2();
346
               float x2 = rotated2.get0();
347
               float y2 = rotated2.get1();
348
               float z2 = rotated2.get2();
349
350
               for(int i=0; i<NUM_AXIS; i++)
351
                 {
352 eb389a97 Leszek Koltunski
                 row1 = computeRow(x1,y1,z1,i);
353
                 row2 = computeRow(x2,y2,z2,i);
354
355 bb490017 Leszek Koltunski
                 if( (row1==0 && row2==0) || (row1==lastLayer && row2==lastLayer) ) return true;
356 1ebc4767 Leszek Koltunski
                 }
357
               return false;
358
359
      default: return false;  // edge or corner
360
      }
361
    }
362
363 f0336037 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
364 a304ee64 Leszek Koltunski
// order: Up --> Right --> Front --> Down --> Left --> Back
365
// (because the first implemented Solver - the two-phase Cube3 one - expects such order)
366
//
367 fa0f7a56 Leszek Koltunski
// Solved 3x3x3 Cube maps to "UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB"
368 a304ee64 Leszek Koltunski
//
369 fa0f7a56 Leszek Koltunski
// s : size of the cube; let index = a*s + b    (i.e. a,b = row,column)
370
//
371
// Up    :   index --> b<s-1 ? (s-1)*(s+4b)+a : 6*s*s -13*s +8 +a
372 a304ee64 Leszek Koltunski
// Right :   index --> 6*s*s - 12*s + 7 - index
373 fa0f7a56 Leszek Koltunski
// Front :   index --> if b==0  : s*s - 1 - index
374
//                     if b==s-1: 6*s*s -11*s +6 - index
375
//                     else
376
//                         a==0: s*s + s-1 + 4*(b-1)*(s-1) + 2*(s-2) + s
377
//                         else: s*s + s-1 + 4*(b-1)*(s-1) + 2*(s-1-a)
378
// Down  :   index --> b==0 ? (s-1-a) : s*s + s-1 + 4*(b-1)*(s-1) - a
379
// Left  :   index --> (s-1-a)*s + b
380
// Back  :   index --> if b==s-1: s*(s-1-a)
381
//                     if b==0  : 5*s*s -12*s + 8 + (s-1-a)*s
382
//                     else
383
//                        if a==s-1: s*s + 4*(s-2-b)*(s-1)
384
//                        else     : s*s + 4*(s-2-b)*(s-1) + s + (s-2-a)*2
385 f0336037 Leszek Koltunski
386 20931cf6 Leszek Koltunski
  public String retObjectString()
387 f0336037 Leszek Koltunski
    {
388 fa0f7a56 Leszek Koltunski
    StringBuilder objectString = new StringBuilder();
389 d99f3a48 Leszek Koltunski
    int layers = getNumLayers();
390
    int len = layers*layers;
391 ac940e24 Leszek Koltunski
    int cubitIndex, row, col, color,face;
392 fa0f7a56 Leszek Koltunski
393
    final int RIGHT= 0;
394
    final int LEFT = 1;
395
    final int UP   = 2;
396
    final int DOWN = 3;
397
    final int FRONT= 4;
398
    final int BACK = 5;
399
400 fb52fae9 Leszek Koltunski
    // 'I' - interior, theoretically can happen
401
    final char[] FACE_NAMES = { 'R', 'L', 'U', 'D', 'F', 'B', 'I'};
402 49595e4b Leszek Koltunski
403
    face = UP;
404
405 fa0f7a56 Leszek Koltunski
    for(int i=0; i<len; i++)
406
      {
407 d99f3a48 Leszek Koltunski
      row = i/layers;
408
      col = i%layers;
409 fa0f7a56 Leszek Koltunski
410 d99f3a48 Leszek Koltunski
      cubitIndex = col<layers-1 ? (layers-1)*(layers+4*col) + row : 6*layers*layers - 13*layers + 8 + row;
411 49595e4b Leszek Koltunski
      color = getCubitFaceColorIndex(cubitIndex,face);
412 fa0f7a56 Leszek Koltunski
      objectString.append(FACE_NAMES[color]);
413
      }
414
415 49595e4b Leszek Koltunski
    face = RIGHT;
416
417 fa0f7a56 Leszek Koltunski
    for(int i=0; i<len; i++)
418
      {
419 d99f3a48 Leszek Koltunski
      cubitIndex = 6*layers*layers - 12*layers +7 - i;
420 49595e4b Leszek Koltunski
      color = getCubitFaceColorIndex(cubitIndex,face);
421 fa0f7a56 Leszek Koltunski
      objectString.append(FACE_NAMES[color]);
422
      }
423
424 064ccc31 Leszek Koltunski
    face = FRONT;
425 49595e4b Leszek Koltunski
426 fa0f7a56 Leszek Koltunski
    for(int i=0; i<len; i++)
427
      {
428 d99f3a48 Leszek Koltunski
      row = i/layers;
429
      col = i%layers;
430 fa0f7a56 Leszek Koltunski
431 d99f3a48 Leszek Koltunski
      if( col==layers-1 ) cubitIndex = 6*layers*layers - 11*layers + 6 -i;
432
      else if(   col==0 ) cubitIndex = layers*layers - 1 - i;
433 fa0f7a56 Leszek Koltunski
      else
434
        {
435 d99f3a48 Leszek Koltunski
        if( row==0 ) cubitIndex = layers*layers + layers-1 + 4*(col-1)*(layers-1) + 2*(layers-2) + layers;
436
        else         cubitIndex = layers*layers + layers-1 + 4*(col-1)*(layers-1) + 2*(layers-1-row);
437 fa0f7a56 Leszek Koltunski
        }
438
439 49595e4b Leszek Koltunski
      color = getCubitFaceColorIndex(cubitIndex,face);
440 fa0f7a56 Leszek Koltunski
      objectString.append(FACE_NAMES[color]);
441
      }
442
443 49595e4b Leszek Koltunski
    face = DOWN;
444
445 fa0f7a56 Leszek Koltunski
    for(int i=0; i<len; i++)
446
      {
447 d99f3a48 Leszek Koltunski
      row = i/layers;
448
      col = i%layers;
449 fa0f7a56 Leszek Koltunski
450 d99f3a48 Leszek Koltunski
      cubitIndex = col==0 ? layers-1-row : layers*layers + layers-1 + 4*(col-1)*(layers-1) - row;
451 49595e4b Leszek Koltunski
      color = getCubitFaceColorIndex(cubitIndex,face);
452 fa0f7a56 Leszek Koltunski
      objectString.append(FACE_NAMES[color]);
453
      }
454
455 49595e4b Leszek Koltunski
    face = LEFT;
456
457 fa0f7a56 Leszek Koltunski
    for(int i=0; i<len; i++)
458
      {
459 d99f3a48 Leszek Koltunski
      row = i/layers;
460
      col = i%layers;
461 fa0f7a56 Leszek Koltunski
462 d99f3a48 Leszek Koltunski
      cubitIndex = (layers-1-row)*layers + col;
463 49595e4b Leszek Koltunski
      color = getCubitFaceColorIndex(cubitIndex,face);
464 fa0f7a56 Leszek Koltunski
      objectString.append(FACE_NAMES[color]);
465
      }
466
467 49595e4b Leszek Koltunski
    face = BACK;
468
469 fa0f7a56 Leszek Koltunski
    for(int i=0; i<len; i++)
470
      {
471 d99f3a48 Leszek Koltunski
      row = i/layers;
472
      col = i%layers;
473 fa0f7a56 Leszek Koltunski
474 d99f3a48 Leszek Koltunski
      if( col==layers-1 ) cubitIndex = layers*(layers-1-row);
475
      else if(   col==0 ) cubitIndex = 5*layers*layers - 12*layers + 8 + (layers-1-row)*layers;
476 fa0f7a56 Leszek Koltunski
      else
477
        {
478 d99f3a48 Leszek Koltunski
        if( row==layers-1 ) cubitIndex = layers*layers + 4*(layers-2-col)*(layers-1);
479
        else                cubitIndex = layers*layers + 4*(layers-2-col)*(layers-1) + layers + 2*(layers-2-row);
480 fa0f7a56 Leszek Koltunski
        }
481
482 49595e4b Leszek Koltunski
      color = getCubitFaceColorIndex(cubitIndex,face);
483 fa0f7a56 Leszek Koltunski
      objectString.append(FACE_NAMES[color]);
484
      }
485
486
    return objectString.toString();
487 f0336037 Leszek Koltunski
    }
488 6fd4a72c Leszek Koltunski
489
///////////////////////////////////////////////////////////////////////////////////////////////////
490
491
  public int getObjectName(int numLayers)
492
    {
493
    switch(numLayers)
494
      {
495
      case 2: return R.string.cube2;
496
      case 3: return R.string.cube3;
497
      case 4: return R.string.cube4;
498
      case 5: return R.string.cube5;
499
      }
500
    return R.string.cube3;
501
    }
502
503
///////////////////////////////////////////////////////////////////////////////////////////////////
504
505
  public int getInventor(int numLayers)
506
    {
507
    switch(numLayers)
508
      {
509
      case 2: return R.string.cube2_inventor;
510
      case 3: return R.string.cube3_inventor;
511
      case 4: return R.string.cube4_inventor;
512
      case 5: return R.string.cube5_inventor;
513
      }
514
    return R.string.cube3_inventor;
515
    }
516
517
///////////////////////////////////////////////////////////////////////////////////////////////////
518
519
  public int getComplexity(int numLayers)
520
    {
521
    switch(numLayers)
522
      {
523
      case 2: return 4;
524
      case 3: return 6;
525
      case 4: return 8;
526
      case 5: return 10;
527
      }
528
    return 6;
529
    }
530 0c52af30 Leszek Koltunski
}