Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyCube.java @ e1dc3366

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 e1dc3366 Leszek Koltunski
  private int[][] mScrambleTable;
136
  private int[] mNumOccurences;
137 caccea6e Leszek Koltunski
138 411c6285 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
139
140 9c2f0c91 Leszek Koltunski
  TwistyCube(int size, Static4D quat, DistortedTexture texture,
141
             MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
142 411c6285 Leszek Koltunski
    {
143 db875721 Leszek Koltunski
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.CUBE, res, scrWidth);
144 caccea6e Leszek Koltunski
145
    int[][] m = new int[16][];
146
    for(int i=1; i<16; i++) m[i] = createEdges(size,i);
147
148 6cf89a3e Leszek Koltunski
    mStates = new ScrambleState[]  // built so that all 3 axes must be present in every 4 consecutive moves
149 caccea6e Leszek Koltunski
      {
150 6cf89a3e Leszek Koltunski
      new ScrambleState( new int[][] { m[ 1], m[ 2], m[ 3] } ),  // 0
151
      new ScrambleState( new int[][] {  null, m[ 4], m[ 5] } ),  // x
152
      new ScrambleState( new int[][] { m[ 6],  null, m[ 7] } ),  // y
153
      new ScrambleState( new int[][] { m[ 8], m[ 8],  null } ),  // z
154
      new ScrambleState( new int[][] { m[10],  null, m[ 7] } ),  // xy
155
      new ScrambleState( new int[][] { m[11], m[ 9],  null } ),  // xz
156
      new ScrambleState( new int[][] {  null, m[12], m[ 5] } ),  // yx
157
      new ScrambleState( new int[][] { m[ 8], m[13],  null } ),  // yz
158
      new ScrambleState( new int[][] {  null, m[ 4], m[14] } ),  // zx
159
      new ScrambleState( new int[][] { m[ 6],  null, m[15] } ),  // zy
160
      new ScrambleState( new int[][] {  null,  null, m[ 5] } ),  // xyx
161
      new ScrambleState( new int[][] {  null, m[ 4],  null } ),  // xzx
162
      new ScrambleState( new int[][] {  null,  null, m[ 7] } ),  // yxy
163
      new ScrambleState( new int[][] { m[ 6],  null,  null } ),  // yzy
164
      new ScrambleState( new int[][] {  null, m[ 9],  null } ),  // zxz
165
      new ScrambleState( new int[][] { m[ 8],  null,  null } ),  // zyz
166 caccea6e Leszek Koltunski
      };
167
    }
168
169
///////////////////////////////////////////////////////////////////////////////////////////////////
170
171
  private int[] createEdges(int size, int vertex)
172
    {
173
    int[] ret = new int[9*size];
174
175
    for(int l=0; l<size; l++)
176
      {
177
      ret[9*l  ] = l;
178
      ret[9*l+1] =-1;
179
      ret[9*l+2] = vertex;
180
      ret[9*l+3] = l;
181
      ret[9*l+4] = 1;
182
      ret[9*l+5] = vertex;
183
      ret[9*l+6] = l;
184
      ret[9*l+7] = 2;
185
      ret[9*l+8] = vertex;
186
      }
187
188
    return ret;
189 411c6285 Leszek Koltunski
    }
190
191 a480ee80 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
192
193
  int[] getSolvedQuats(int cubit, int numLayers)
194
    {
195
    int status = retCubitSolvedStatus(cubit,numLayers);
196
    return status<0 ? null : buildSolvedQuats(MovementCube.FACE_AXIS[status],QUATS);
197
    }
198
199 f10a88a8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
200
201
  ObjectShape getObjectShape(int cubit, int numLayers)
202
    {
203
    int extraI, extraV, num;
204
    float height;
205
206
    switch(numLayers)
207
      {
208
      case 2 : num = 6; extraI = 2; extraV = 2; height = 0.045f; break;
209
      case 3 : num = 5; extraI = 2; extraV = 2; height = 0.045f; break;
210
      case 4 : num = 5; extraI = 1; extraV = 1; height = 0.045f; break;
211
      default: num = 5; extraI = 0; extraV = 0; height = 0.045f; break;
212
      }
213
214
    float[][] bands     = new float[][] { {height,35,0.5f,0.7f,num,extraI,extraV} };
215
    int[] bandIndices   = new int[] { 0,0,0,0,0,0};
216
    float[][] corners   = new float[][] { {0.036f,0.12f} };
217
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
218
    float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
219
    int[] centerIndices = new int[] { 0,0,0,0,0,0,0,0 };
220
221
    return new ObjectShape(VERTICES,VERT_INDEXES,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
222
    }
223
224 ac940e24 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
225
226 3e605536 Leszek Koltunski
  Static4D getQuat(int cubit, int numLayers)
227 ac940e24 Leszek Koltunski
    {
228 3e605536 Leszek Koltunski
    return QUATS[0];
229
    }
230 f10a88a8 Leszek Koltunski
231 3e605536 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
232 ac940e24 Leszek Koltunski
233 3e605536 Leszek Koltunski
  int getNumCubitVariants(int numLayers)
234
    {
235
    return 1;
236
    }
237 ac940e24 Leszek Koltunski
238 3e605536 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
239 f10a88a8 Leszek Koltunski
240 3e605536 Leszek Koltunski
  int getCubitVariant(int cubit, int numLayers)
241
    {
242
    return 0;
243 ac940e24 Leszek Koltunski
    }
244
245 7289fd6c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
246
247 9c06394a Leszek Koltunski
  int getColor(int face)
248 7289fd6c Leszek Koltunski
    {
249 9c06394a Leszek Koltunski
    return FACE_COLORS[face];
250
    }
251
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253 7289fd6c Leszek Koltunski
254 9c06394a Leszek Koltunski
  ObjectSticker retSticker(int face)
255
    {
256
    return mStickers[face/NUM_FACES];
257 7289fd6c Leszek Koltunski
    }
258
259 411c6285 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
260
261 b1f2ccf5 Leszek Koltunski
  float[][] getCubitPositions(int numLayers)
262 a10ada2a Leszek Koltunski
    {
263 b1f2ccf5 Leszek Koltunski
    int numCubits = numLayers>1 ? 6*numLayers*numLayers - 12*numLayers + 8 : 1;
264 e6cf7283 Leszek Koltunski
    float[][] tmp = new float[numCubits][];
265 beb325a0 Leszek Koltunski
266 b1f2ccf5 Leszek Koltunski
    float diff = 0.5f*(numLayers-1);
267 a10ada2a Leszek Koltunski
    int currentPosition = 0;
268 beb325a0 Leszek Koltunski
269 b1f2ccf5 Leszek Koltunski
    for(int x = 0; x<numLayers; x++)
270
      for(int y = 0; y<numLayers; y++)
271
        for(int z = 0; z<numLayers; z++)
272
          if( x==0 || x==numLayers-1 || y==0 || y==numLayers-1 || z==0 || z==numLayers-1 )
273 beb325a0 Leszek Koltunski
            {
274 e6cf7283 Leszek Koltunski
            tmp[currentPosition++] = new float[] {x-diff,y-diff,z-diff};
275 a10ada2a Leszek Koltunski
            }
276 47ba5ddc Leszek Koltunski
277 a10ada2a Leszek Koltunski
    return tmp;
278
    }
279 47ba5ddc Leszek Koltunski
280 beb325a0 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
281
282 10585385 Leszek Koltunski
  Static4D[] getQuats()
283 a10ada2a Leszek Koltunski
    {
284 10585385 Leszek Koltunski
    return QUATS;
285 a10ada2a Leszek Koltunski
    }
286 47ba5ddc Leszek Koltunski
287 eaee1ddc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
288
289
  boolean shouldResetTextureMaps()
290
    {
291
    return false;
292
    }
293
294 47ba5ddc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
295
296 411c6285 Leszek Koltunski
  int getNumFaces()
297 a10ada2a Leszek Koltunski
    {
298 411c6285 Leszek Koltunski
    return FACE_COLORS.length;
299 8f53e513 Leszek Koltunski
    }
300
301 7403cdfa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
302
303 e6734aa9 Leszek Koltunski
  float[][] getCuts(int numLayers)
304 7403cdfa Leszek Koltunski
    {
305 e6734aa9 Leszek Koltunski
    float[][] cuts = new float[3][numLayers-1];
306 a97e02b7 Leszek Koltunski
307 a64e07d0 Leszek Koltunski
    for(int i=0; i<numLayers-1; i++)
308 a97e02b7 Leszek Koltunski
      {
309 e6734aa9 Leszek Koltunski
      float cut = (2-numLayers)*0.5f + i;
310
      cuts[0][i] = cut;
311
      cuts[1][i] = cut;
312
      cuts[2][i] = cut;
313 a97e02b7 Leszek Koltunski
      }
314
315
    return cuts;
316 7403cdfa Leszek Koltunski
    }
317
318 169219a7 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
319
320
  int getSolvedFunctionIndex()
321
    {
322
    return 0;
323
    }
324
325 eab9d8f8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
326
327 a64e07d0 Leszek Koltunski
  int getNumStickerTypes(int numLayers)
328 eab9d8f8 Leszek Koltunski
    {
329 b1f2ccf5 Leszek Koltunski
    return STICKERS.length;
330 eab9d8f8 Leszek Koltunski
    }
331
332 8f53e513 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
333
334
  int getNumCubitFaces()
335
    {
336
    return FACE_COLORS.length;
337 411c6285 Leszek Koltunski
    }
338 47ba5ddc Leszek Koltunski
339 f0fa83ae Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
340
341
  float getScreenRatio()
342
    {
343
    return 0.5f;
344
    }
345
346 f6d06256 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
347
348 f10a88a8 Leszek Koltunski
  int getFaceColor(int cubit, int cubitface, int numLayers)
349 f6d06256 Leszek Koltunski
    {
350 f10a88a8 Leszek Koltunski
    return CUBITS[cubit].mRotationRow[cubitface/2] == (cubitface%2==0 ? (1<<(numLayers-1)):1) ? cubitface : NUM_FACES;
351 f6d06256 Leszek Koltunski
    }
352
353 fb377dae Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
354
355
  float returnMultiplier()
356
    {
357 d99f3a48 Leszek Koltunski
    return getNumLayers();
358 fb377dae Leszek Koltunski
    }
359
360 e844c116 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
361
// PUBLIC API
362
363 12ad3fca Leszek Koltunski
  public Static3D[] getRotationAxis()
364
    {
365 ad38d800 Leszek Koltunski
    return ROT_AXIS;
366 12ad3fca Leszek Koltunski
    }
367
368
///////////////////////////////////////////////////////////////////////////////////////////////////
369
370 925ed78f Leszek Koltunski
  public int[] getBasicAngle()
371 e844c116 Leszek Koltunski
    {
372 925ed78f Leszek Koltunski
    return BASIC_ANGLE;
373 e844c116 Leszek Koltunski
    }
374 39e74052 Leszek Koltunski
375 e1dc3366 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
376
377
  private void initializeScrambling()
378
    {
379
    int numLayers = getNumLayers();
380
381
    if( mScrambleTable ==null )
382
      {
383
      mScrambleTable = new int[NUM_AXIS][numLayers];
384
      }
385
    if( mNumOccurences ==null )
386
      {
387
      int max=0;
388
389
      for (ScrambleState mState : mStates)
390
        {
391
        int tmp = mState.getTotal(-1);
392
        if (max < tmp) max = tmp;
393
        }
394
395
      mNumOccurences = new int[max];
396
      }
397
398
    for(int i=0; i<NUM_AXIS; i++)
399
      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
400
    }
401
402 7c969a6d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
403
404 caccea6e Leszek Koltunski
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
405 7c969a6d Leszek Koltunski
    {
406 9f171eba Leszek Koltunski
    if( curr==0 )
407 5cf34c5f Leszek Koltunski
      {
408 caccea6e Leszek Koltunski
      mCurrState     = 0;
409
      mIndexExcluded =-1;
410 e1dc3366 Leszek Koltunski
      initializeScrambling();
411 5cf34c5f Leszek Koltunski
      }
412
413 e1dc3366 Leszek Koltunski
    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
414 7c969a6d Leszek Koltunski
415 caccea6e Leszek Koltunski
    scramble[curr][0] = info[0];
416
    scramble[curr][1] = info[1];
417
    scramble[curr][2] = info[2];
418 7c969a6d Leszek Koltunski
419 caccea6e Leszek Koltunski
    mCurrState     = info[3];
420
    mIndexExcluded = info[0];
421 e46e17fb Leszek Koltunski
    }
422 f0336037 Leszek Koltunski
423
///////////////////////////////////////////////////////////////////////////////////////////////////
424 6fd4a72c Leszek Koltunski
425
  public int getObjectName(int numLayers)
426
    {
427
    switch(numLayers)
428
      {
429
      case 2: return R.string.cube2;
430
      case 3: return R.string.cube3;
431
      case 4: return R.string.cube4;
432
      case 5: return R.string.cube5;
433
      }
434
    return R.string.cube3;
435
    }
436
437
///////////////////////////////////////////////////////////////////////////////////////////////////
438
439
  public int getInventor(int numLayers)
440
    {
441
    switch(numLayers)
442
      {
443
      case 2: return R.string.cube2_inventor;
444
      case 3: return R.string.cube3_inventor;
445
      case 4: return R.string.cube4_inventor;
446
      case 5: return R.string.cube5_inventor;
447
      }
448
    return R.string.cube3_inventor;
449
    }
450
451
///////////////////////////////////////////////////////////////////////////////////////////////////
452
453
  public int getComplexity(int numLayers)
454
    {
455
    switch(numLayers)
456
      {
457
      case 2: return 4;
458
      case 3: return 6;
459
      case 4: return 8;
460
      case 5: return 10;
461
      }
462
    return 6;
463
    }
464 0c52af30 Leszek Koltunski
}