Project

General

Profile

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

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

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
24 f10a88a8 Leszek Koltunski
import org.distorted.helpers.ObjectShape;
25 9c06394a Leszek Koltunski
import org.distorted.helpers.ObjectSticker;
26 6cf89a3e Leszek Koltunski
import org.distorted.helpers.ScrambleState;
27 0c52af30 Leszek Koltunski
import org.distorted.library.main.DistortedEffects;
28
import org.distorted.library.main.DistortedTexture;
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 0c52af30 Leszek Koltunski
34 7c969a6d Leszek Koltunski
import java.util.Random;
35
36 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
37
38 9c2f0c91 Leszek Koltunski
class TwistyCube extends TwistyObject
39 0c52af30 Leszek Koltunski
{
40 e844c116 Leszek Koltunski
  // the three rotation axis of a RubikCube. Must be normalized.
41 ad38d800 Leszek Koltunski
  static final Static3D[] ROT_AXIS = new Static3D[]
42 efef689c Leszek Koltunski
         {
43
           new Static3D(1,0,0),
44
           new Static3D(0,1,0),
45
           new Static3D(0,0,1)
46
         };
47
48 925ed78f Leszek Koltunski
  private static final int[] BASIC_ANGLE = new int[] { 4,4,4 };
49
50 37a25788 Leszek Koltunski
  private static final int[] FACE_COLORS = new int[]
51 efef689c Leszek Koltunski
         {
52 ece1b58d Leszek Koltunski
           COLOR_YELLOW, COLOR_WHITE,
53
           COLOR_BLUE  , COLOR_GREEN,
54 323b217c Leszek Koltunski
           COLOR_RED   , COLOR_ORANGE
55 efef689c Leszek Koltunski
         };
56
57 10585385 Leszek Koltunski
  // All legal rotation quats of a RubikCube of any size.
58 efef689c Leszek Koltunski
  // Here's how to compute this:
59
  // 1) compute how many rotations there are (RubikCube of any size = 24)
60
  // 2) take the AXIS, angles of rotation (90 in RubikCube's case) compute the basic quaternions
61
  // (i.e. rotations of 1 basic angle along each of the axis) and from there start semi-randomly
62
  // multiplying them and eventually you'll find all (24) legal rotations.
63 9f4c44fe Leszek Koltunski
  // Example program in C, res/raw/compute_quats.c , is included.
64 10585385 Leszek Koltunski
  private static final Static4D[] QUATS = new Static4D[]
65 efef689c Leszek Koltunski
         {
66 10585385 Leszek Koltunski
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
67
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
68
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
69
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
70
71
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
72
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
73
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
74
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
75
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
76
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
77
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
78
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
79
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
80
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
81
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
82
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
83
84
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
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 efef689c Leszek Koltunski
         };
93 411c6285 Leszek Koltunski
94 b1f2ccf5 Leszek Koltunski
  private static final double[][] VERTICES = new double[][]
95
          {
96
              { 0.5, 0.5, 0.5 },
97
              { 0.5, 0.5,-0.5 },
98
              { 0.5,-0.5, 0.5 },
99
              { 0.5,-0.5,-0.5 },
100
              {-0.5, 0.5, 0.5 },
101
              {-0.5, 0.5,-0.5 },
102
              {-0.5,-0.5, 0.5 },
103
              {-0.5,-0.5,-0.5 },
104
          };
105
106
  private static final int[][] VERT_INDEXES = new int[][]
107
          {
108
              {2,3,1,0},   // counterclockwise!
109
              {7,6,4,5},
110
              {4,0,1,5},
111
              {7,3,2,6},
112
              {6,2,0,4},
113
              {3,7,5,1}
114
          };
115
116
  private static final float[][] STICKERS = new float[][]
117
          {
118
              { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f }
119
          };
120
121 9c06394a Leszek Koltunski
  private static final ObjectSticker[] mStickers;
122
123
  static
124
    {
125
    final float radius = 0.10f;
126
    final float stroke = 0.08f;
127
    final float[] radii = {radius,radius,radius,radius};
128
    mStickers = new ObjectSticker[STICKERS.length];
129
    mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke );
130
    }
131
132 caccea6e Leszek Koltunski
  private int mCurrState;
133
  private int mIndexExcluded;
134 6cf89a3e Leszek Koltunski
  private final ScrambleState[] mStates;
135 caccea6e Leszek Koltunski
136 411c6285 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
137
138 9c2f0c91 Leszek Koltunski
  TwistyCube(int size, Static4D quat, DistortedTexture texture,
139
             MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
140 411c6285 Leszek Koltunski
    {
141 db875721 Leszek Koltunski
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.CUBE, res, scrWidth);
142 caccea6e Leszek Koltunski
143
    int[][] m = new int[16][];
144
    for(int i=1; i<16; i++) m[i] = createEdges(size,i);
145
146 6cf89a3e Leszek Koltunski
    mStates = new ScrambleState[]  // built so that all 3 axes must be present in every 4 consecutive moves
147 caccea6e Leszek Koltunski
      {
148 6cf89a3e Leszek Koltunski
      new ScrambleState( new int[][] { m[ 1], m[ 2], m[ 3] } ),  // 0
149
      new ScrambleState( new int[][] {  null, m[ 4], m[ 5] } ),  // x
150
      new ScrambleState( new int[][] { m[ 6],  null, m[ 7] } ),  // y
151
      new ScrambleState( new int[][] { m[ 8], m[ 8],  null } ),  // z
152
      new ScrambleState( new int[][] { m[10],  null, m[ 7] } ),  // xy
153
      new ScrambleState( new int[][] { m[11], m[ 9],  null } ),  // xz
154
      new ScrambleState( new int[][] {  null, m[12], m[ 5] } ),  // yx
155
      new ScrambleState( new int[][] { m[ 8], m[13],  null } ),  // yz
156
      new ScrambleState( new int[][] {  null, m[ 4], m[14] } ),  // zx
157
      new ScrambleState( new int[][] { m[ 6],  null, m[15] } ),  // zy
158
      new ScrambleState( new int[][] {  null,  null, m[ 5] } ),  // xyx
159
      new ScrambleState( new int[][] {  null, m[ 4],  null } ),  // xzx
160
      new ScrambleState( new int[][] {  null,  null, m[ 7] } ),  // yxy
161
      new ScrambleState( new int[][] { m[ 6],  null,  null } ),  // yzy
162
      new ScrambleState( new int[][] {  null, m[ 9],  null } ),  // zxz
163
      new ScrambleState( new int[][] { m[ 8],  null,  null } ),  // zyz
164 caccea6e Leszek Koltunski
      };
165
    }
166
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168
169
  private int[] createEdges(int size, int vertex)
170
    {
171
    int[] ret = new int[9*size];
172
173
    for(int l=0; l<size; l++)
174
      {
175
      ret[9*l  ] = l;
176
      ret[9*l+1] =-1;
177
      ret[9*l+2] = vertex;
178
      ret[9*l+3] = l;
179
      ret[9*l+4] = 1;
180
      ret[9*l+5] = vertex;
181
      ret[9*l+6] = l;
182
      ret[9*l+7] = 2;
183
      ret[9*l+8] = vertex;
184
      }
185
186
    return ret;
187 411c6285 Leszek Koltunski
    }
188
189 a480ee80 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
190
191
  int[] getSolvedQuats(int cubit, int numLayers)
192
    {
193
    int status = retCubitSolvedStatus(cubit,numLayers);
194
    return status<0 ? null : buildSolvedQuats(MovementCube.FACE_AXIS[status],QUATS);
195
    }
196
197 f10a88a8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
198
199
  ObjectShape getObjectShape(int cubit, int numLayers)
200
    {
201
    int extraI, extraV, num;
202
    float height;
203
204
    switch(numLayers)
205
      {
206
      case 2 : num = 6; extraI = 2; extraV = 2; height = 0.045f; break;
207
      case 3 : num = 5; extraI = 2; extraV = 2; height = 0.045f; break;
208
      case 4 : num = 5; extraI = 1; extraV = 1; height = 0.045f; break;
209
      default: num = 5; extraI = 0; extraV = 0; height = 0.045f; break;
210
      }
211
212
    float[][] bands     = new float[][] { {height,35,0.5f,0.7f,num,extraI,extraV} };
213
    int[] bandIndices   = new int[] { 0,0,0,0,0,0};
214
    float[][] corners   = new float[][] { {0.036f,0.12f} };
215
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
216
    float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
217
    int[] centerIndices = new int[] { 0,0,0,0,0,0,0,0 };
218
219
    return new ObjectShape(VERTICES,VERT_INDEXES,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
220
    }
221
222 ac940e24 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
223
224 3e605536 Leszek Koltunski
  Static4D getQuat(int cubit, int numLayers)
225 ac940e24 Leszek Koltunski
    {
226 3e605536 Leszek Koltunski
    return QUATS[0];
227
    }
228 f10a88a8 Leszek Koltunski
229 3e605536 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
230 ac940e24 Leszek Koltunski
231 3e605536 Leszek Koltunski
  int getNumCubitVariants(int numLayers)
232
    {
233
    return 1;
234
    }
235 ac940e24 Leszek Koltunski
236 3e605536 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
237 f10a88a8 Leszek Koltunski
238 3e605536 Leszek Koltunski
  int getCubitVariant(int cubit, int numLayers)
239
    {
240
    return 0;
241 ac940e24 Leszek Koltunski
    }
242
243 7289fd6c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
244
245 9c06394a Leszek Koltunski
  int getColor(int face)
246 7289fd6c Leszek Koltunski
    {
247 9c06394a Leszek Koltunski
    return FACE_COLORS[face];
248
    }
249
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251 7289fd6c Leszek Koltunski
252 9c06394a Leszek Koltunski
  ObjectSticker retSticker(int face)
253
    {
254
    return mStickers[face/NUM_FACES];
255 7289fd6c Leszek Koltunski
    }
256
257 411c6285 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
258
259 b1f2ccf5 Leszek Koltunski
  float[][] getCubitPositions(int numLayers)
260 a10ada2a Leszek Koltunski
    {
261 b1f2ccf5 Leszek Koltunski
    int numCubits = numLayers>1 ? 6*numLayers*numLayers - 12*numLayers + 8 : 1;
262 e6cf7283 Leszek Koltunski
    float[][] tmp = new float[numCubits][];
263 beb325a0 Leszek Koltunski
264 b1f2ccf5 Leszek Koltunski
    float diff = 0.5f*(numLayers-1);
265 a10ada2a Leszek Koltunski
    int currentPosition = 0;
266 beb325a0 Leszek Koltunski
267 b1f2ccf5 Leszek Koltunski
    for(int x = 0; x<numLayers; x++)
268
      for(int y = 0; y<numLayers; y++)
269
        for(int z = 0; z<numLayers; z++)
270
          if( x==0 || x==numLayers-1 || y==0 || y==numLayers-1 || z==0 || z==numLayers-1 )
271 beb325a0 Leszek Koltunski
            {
272 e6cf7283 Leszek Koltunski
            tmp[currentPosition++] = new float[] {x-diff,y-diff,z-diff};
273 a10ada2a Leszek Koltunski
            }
274 47ba5ddc Leszek Koltunski
275 a10ada2a Leszek Koltunski
    return tmp;
276
    }
277 47ba5ddc Leszek Koltunski
278 beb325a0 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
279
280 10585385 Leszek Koltunski
  Static4D[] getQuats()
281 a10ada2a Leszek Koltunski
    {
282 10585385 Leszek Koltunski
    return QUATS;
283 a10ada2a Leszek Koltunski
    }
284 47ba5ddc Leszek Koltunski
285 eaee1ddc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
286
287
  boolean shouldResetTextureMaps()
288
    {
289
    return false;
290
    }
291
292 47ba5ddc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
293
294 411c6285 Leszek Koltunski
  int getNumFaces()
295 a10ada2a Leszek Koltunski
    {
296 411c6285 Leszek Koltunski
    return FACE_COLORS.length;
297 8f53e513 Leszek Koltunski
    }
298
299 7403cdfa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
300
301 e6734aa9 Leszek Koltunski
  float[][] getCuts(int numLayers)
302 7403cdfa Leszek Koltunski
    {
303 e6734aa9 Leszek Koltunski
    float[][] cuts = new float[3][numLayers-1];
304 a97e02b7 Leszek Koltunski
305 a64e07d0 Leszek Koltunski
    for(int i=0; i<numLayers-1; i++)
306 a97e02b7 Leszek Koltunski
      {
307 e6734aa9 Leszek Koltunski
      float cut = (2-numLayers)*0.5f + i;
308
      cuts[0][i] = cut;
309
      cuts[1][i] = cut;
310
      cuts[2][i] = cut;
311 a97e02b7 Leszek Koltunski
      }
312
313
    return cuts;
314 7403cdfa Leszek Koltunski
    }
315
316 169219a7 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
317
318
  int getSolvedFunctionIndex()
319
    {
320
    return 0;
321
    }
322
323 eab9d8f8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
324
325 a64e07d0 Leszek Koltunski
  int getNumStickerTypes(int numLayers)
326 eab9d8f8 Leszek Koltunski
    {
327 b1f2ccf5 Leszek Koltunski
    return STICKERS.length;
328 eab9d8f8 Leszek Koltunski
    }
329
330 8f53e513 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
331
332
  int getNumCubitFaces()
333
    {
334
    return FACE_COLORS.length;
335 411c6285 Leszek Koltunski
    }
336 47ba5ddc Leszek Koltunski
337 f0fa83ae Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
338
339
  float getScreenRatio()
340
    {
341
    return 0.5f;
342
    }
343
344 f6d06256 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
345
346 f10a88a8 Leszek Koltunski
  int getFaceColor(int cubit, int cubitface, int numLayers)
347 f6d06256 Leszek Koltunski
    {
348 f10a88a8 Leszek Koltunski
    return CUBITS[cubit].mRotationRow[cubitface/2] == (cubitface%2==0 ? (1<<(numLayers-1)):1) ? cubitface : NUM_FACES;
349 f6d06256 Leszek Koltunski
    }
350
351 fb377dae Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
352
353
  float returnMultiplier()
354
    {
355 d99f3a48 Leszek Koltunski
    return getNumLayers();
356 fb377dae Leszek Koltunski
    }
357
358 e844c116 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
359
// PUBLIC API
360
361 12ad3fca Leszek Koltunski
  public Static3D[] getRotationAxis()
362
    {
363 ad38d800 Leszek Koltunski
    return ROT_AXIS;
364 12ad3fca Leszek Koltunski
    }
365
366
///////////////////////////////////////////////////////////////////////////////////////////////////
367
368 925ed78f Leszek Koltunski
  public int[] getBasicAngle()
369 e844c116 Leszek Koltunski
    {
370 925ed78f Leszek Koltunski
    return BASIC_ANGLE;
371 e844c116 Leszek Koltunski
    }
372 39e74052 Leszek Koltunski
373 7c969a6d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
374
375 caccea6e Leszek Koltunski
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
376 7c969a6d Leszek Koltunski
    {
377 9f171eba Leszek Koltunski
    if( curr==0 )
378 5cf34c5f Leszek Koltunski
      {
379 caccea6e Leszek Koltunski
      mCurrState     = 0;
380
      mIndexExcluded =-1;
381 5cf34c5f Leszek Koltunski
      }
382
383 caccea6e Leszek Koltunski
    int total = mStates[mCurrState].getTotal(mIndexExcluded);
384
    int random= rnd.nextInt(total);
385
    int[] info= mStates[mCurrState].getInfo(random,mIndexExcluded);
386 7c969a6d Leszek Koltunski
387 caccea6e Leszek Koltunski
    scramble[curr][0] = info[0];
388
    scramble[curr][1] = info[1];
389
    scramble[curr][2] = info[2];
390 7c969a6d Leszek Koltunski
391 caccea6e Leszek Koltunski
    mCurrState     = info[3];
392
    mIndexExcluded = info[0];
393 e46e17fb Leszek Koltunski
    }
394 f0336037 Leszek Koltunski
395
///////////////////////////////////////////////////////////////////////////////////////////////////
396 6fd4a72c Leszek Koltunski
397
  public int getObjectName(int numLayers)
398
    {
399
    switch(numLayers)
400
      {
401
      case 2: return R.string.cube2;
402
      case 3: return R.string.cube3;
403
      case 4: return R.string.cube4;
404
      case 5: return R.string.cube5;
405
      }
406
    return R.string.cube3;
407
    }
408
409
///////////////////////////////////////////////////////////////////////////////////////////////////
410
411
  public int getInventor(int numLayers)
412
    {
413
    switch(numLayers)
414
      {
415
      case 2: return R.string.cube2_inventor;
416
      case 3: return R.string.cube3_inventor;
417
      case 4: return R.string.cube4_inventor;
418
      case 5: return R.string.cube5_inventor;
419
      }
420
    return R.string.cube3_inventor;
421
    }
422
423
///////////////////////////////////////////////////////////////////////////////////////////////////
424
425
  public int getComplexity(int numLayers)
426
    {
427
    switch(numLayers)
428
      {
429
      case 2: return 4;
430
      case 3: return 6;
431
      case 4: return 8;
432
      case 5: return 10;
433
      }
434
    return 6;
435
    }
436 0c52af30 Leszek Koltunski
}