Project

General

Profile

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

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

1
///////////////////////////////////////////////////////////////////////////////////////////////////
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
import org.distorted.helpers.ObjectShape;
25
import org.distorted.helpers.ObjectSticker;
26
import org.distorted.helpers.ScrambleState;
27
import org.distorted.library.main.DistortedEffects;
28
import org.distorted.library.main.DistortedTexture;
29
import org.distorted.library.mesh.MeshSquare;
30
import org.distorted.library.type.Static3D;
31
import org.distorted.library.type.Static4D;
32
import org.distorted.main.R;
33

    
34
import java.util.Random;
35

    
36
///////////////////////////////////////////////////////////////////////////////////////////////////
37

    
38
public class TwistyRedi extends TwistyObject
39
{
40
  private static final int FACES_PER_CUBIT =9;
41

    
42
  // the four rotation axis of a RubikRedi. Must be normalized.
43
  static final Static3D[] ROT_AXIS = new Static3D[]
44
         {
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
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
49
         };
50

    
51
  private static final int[] BASIC_ANGLE = new int[] { 3,3,3,3 };
52

    
53
  private static final int[] FACE_COLORS = new int[]
54
         {
55
           COLOR_YELLOW, COLOR_WHITE,
56
           COLOR_BLUE  , COLOR_GREEN,
57
           COLOR_RED   , COLOR_ORANGE
58
         };
59

    
60
  // All legal rotation quats of a RubikRedi
61
  private static final Static4D[] QUATS = new Static4D[]
62
         {
63
           new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
64
           new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
65
           new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
66
           new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
67

    
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
           new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
76
         };
77

    
78
  private static final float DIST_CORNER = 1.0f;
79
  private static final float DIST_EDGE   = 1.5f;
80

    
81
  // centers of the 8 corners + 12 edges ( i.e. of the all 20 cubits)
82
  private static final float[][] CENTERS = new float[][]
83
         {
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
             {-DIST_CORNER,-DIST_CORNER,-DIST_CORNER },
92

    
93
             {      0.0f, DIST_EDGE, DIST_EDGE },
94
             { DIST_EDGE,      0.0f, DIST_EDGE },
95
             {      0.0f,-DIST_EDGE, DIST_EDGE },
96
             {-DIST_EDGE,      0.0f, DIST_EDGE },
97
             { DIST_EDGE, DIST_EDGE,      0.0f },
98
             { DIST_EDGE,-DIST_EDGE,      0.0f },
99
             {-DIST_EDGE,-DIST_EDGE,      0.0f },
100
             {-DIST_EDGE, DIST_EDGE,      0.0f },
101
             {      0.0f, DIST_EDGE,-DIST_EDGE },
102
             { DIST_EDGE,      0.0f,-DIST_EDGE },
103
             {      0.0f,-DIST_EDGE,-DIST_EDGE },
104
             {-DIST_EDGE,      0.0f,-DIST_EDGE }
105
         };
106

    
107
  // Colors of the faces of cubits.
108
  // YELLOW 0 WHITE 1 BLUE 2 GREEN 3 RED 4  ORANGE 5
109
  // YELLOW 6 WHITE 7 BLUE 8 GREEN 9 RED 10 ORANGE 11
110
  private static final int[][] mFaceMap = new int[][]
111
         {
112
           {  4, 2, 0 },
113
           {  2, 5, 0 },
114
           {  3, 4, 0 },
115
           {  5, 3, 0 },
116
           {  1, 2, 4 },
117
           {  5, 2, 1 },
118
           {  4, 3, 1 },
119
           {  1, 3, 5 },
120

    
121
           { 10, 8,12 },
122
           {  6,10,12 },
123
           { 10, 9,12 },
124
           {  7,10,12 },
125
           {  8, 6,12 },
126
           {  9, 6,12 },
127
           {  9, 7,12 },
128
           {  8, 7,12 },
129
           { 11, 8,12 },
130
           {  6,11,12 },
131
           { 11, 9,12 },
132
           {  7,11,12 },
133
         };
134

    
135
  private static final double[][] VERTICES_CORNER = new double[][]
136
          {
137
             { 0.0f, 0.0f, 0.0f },
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
             {-0.5f, 0.5f,-0.5f },
145
          };
146

    
147
  private static final int[][] VERT_INDEXES_CORNER = new int[][]
148
          {
149
             { 2,4,3,1 },
150
             { 1,3,5,7 },
151
             { 4,6,5,3 },
152

    
153
             { 2,4,0 },
154
             { 5,7,0 },
155
             { 4,6,0 },
156
             { 7,1,0 },
157
             { 1,2,0 },
158
             { 6,5,0 }
159
          };
160

    
161
  private static final double[][] VERTICES_EDGE = new double[][]
162
          {
163
             {-0.5f, 0.0f, 0.0f},
164
             { 0.5f, 0.0f, 0.0f},
165
             {-0.5f,-1.0f, 0.0f},
166
             { 0.5f,-1.0f, 0.0f},
167
             { 0.0f,-1.5f, 0.0f},
168
             {-0.5f, 0.0f,-1.0f},
169
             { 0.5f, 0.0f,-1.0f},
170
             { 0.0f, 0.0f,-1.5f},
171
          };
172

    
173
  private static final int[][] VERT_INDEXES_EDGE = new int[][]
174
          {
175
             { 0,2,4,3,1 },
176
             { 0,1,6,7,5 },
177
             { 1,3,6 },
178
             { 0,2,5 },
179
             { 4,7,6,3 },
180
             { 4,7,5,2 }
181
          };
182

    
183
  private static final float[][] STICKERS = new float[][]
184
          {
185
             { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f },
186
             { -0.3125f, 0.4375f, -0.3125f, -0.1875f, 0.0f, -0.5f, 0.3125f, -0.1875f, 0.3125f, 0.4375f }
187
          };
188

    
189
  private static final ObjectSticker[] mStickers;
190

    
191
  static
192
    {
193
    mStickers = new ObjectSticker[STICKERS.length];
194
    final float R0 = 0.09f;
195
    final float R1 = 0.06f;
196
    final float[][] radii = { {R0,R0,R0,R0},{R1,R1,R1,R1,R1} };
197
    final float[] strokes = { 0.09f,0.06f };
198

    
199
    for(int s=0; s<STICKERS.length; s++)
200
      {
201
      mStickers[s] = new ObjectSticker(STICKERS[s],null,radii[s],strokes[s]);
202
      }
203
    }
204

    
205
  private int mCurrState;
206
  private int mIndexExcluded;
207
  private final ScrambleState[] mStates;
208
  private int[][] mScrambleTable;
209
  private int[] mNumOccurences;
210

    
211
///////////////////////////////////////////////////////////////////////////////////////////////////
212

    
213
  TwistyRedi(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
214
             DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
215
    {
216
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.REDI, res, scrWidth);
217

    
218
    mStates = new ScrambleState[]
219
      {
220
      new ScrambleState( new int[][] { {0,1,1,0,-1,1, 2,1,2,2,-1,2},{0,1,3,0,-1,3, 2,1,4,2,-1,4},{0,1,5,0,-1,5, 2,1,6,2,-1,6},{0,1,7,0,-1,7, 2,1,8,2,-1,8} } ),
221
      new ScrambleState( new int[][] { {                          },{0,1,3,0,-1,3              },{0,1,5,0,-1,5,             },{              2,1,8,2,-1,8} } ),
222
      new ScrambleState( new int[][] { {                          },{              2,1,4,2,-1,4},{              2,1,6,2,-1,6},{0,1,7,0,-1,7              } } ),
223
      new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{                          },{              2,1,6,2,-1,6},{0,1,7,0,-1,7              } } ),
224
      new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{                          },{0,1,5,0,-1,5,             },{              2,1,8,2,-1,8} } ),
225
      new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{              2,1,4,2,-1,4},{                          },{0,1,7,0,-1,7              } } ),
226
      new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{                          },{              2,1,8,2,-1,8} } ),
227
      new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{0,1,5,0,-1,5,             },{                          } } ),
228
      new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{              2,1,4,2,-1,4},{              2,1,6,2,-1,6},{                          } } ),
229
      };
230
    }
231

    
232
///////////////////////////////////////////////////////////////////////////////////////////////////
233

    
234
  int[] getSolvedQuats(int cubit, int numLayers)
235
    {
236
    int status = retCubitSolvedStatus(cubit,numLayers);
237
    return status<0 ? null : buildSolvedQuats(MovementRedi.FACE_AXIS[status],QUATS);
238
    }
239

    
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241

    
242
  float getScreenRatio()
243
    {
244
    return 0.50f;
245
    }
246

    
247
///////////////////////////////////////////////////////////////////////////////////////////////////
248

    
249
  Static4D[] getQuats()
250
    {
251
    return QUATS;
252
    }
253

    
254
///////////////////////////////////////////////////////////////////////////////////////////////////
255

    
256
  int getNumFaces()
257
    {
258
    return FACE_COLORS.length;
259
    }
260

    
261
///////////////////////////////////////////////////////////////////////////////////////////////////
262

    
263
  int getSolvedFunctionIndex()
264
    {
265
    return 0;
266
    }
267

    
268
///////////////////////////////////////////////////////////////////////////////////////////////////
269

    
270
  boolean shouldResetTextureMaps()
271
    {
272
    return false;
273
    }
274

    
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276

    
277
  int getNumStickerTypes(int numLayers)
278
    {
279
    return STICKERS.length;
280
    }
281

    
282
///////////////////////////////////////////////////////////////////////////////////////////////////
283

    
284
  float[][] getCuts(int size)
285
    {
286
    float C = +SQ3/3 +0.05f;
287
    float[] cut = new float[] {-C,+C};
288
    return new float[][] { cut,cut,cut,cut };
289
    }
290

    
291
///////////////////////////////////////////////////////////////////////////////////////////////////
292

    
293
  int getNumCubitFaces()
294
    {
295
    return FACES_PER_CUBIT;
296
    }
297

    
298
///////////////////////////////////////////////////////////////////////////////////////////////////
299

    
300
  float[][] getCubitPositions(int size)
301
    {
302
    return CENTERS;
303
    }
304

    
305
///////////////////////////////////////////////////////////////////////////////////////////////////
306

    
307
  ObjectShape getObjectShape(int cubit, int numLayers)
308
    {
309
    int variant = getCubitVariant(cubit,numLayers);
310

    
311
    if( variant==0 )
312
      {
313
      float[][] bands     = new float[][] { {0.06f,35,0.5f,0.7f,5,2,2}, {0.01f,35,0.2f,0.4f,5,2,2} };
314
      int[] bandIndices   = new int[] { 0,0,0,1,1,1,1,1,1 };
315
      float[][] corners   = new float[][] { {0.06f,0.12f} };
316
      int[] cornerIndices = new int[]  { -1,0,-1,0,0,0,-1,-1 };
317
      float[][] centers   = new float[][] { { 0.0f, 0.0f, 0.0f} };
318
      int[] centerIndices = new int[] { -1,0,-1,0,0,0,-1,-1 };
319
      return new ObjectShape(VERTICES_CORNER,VERT_INDEXES_CORNER,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
320
      }
321
    else
322
      {
323
      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} };
324
      int[] bandIndices   = new int[] { 0,0,1,1,2,2 };
325
      float[][] corners   = new float[][] { {0.06f,0.20f} };
326
      int[] cornerIndices = new int[] { 0,0,-1,-1,-1,-1,-1,-1 };
327
      float[][] centers   = new float[][] { { 0.0f,-0.75f,-0.75f} };
328
      int[] centerIndices = new int[] { 0,0,-1,-1,-1,-1,-1,-1 };
329
      return new ObjectShape(VERTICES_EDGE,VERT_INDEXES_EDGE,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
330
      }
331
    }
332

    
333
///////////////////////////////////////////////////////////////////////////////////////////////////
334

    
335
  Static4D getQuat(int cubit, int numLayers)
336
    {
337
    switch(cubit)
338
      {
339
      case  0: return QUATS[0];                          //  unit quat
340
      case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
341
      case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
342
      case  3: return QUATS[1];                          // 180 along X
343
      case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
344
      case  5: return QUATS[2];                          // 180 along Y
345
      case  6: return QUATS[3];                          // 180 along Z
346
      case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
347

    
348
      case  8: return QUATS[0];
349
      case  9: return QUATS[5];
350
      case 10: return QUATS[3];
351
      case 11: return QUATS[11];
352
      case 12: return QUATS[4];
353
      case 13: return QUATS[7];
354
      case 14: return QUATS[9];
355
      case 15: return QUATS[10];
356
      case 16: return QUATS[2];
357
      case 17: return QUATS[8];
358
      case 18: return QUATS[1];
359
      case 19: return QUATS[6];
360
      }
361

    
362
    return null;
363
    }
364

    
365
///////////////////////////////////////////////////////////////////////////////////////////////////
366

    
367
  int getNumCubitVariants(int numLayers)
368
    {
369
    return 2;
370
    }
371

    
372
///////////////////////////////////////////////////////////////////////////////////////////////////
373

    
374
  int getCubitVariant(int cubit, int numLayers)
375
    {
376
    return cubit<8 ? 0:1;
377
    }
378

    
379
///////////////////////////////////////////////////////////////////////////////////////////////////
380

    
381
  int getFaceColor(int cubit, int cubitface, int size)
382
    {
383
    return cubitface<3 ? mFaceMap[cubit][cubitface] : STICKERS.length*FACE_COLORS.length;
384
    }
385

    
386
///////////////////////////////////////////////////////////////////////////////////////////////////
387

    
388
  int getColor(int face)
389
    {
390
    return FACE_COLORS[face];
391
    }
392

    
393
///////////////////////////////////////////////////////////////////////////////////////////////////
394

    
395
  ObjectSticker retSticker(int face)
396
    {
397
    return mStickers[face/NUM_FACES];
398
    }
399

    
400
///////////////////////////////////////////////////////////////////////////////////////////////////
401

    
402
  float returnMultiplier()
403
    {
404
    return 2.0f;
405
    }
406

    
407
///////////////////////////////////////////////////////////////////////////////////////////////////
408

    
409
  private void initializeScrambling()
410
    {
411
    int numLayers = getNumLayers();
412

    
413
    if( mScrambleTable ==null )
414
      {
415
      mScrambleTable = new int[NUM_AXIS][numLayers];
416
      }
417
    if( mNumOccurences ==null )
418
      {
419
      int max=0;
420

    
421
      for (ScrambleState mState : mStates)
422
        {
423
        int tmp = mState.getTotal(-1);
424
        if (max < tmp) max = tmp;
425
        }
426

    
427
      mNumOccurences = new int[max];
428
      }
429

    
430
    for(int i=0; i<NUM_AXIS; i++)
431
      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
432
    }
433

    
434
///////////////////////////////////////////////////////////////////////////////////////////////////
435
// PUBLIC API
436

    
437
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
438
    {
439
    if( curr==0 )
440
      {
441
      mCurrState     = 0;
442
      mIndexExcluded =-1;
443
      initializeScrambling();
444
      }
445

    
446
    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
447

    
448
    scramble[curr][0] = info[0];
449
    scramble[curr][1] = info[1];
450
    scramble[curr][2] = info[2];
451

    
452
    mCurrState     = info[3];
453
    mIndexExcluded = info[0];
454
    }
455

    
456
///////////////////////////////////////////////////////////////////////////////////////////////////
457

    
458
  public Static3D[] getRotationAxis()
459
    {
460
    return ROT_AXIS;
461
    }
462

    
463
///////////////////////////////////////////////////////////////////////////////////////////////////
464

    
465
  public int[] getBasicAngle()
466
    {
467
    return BASIC_ANGLE;
468
    }
469

    
470
///////////////////////////////////////////////////////////////////////////////////////////////////
471

    
472
  public int getObjectName(int numLayers)
473
    {
474
    return R.string.redi2;
475
    }
476

    
477
///////////////////////////////////////////////////////////////////////////////////////////////////
478

    
479
  public int getInventor(int numLayers)
480
    {
481
    return R.string.redi2_inventor;
482
    }
483

    
484
///////////////////////////////////////////////////////////////////////////////////////////////////
485

    
486
  public int getComplexity(int numLayers)
487
    {
488
    return 4;
489
    }
490
}
(35-35/41)