Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyRedi.java @ 20898e6f

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 169219a7 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
246
247
  int getSolvedFunctionIndex()
248
    {
249
    return 0;
250
    }
251
252 68f6046c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
253
254
  boolean shouldResetTextureMaps()
255
    {
256
    return false;
257
    }
258
259
///////////////////////////////////////////////////////////////////////////////////////////////////
260
261 a64e07d0 Leszek Koltunski
  int getNumStickerTypes(int numLayers)
262 68f6046c Leszek Koltunski
    {
263 516451c4 Leszek Koltunski
    return STICKERS.length;
264 68f6046c Leszek Koltunski
    }
265
266
///////////////////////////////////////////////////////////////////////////////////////////////////
267
268 e6734aa9 Leszek Koltunski
  float[][] getCuts(int size)
269 68f6046c Leszek Koltunski
    {
270 668423be Leszek Koltunski
    float C = +SQ3/3 +0.05f;
271
    float[] cut = new float[] {-C,+C};
272 e6734aa9 Leszek Koltunski
    return new float[][] { cut,cut,cut,cut };
273 68f6046c Leszek Koltunski
    }
274
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276
277
  int getNumCubitFaces()
278
    {
279
    return FACES_PER_CUBIT;
280
    }
281
282
///////////////////////////////////////////////////////////////////////////////////////////////////
283
284 e6cf7283 Leszek Koltunski
  float[][] getCubitPositions(int size)
285 68f6046c Leszek Koltunski
    {
286
    return CENTERS;
287
    }
288
289
///////////////////////////////////////////////////////////////////////////////////////////////////
290
291 2077dd18 Leszek Koltunski
  ObjectShape getObjectShape(int cubit, int numLayers)
292
    {
293
    int variant = getCubitVariant(cubit,numLayers);
294
295
    if( variant==0 )
296
      {
297 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} };
298 2077dd18 Leszek Koltunski
      int[] bandIndices   = new int[] { 0,0,0,1,1,1,1,1,1 };
299
      float[][] corners   = new float[][] { {0.06f,0.12f} };
300
      int[] cornerIndices = new int[]  { -1,0,-1,0,0,0,-1,-1 };
301
      float[][] centers   = new float[][] { { 0.0f, 0.0f, 0.0f} };
302
      int[] centerIndices = new int[] { -1,0,-1,0,0,0,-1,-1 };
303
      return new ObjectShape(VERTICES_CORNER,VERT_INDEXES_CORNER,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
304
      }
305
    else
306
      {
307 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} };
308 2077dd18 Leszek Koltunski
      int[] bandIndices   = new int[] { 0,0,1,1,2,2 };
309
      float[][] corners   = new float[][] { {0.06f,0.20f} };
310
      int[] cornerIndices = new int[] { 0,0,-1,-1,-1,-1,-1,-1 };
311
      float[][] centers   = new float[][] { { 0.0f,-0.75f,-0.75f} };
312
      int[] centerIndices = new int[] { 0,0,-1,-1,-1,-1,-1,-1 };
313
      return new ObjectShape(VERTICES_EDGE,VERT_INDEXES_EDGE,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
314
      }
315
    }
316
317
///////////////////////////////////////////////////////////////////////////////////////////////////
318
319 3e605536 Leszek Koltunski
  Static4D getQuat(int cubit, int numLayers)
320 68f6046c Leszek Koltunski
    {
321
    switch(cubit)
322
      {
323
      case  0: return QUATS[0];                          //  unit quat
324
      case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
325
      case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
326
      case  3: return QUATS[1];                          // 180 along X
327
      case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
328
      case  5: return QUATS[2];                          // 180 along Y
329
      case  6: return QUATS[3];                          // 180 along Z
330
      case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
331
332
      case  8: return QUATS[0];
333
      case  9: return QUATS[5];
334
      case 10: return QUATS[3];
335
      case 11: return QUATS[11];
336
      case 12: return QUATS[4];
337
      case 13: return QUATS[7];
338
      case 14: return QUATS[9];
339
      case 15: return QUATS[10];
340
      case 16: return QUATS[2];
341
      case 17: return QUATS[8];
342
      case 18: return QUATS[1];
343
      case 19: return QUATS[6];
344
      }
345
346
    return null;
347
    }
348
349 2077dd18 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
350
351 3e605536 Leszek Koltunski
  int getNumCubitVariants(int numLayers)
352 2077dd18 Leszek Koltunski
    {
353
    return 2;
354
    }
355
356
///////////////////////////////////////////////////////////////////////////////////////////////////
357
358
  int getCubitVariant(int cubit, int numLayers)
359
    {
360
    return cubit<8 ? 0:1;
361
    }
362
363 68f6046c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
364
365
  int getFaceColor(int cubit, int cubitface, int size)
366
    {
367 516451c4 Leszek Koltunski
    return cubitface<3 ? mFaceMap[cubit][cubitface] : STICKERS.length*FACE_COLORS.length;
368 68f6046c Leszek Koltunski
    }
369
370
///////////////////////////////////////////////////////////////////////////////////////////////////
371
372 9c06394a Leszek Koltunski
  int getColor(int face)
373 68f6046c Leszek Koltunski
    {
374 9c06394a Leszek Koltunski
    return FACE_COLORS[face];
375
    }
376 68f6046c Leszek Koltunski
377 9c06394a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
378
379
  ObjectSticker retSticker(int face)
380
    {
381
    return mStickers[face/NUM_FACES];
382 68f6046c Leszek Koltunski
    }
383
384
///////////////////////////////////////////////////////////////////////////////////////////////////
385
386
  float returnMultiplier()
387
    {
388
    return 2.0f;
389
    }
390
391
///////////////////////////////////////////////////////////////////////////////////////////////////
392
// PUBLIC API
393
394
  public Static3D[] getRotationAxis()
395
    {
396
    return ROT_AXIS;
397
    }
398
399
///////////////////////////////////////////////////////////////////////////////////////////////////
400
401 925ed78f Leszek Koltunski
  public int[] getBasicAngle()
402 68f6046c Leszek Koltunski
    {
403 925ed78f Leszek Koltunski
    return BASIC_ANGLE;
404 68f6046c Leszek Koltunski
    }
405
406 0812242b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
407
408
  private void initializeScrambleTable(int[] first)
409
    {
410
    if( mScrambleTable ==null ) mScrambleTable = new int[NUM_AXIS][2];
411
    if( mPossibleAxis  ==null ) mPossibleAxis  = new int[NUM_AXIS-1];
412
    if( mPossibleLayers==null ) mPossibleLayers= new int[NUM_AXIS-1];
413 4c737817 Leszek Koltunski
    if( mNumOccurences ==null ) mNumOccurences = new int[NUM_AXIS-1];
414 0812242b Leszek Koltunski
415
    for(int i=0; i<NUM_AXIS; i++)
416
      for(int j=0; j<2; j++)
417
        {
418
        mScrambleTable[i][j] = 0;
419
        }
420
421
    mScrambleTable[first[0]][first[1]/2] = 1;
422
    }
423
424
///////////////////////////////////////////////////////////////////////////////////////////////////
425
426 4c737817 Leszek Koltunski
  private boolean areOpposite(int oldAxis, int newAxis, int oldRow, int nom)
427
    {
428
    return (oldAxis+newAxis==3)^(oldRow<nom);
429
    }
430
431
///////////////////////////////////////////////////////////////////////////////////////////////////
432
433
  private int retNewRotationIndex(Random rnd, int nom, int[] oldRot)
434 0812242b Leszek Koltunski
    {
435
    int index=0, max=0;
436
437
    for(int ax=0; ax<NUM_AXIS; ax++)
438
      {
439
      if( ax!=oldRot[0] )
440
        {
441
        mPossibleAxis[index] = ax;
442 4c737817 Leszek Koltunski
        mPossibleLayers[index] = areOpposite(oldRot[0],ax,oldRot[1],nom) ? 0:1;
443 0812242b Leszek Koltunski
        int tmp = mScrambleTable[mPossibleAxis[index]][mPossibleLayers[index]];
444
        if( tmp>max ) max=tmp;
445
        index++;
446
        }
447
      }
448
449 4c737817 Leszek Koltunski
    for(int ax=0; ax<NUM_AXIS-1; ax++)
450
      {
451
      int value = mScrambleTable[mPossibleAxis[ax]][mPossibleLayers[ax]];
452
      mNumOccurences[ax] = max - value + (ax==0 ? 0 : mNumOccurences[ax-1]);
453
      }
454 0812242b Leszek Koltunski
455 4c737817 Leszek Koltunski
    float random= rnd.nextFloat()*mNumOccurences[NUM_AXIS-2];
456 0812242b Leszek Koltunski
457 4c737817 Leszek Koltunski
    for(int ax=0; ax<NUM_AXIS-1; ax++)
458
      {
459
      if( random <= mNumOccurences[ax] )
460
        {
461
        index=ax;
462
        break;
463
        }
464
      }
465 0812242b Leszek Koltunski
466
    mScrambleTable[mPossibleAxis[index]][mPossibleLayers[index]]++;
467
468
    return index;
469
    }
470
471 68f6046c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
472 4c737817 Leszek Koltunski
// PUBLIC API
473 68f6046c Leszek Koltunski
474 9f171eba Leszek Koltunski
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total)
475 68f6046c Leszek Koltunski
    {
476 9f171eba Leszek Koltunski
    if( curr==0 )
477 68f6046c Leszek Koltunski
      {
478 9f171eba Leszek Koltunski
      scramble[curr][0] = rnd.nextInt(NUM_AXIS);
479
      scramble[curr][1] = rnd.nextFloat()<=0.5f ? 0:2;
480 0812242b Leszek Koltunski
      initializeScrambleTable(scramble[curr]);
481 68f6046c Leszek Koltunski
      }
482
    else
483
      {
484 4c737817 Leszek Koltunski
      int index = retNewRotationIndex(rnd,1,scramble[curr-1]);
485 0812242b Leszek Koltunski
      scramble[curr][0] = mPossibleAxis[index];
486
      scramble[curr][1] = 2*mPossibleLayers[index];
487 68f6046c Leszek Koltunski
      }
488
489 5043d5d0 Leszek Koltunski
    switch( rnd.nextInt(2) )
490
      {
491 9f171eba Leszek Koltunski
      case 0: scramble[curr][2] = -1; break;
492
      case 1: scramble[curr][2] =  1; break;
493 5043d5d0 Leszek Koltunski
      }
494 68f6046c Leszek Koltunski
    }
495
496 6fd4a72c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
497
498
  public int getObjectName(int numLayers)
499
    {
500
    return R.string.redi2;
501
    }
502
503
///////////////////////////////////////////////////////////////////////////////////////////////////
504
505
  public int getInventor(int numLayers)
506
    {
507
    return R.string.redi2_inventor;
508
    }
509
510
///////////////////////////////////////////////////////////////////////////////////////////////////
511
512
  public int getComplexity(int numLayers)
513
    {
514
    return 4;
515
    }
516 68f6046c Leszek Koltunski
}