Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyRedi.java @ a480ee80

1 68f6046c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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
24 2077dd18 Leszek Koltunski
import org.distorted.helpers.ObjectShape;
25 9c06394a Leszek Koltunski
import org.distorted.helpers.ObjectSticker;
26 68f6046c Leszek Koltunski
import org.distorted.library.main.DistortedEffects;
27
import org.distorted.library.main.DistortedTexture;
28
import org.distorted.library.mesh.MeshSquare;
29
import org.distorted.library.type.Static3D;
30
import org.distorted.library.type.Static4D;
31 6fd4a72c Leszek Koltunski
import org.distorted.main.R;
32 68f6046c Leszek Koltunski
33
import java.util.Random;
34
35
///////////////////////////////////////////////////////////////////////////////////////////////////
36
37
public class TwistyRedi extends TwistyObject
38
{
39 516451c4 Leszek Koltunski
  private static final int FACES_PER_CUBIT =9;
40 68f6046c Leszek Koltunski
41
  // the four rotation axis of a RubikRedi. Must be normalized.
42
  static final Static3D[] ROT_AXIS = new Static3D[]
43
         {
44
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
45
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
46
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
47
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
48
         };
49
50 925ed78f Leszek Koltunski
  private static final int[] BASIC_ANGLE = new int[] { 3,3,3,3 };
51
52 68f6046c Leszek Koltunski
  private static final int[] FACE_COLORS = new int[]
53
         {
54
           COLOR_YELLOW, COLOR_WHITE,
55
           COLOR_BLUE  , COLOR_GREEN,
56 323b217c Leszek Koltunski
           COLOR_RED   , COLOR_ORANGE
57 68f6046c Leszek Koltunski
         };
58
59
  // All legal rotation quats of a RubikRedi
60
  private static final Static4D[] QUATS = new Static4D[]
61
         {
62
           new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
63
           new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
64
           new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
65
           new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
66
67
           new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
68
           new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
69
           new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
70
           new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
71
           new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
72
           new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
73
           new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
74
           new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
75
         };
76
77
  private static final float DIST_CORNER = 1.0f;
78
  private static final float DIST_EDGE   = 1.5f;
79
80
  // centers of the 8 corners + 12 edges ( i.e. of the all 20 cubits)
81 e6cf7283 Leszek Koltunski
  private static final float[][] CENTERS = new float[][]
82 68f6046c Leszek Koltunski
         {
83 e6cf7283 Leszek Koltunski
             { DIST_CORNER, DIST_CORNER, DIST_CORNER },
84
             { DIST_CORNER, DIST_CORNER,-DIST_CORNER },
85
             { DIST_CORNER,-DIST_CORNER, DIST_CORNER },
86
             { DIST_CORNER,-DIST_CORNER,-DIST_CORNER },
87
             {-DIST_CORNER, DIST_CORNER, DIST_CORNER },
88
             {-DIST_CORNER, DIST_CORNER,-DIST_CORNER },
89
             {-DIST_CORNER,-DIST_CORNER, DIST_CORNER },
90
             {-DIST_CORNER,-DIST_CORNER,-DIST_CORNER },
91
92
             {      0.0f, DIST_EDGE, DIST_EDGE },
93
             { DIST_EDGE,      0.0f, DIST_EDGE },
94
             {      0.0f,-DIST_EDGE, DIST_EDGE },
95
             {-DIST_EDGE,      0.0f, DIST_EDGE },
96
             { DIST_EDGE, DIST_EDGE,      0.0f },
97
             { DIST_EDGE,-DIST_EDGE,      0.0f },
98
             {-DIST_EDGE,-DIST_EDGE,      0.0f },
99
             {-DIST_EDGE, DIST_EDGE,      0.0f },
100
             {      0.0f, DIST_EDGE,-DIST_EDGE },
101
             { DIST_EDGE,      0.0f,-DIST_EDGE },
102
             {      0.0f,-DIST_EDGE,-DIST_EDGE },
103
             {-DIST_EDGE,      0.0f,-DIST_EDGE }
104 68f6046c Leszek Koltunski
         };
105
106
  // Colors of the faces of cubits.
107 834b2618 Leszek Koltunski
  // YELLOW 0 WHITE 1 BLUE 2 GREEN 3 RED 4  ORANGE 5
108
  // YELLOW 6 WHITE 7 BLUE 8 GREEN 9 RED 10 ORANGE 11
109 68f6046c Leszek Koltunski
  private static final int[][] mFaceMap = new int[][]
110
         {
111 516451c4 Leszek Koltunski
           {  4, 2, 0 },
112
           {  2, 5, 0 },
113
           {  3, 4, 0 },
114
           {  5, 3, 0 },
115
           {  1, 2, 4 },
116
           {  5, 2, 1 },
117
           {  4, 3, 1 },
118
           {  1, 3, 5 },
119
120
           { 10, 8,12 },
121
           {  6,10,12 },
122
           { 10, 9,12 },
123
           {  7,10,12 },
124
           {  8, 6,12 },
125
           {  9, 6,12 },
126
           {  9, 7,12 },
127
           {  8, 7,12 },
128
           { 11, 8,12 },
129
           {  6,11,12 },
130
           { 11, 9,12 },
131
           {  7,11,12 },
132 68f6046c Leszek Koltunski
         };
133
134 680469e6 Leszek Koltunski
  private static final double[][] VERTICES_CORNER = new double[][]
135
          {
136
             { 0.0f, 0.0f, 0.0f },
137
             {-0.5f, 0.5f, 0.5f },
138
             {-0.5f,-0.5f, 0.5f },
139
             { 0.5f, 0.5f, 0.5f },
140
             { 0.5f,-0.5f, 0.5f },
141
             { 0.5f, 0.5f,-0.5f },
142
             { 0.5f,-0.5f,-0.5f },
143
             {-0.5f, 0.5f,-0.5f },
144
          };
145
146
  private static final int[][] VERT_INDEXES_CORNER = new int[][]
147
          {
148
             { 2,4,3,1 },
149
             { 1,3,5,7 },
150
             { 4,6,5,3 },
151
152 516451c4 Leszek Koltunski
             { 2,4,0 },
153
             { 5,7,0 },
154
             { 4,6,0 },
155
             { 7,1,0 },
156
             { 1,2,0 },
157
             { 6,5,0 }
158 680469e6 Leszek Koltunski
          };
159
160
  private static final double[][] VERTICES_EDGE = new double[][]
161
          {
162
             {-0.5f, 0.0f, 0.0f},
163
             { 0.5f, 0.0f, 0.0f},
164
             {-0.5f,-1.0f, 0.0f},
165
             { 0.5f,-1.0f, 0.0f},
166
             { 0.0f,-1.5f, 0.0f},
167
             {-0.5f, 0.0f,-1.0f},
168
             { 0.5f, 0.0f,-1.0f},
169
             { 0.0f, 0.0f,-1.5f},
170
          };
171
172
  private static final int[][] VERT_INDEXES_EDGE = new int[][]
173
          {
174
             { 0,2,4,3,1 },
175
             { 0,1,6,7,5 },
176
             { 1,3,6 },
177
             { 0,2,5 },
178
             { 4,7,6,3 },
179
             { 4,7,5,2 }
180
          };
181
182
  private static final float[][] STICKERS = new float[][]
183
          {
184
             { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f },
185
             { -0.3125f, 0.4375f, -0.3125f, -0.1875f, 0.0f, -0.5f, 0.3125f, -0.1875f, 0.3125f, 0.4375f }
186
          };
187
188 0812242b Leszek Koltunski
  private static int[][] mScrambleTable;
189
  private static int[] mPossibleAxis, mPossibleLayers;
190 4c737817 Leszek Koltunski
  private static int[] mNumOccurences;
191 0812242b Leszek Koltunski
192 9c06394a Leszek Koltunski
  private static final ObjectSticker[] mStickers;
193
194
  static
195
    {
196
    mStickers = new ObjectSticker[STICKERS.length];
197
    final float R0 = 0.09f;
198
    final float R1 = 0.06f;
199
    final float[][] radii = { {R0,R0,R0,R0},{R1,R1,R1,R1,R1} };
200
    final float[] strokes = { 0.09f,0.06f };
201
202
    for(int s=0; s<STICKERS.length; s++)
203
      {
204
      mStickers[s] = new ObjectSticker(STICKERS[s],null,radii[s],strokes[s]);
205
      }
206
    }
207
208 68f6046c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
209
210
  TwistyRedi(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
211
             DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
212
    {
213 db875721 Leszek Koltunski
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.REDI, res, scrWidth);
214 68f6046c Leszek Koltunski
    }
215
216 a480ee80 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
217
218
  int[] getSolvedQuats(int cubit, int numLayers)
219
    {
220
    int status = retCubitSolvedStatus(cubit,numLayers);
221
    return status<0 ? null : buildSolvedQuats(MovementRedi.FACE_AXIS[status],QUATS);
222
    }
223
224 68f6046c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
225
226
  float getScreenRatio()
227
    {
228
    return 0.50f;
229
    }
230
231
///////////////////////////////////////////////////////////////////////////////////////////////////
232
233
  Static4D[] getQuats()
234
    {
235
    return QUATS;
236
    }
237
238
///////////////////////////////////////////////////////////////////////////////////////////////////
239
240
  int getNumFaces()
241
    {
242
    return FACE_COLORS.length;
243
    }
244
245
///////////////////////////////////////////////////////////////////////////////////////////////////
246
247
  boolean shouldResetTextureMaps()
248
    {
249
    return false;
250
    }
251
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253
254 a64e07d0 Leszek Koltunski
  int getNumStickerTypes(int numLayers)
255 68f6046c Leszek Koltunski
    {
256 516451c4 Leszek Koltunski
    return STICKERS.length;
257 68f6046c Leszek Koltunski
    }
258
259
///////////////////////////////////////////////////////////////////////////////////////////////////
260
261 e6734aa9 Leszek Koltunski
  float[][] getCuts(int size)
262 68f6046c Leszek Koltunski
    {
263 668423be Leszek Koltunski
    float C = +SQ3/3 +0.05f;
264
    float[] cut = new float[] {-C,+C};
265 e6734aa9 Leszek Koltunski
    return new float[][] { cut,cut,cut,cut };
266 68f6046c Leszek Koltunski
    }
267
268
///////////////////////////////////////////////////////////////////////////////////////////////////
269
270
  int getNumCubitFaces()
271
    {
272
    return FACES_PER_CUBIT;
273
    }
274
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276
277 e6cf7283 Leszek Koltunski
  float[][] getCubitPositions(int size)
278 68f6046c Leszek Koltunski
    {
279
    return CENTERS;
280
    }
281
282
///////////////////////////////////////////////////////////////////////////////////////////////////
283
284 2077dd18 Leszek Koltunski
  ObjectShape getObjectShape(int cubit, int numLayers)
285
    {
286
    int variant = getCubitVariant(cubit,numLayers);
287
288
    if( variant==0 )
289
      {
290 668423be Leszek Koltunski
      float[][] bands     = new float[][] { {0.06f,35,0.5f,0.7f,5,2,2}, {0.01f,35,0.2f,0.4f,5,2,2} };
291 2077dd18 Leszek Koltunski
      int[] bandIndices   = new int[] { 0,0,0,1,1,1,1,1,1 };
292
      float[][] corners   = new float[][] { {0.06f,0.12f} };
293
      int[] cornerIndices = new int[]  { -1,0,-1,0,0,0,-1,-1 };
294
      float[][] centers   = new float[][] { { 0.0f, 0.0f, 0.0f} };
295
      int[] centerIndices = new int[] { -1,0,-1,0,0,0,-1,-1 };
296
      return new ObjectShape(VERTICES_CORNER,VERT_INDEXES_CORNER,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
297
      }
298
    else
299
      {
300 668423be Leszek Koltunski
      float[][] bands     = new float[][] { {0.038f,35,0.250f,0.7f,7,2,2}, {0.020f,35,0.125f,0.2f,3,1,2}, {0.020f,35,0.125f,0.2f,3,1,1} };
301 2077dd18 Leszek Koltunski
      int[] bandIndices   = new int[] { 0,0,1,1,2,2 };
302
      float[][] corners   = new float[][] { {0.06f,0.20f} };
303
      int[] cornerIndices = new int[] { 0,0,-1,-1,-1,-1,-1,-1 };
304
      float[][] centers   = new float[][] { { 0.0f,-0.75f,-0.75f} };
305
      int[] centerIndices = new int[] { 0,0,-1,-1,-1,-1,-1,-1 };
306
      return new ObjectShape(VERTICES_EDGE,VERT_INDEXES_EDGE,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
307
      }
308
    }
309
310
///////////////////////////////////////////////////////////////////////////////////////////////////
311
312 3e605536 Leszek Koltunski
  Static4D getQuat(int cubit, int numLayers)
313 68f6046c Leszek Koltunski
    {
314
    switch(cubit)
315
      {
316
      case  0: return QUATS[0];                          //  unit quat
317
      case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
318
      case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
319
      case  3: return QUATS[1];                          // 180 along X
320
      case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
321
      case  5: return QUATS[2];                          // 180 along Y
322
      case  6: return QUATS[3];                          // 180 along Z
323
      case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
324
325
      case  8: return QUATS[0];
326
      case  9: return QUATS[5];
327
      case 10: return QUATS[3];
328
      case 11: return QUATS[11];
329
      case 12: return QUATS[4];
330
      case 13: return QUATS[7];
331
      case 14: return QUATS[9];
332
      case 15: return QUATS[10];
333
      case 16: return QUATS[2];
334
      case 17: return QUATS[8];
335
      case 18: return QUATS[1];
336
      case 19: return QUATS[6];
337
      }
338
339
    return null;
340
    }
341
342 2077dd18 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
343
344 3e605536 Leszek Koltunski
  int getNumCubitVariants(int numLayers)
345 2077dd18 Leszek Koltunski
    {
346
    return 2;
347
    }
348
349
///////////////////////////////////////////////////////////////////////////////////////////////////
350
351
  int getCubitVariant(int cubit, int numLayers)
352
    {
353
    return cubit<8 ? 0:1;
354
    }
355
356 68f6046c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
357
358
  int getFaceColor(int cubit, int cubitface, int size)
359
    {
360 516451c4 Leszek Koltunski
    return cubitface<3 ? mFaceMap[cubit][cubitface] : STICKERS.length*FACE_COLORS.length;
361 68f6046c Leszek Koltunski
    }
362
363
///////////////////////////////////////////////////////////////////////////////////////////////////
364
365 9c06394a Leszek Koltunski
  int getColor(int face)
366 68f6046c Leszek Koltunski
    {
367 9c06394a Leszek Koltunski
    return FACE_COLORS[face];
368
    }
369 68f6046c Leszek Koltunski
370 9c06394a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
371
372
  ObjectSticker retSticker(int face)
373
    {
374
    return mStickers[face/NUM_FACES];
375 68f6046c Leszek Koltunski
    }
376
377
///////////////////////////////////////////////////////////////////////////////////////////////////
378
379
  float returnMultiplier()
380
    {
381
    return 2.0f;
382
    }
383
384
///////////////////////////////////////////////////////////////////////////////////////////////////
385
// PUBLIC API
386
387
  public Static3D[] getRotationAxis()
388
    {
389
    return ROT_AXIS;
390
    }
391
392
///////////////////////////////////////////////////////////////////////////////////////////////////
393
394 925ed78f Leszek Koltunski
  public int[] getBasicAngle()
395 68f6046c Leszek Koltunski
    {
396 925ed78f Leszek Koltunski
    return BASIC_ANGLE;
397 68f6046c Leszek Koltunski
    }
398
399 0812242b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
400
401
  private void initializeScrambleTable(int[] first)
402
    {
403
    if( mScrambleTable ==null ) mScrambleTable = new int[NUM_AXIS][2];
404
    if( mPossibleAxis  ==null ) mPossibleAxis  = new int[NUM_AXIS-1];
405
    if( mPossibleLayers==null ) mPossibleLayers= new int[NUM_AXIS-1];
406 4c737817 Leszek Koltunski
    if( mNumOccurences ==null ) mNumOccurences = new int[NUM_AXIS-1];
407 0812242b Leszek Koltunski
408
    for(int i=0; i<NUM_AXIS; i++)
409
      for(int j=0; j<2; j++)
410
        {
411
        mScrambleTable[i][j] = 0;
412
        }
413
414
    mScrambleTable[first[0]][first[1]/2] = 1;
415
    }
416
417
///////////////////////////////////////////////////////////////////////////////////////////////////
418
419 4c737817 Leszek Koltunski
  private boolean areOpposite(int oldAxis, int newAxis, int oldRow, int nom)
420
    {
421
    return (oldAxis+newAxis==3)^(oldRow<nom);
422
    }
423
424
///////////////////////////////////////////////////////////////////////////////////////////////////
425
426
  private int retNewRotationIndex(Random rnd, int nom, int[] oldRot)
427 0812242b Leszek Koltunski
    {
428
    int index=0, max=0;
429
430
    for(int ax=0; ax<NUM_AXIS; ax++)
431
      {
432
      if( ax!=oldRot[0] )
433
        {
434
        mPossibleAxis[index] = ax;
435 4c737817 Leszek Koltunski
        mPossibleLayers[index] = areOpposite(oldRot[0],ax,oldRot[1],nom) ? 0:1;
436 0812242b Leszek Koltunski
        int tmp = mScrambleTable[mPossibleAxis[index]][mPossibleLayers[index]];
437
        if( tmp>max ) max=tmp;
438
        index++;
439
        }
440
      }
441
442 4c737817 Leszek Koltunski
    for(int ax=0; ax<NUM_AXIS-1; ax++)
443
      {
444
      int value = mScrambleTable[mPossibleAxis[ax]][mPossibleLayers[ax]];
445
      mNumOccurences[ax] = max - value + (ax==0 ? 0 : mNumOccurences[ax-1]);
446
      }
447 0812242b Leszek Koltunski
448 4c737817 Leszek Koltunski
    float random= rnd.nextFloat()*mNumOccurences[NUM_AXIS-2];
449 0812242b Leszek Koltunski
450 4c737817 Leszek Koltunski
    for(int ax=0; ax<NUM_AXIS-1; ax++)
451
      {
452
      if( random <= mNumOccurences[ax] )
453
        {
454
        index=ax;
455
        break;
456
        }
457
      }
458 0812242b Leszek Koltunski
459
    mScrambleTable[mPossibleAxis[index]][mPossibleLayers[index]]++;
460
461
    return index;
462
    }
463
464 68f6046c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
465 4c737817 Leszek Koltunski
// PUBLIC API
466 68f6046c Leszek Koltunski
467 9f171eba Leszek Koltunski
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total)
468 68f6046c Leszek Koltunski
    {
469 9f171eba Leszek Koltunski
    if( curr==0 )
470 68f6046c Leszek Koltunski
      {
471 9f171eba Leszek Koltunski
      scramble[curr][0] = rnd.nextInt(NUM_AXIS);
472
      scramble[curr][1] = rnd.nextFloat()<=0.5f ? 0:2;
473 0812242b Leszek Koltunski
      initializeScrambleTable(scramble[curr]);
474 68f6046c Leszek Koltunski
      }
475
    else
476
      {
477 4c737817 Leszek Koltunski
      int index = retNewRotationIndex(rnd,1,scramble[curr-1]);
478 0812242b Leszek Koltunski
      scramble[curr][0] = mPossibleAxis[index];
479
      scramble[curr][1] = 2*mPossibleLayers[index];
480 68f6046c Leszek Koltunski
      }
481
482 5043d5d0 Leszek Koltunski
    switch( rnd.nextInt(2) )
483
      {
484 9f171eba Leszek Koltunski
      case 0: scramble[curr][2] = -1; break;
485
      case 1: scramble[curr][2] =  1; break;
486 5043d5d0 Leszek Koltunski
      }
487 68f6046c Leszek Koltunski
    }
488
489 6fd4a72c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
490
491
  public int getObjectName(int numLayers)
492
    {
493
    return R.string.redi2;
494
    }
495
496
///////////////////////////////////////////////////////////////////////////////////////////////////
497
498
  public int getInventor(int numLayers)
499
    {
500
    return R.string.redi2_inventor;
501
    }
502
503
///////////////////////////////////////////////////////////////////////////////////////////////////
504
505
  public int getComplexity(int numLayers)
506
    {
507
    return 4;
508
    }
509 68f6046c Leszek Koltunski
}