Project

General

Profile

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

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

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 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
class TwistyCube extends TwistyObject
39
{
40
  static final Static3D[] ROT_AXIS = new Static3D[]
41
         {
42
           new Static3D(1,0,0),
43
           new Static3D(0,1,0),
44
           new Static3D(0,0,1)
45
         };
46

    
47
  private static final int[] FACE_COLORS = new int[]
48
         {
49
           COLOR_YELLOW, COLOR_WHITE,
50
           COLOR_BLUE  , COLOR_GREEN,
51
           COLOR_RED   , COLOR_ORANGE
52
         };
53

    
54
  private int mCurrState;
55
  private int mIndexExcluded;
56
  private final ScrambleState[] mStates;
57
  private int[][] mScrambleTable;
58
  private int[] mNumOccurences;
59
  private Static4D[] mQuats;
60
  private int[] mBasicAngle;
61
  private ObjectSticker[] mStickers;
62

    
63
///////////////////////////////////////////////////////////////////////////////////////////////////
64

    
65
  TwistyCube(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
66
             DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
67
    {
68
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.CUBE, res, scrWidth);
69

    
70
    int[][] m = new int[16][];
71
    for(int i=1; i<16; i++) m[i] = createEdges(size,i);
72

    
73
    mStates = new ScrambleState[]  // built so that all 3 axes must be present in every 4 consecutive moves
74
      {
75
      new ScrambleState( new int[][] { m[ 1], m[ 2], m[ 3] } ),  // 0
76
      new ScrambleState( new int[][] {  null, m[ 4], m[ 5] } ),  // x
77
      new ScrambleState( new int[][] { m[ 6],  null, m[ 7] } ),  // y
78
      new ScrambleState( new int[][] { m[ 8], m[ 8],  null } ),  // z
79
      new ScrambleState( new int[][] { m[10],  null, m[ 7] } ),  // xy
80
      new ScrambleState( new int[][] { m[11], m[ 9],  null } ),  // xz
81
      new ScrambleState( new int[][] {  null, m[12], m[ 5] } ),  // yx
82
      new ScrambleState( new int[][] { m[ 8], m[13],  null } ),  // yz
83
      new ScrambleState( new int[][] {  null, m[ 4], m[14] } ),  // zx
84
      new ScrambleState( new int[][] { m[ 6],  null, m[15] } ),  // zy
85
      new ScrambleState( new int[][] {  null,  null, m[ 5] } ),  // xyx
86
      new ScrambleState( new int[][] {  null, m[ 4],  null } ),  // xzx
87
      new ScrambleState( new int[][] {  null,  null, m[ 7] } ),  // yxy
88
      new ScrambleState( new int[][] { m[ 6],  null,  null } ),  // yzy
89
      new ScrambleState( new int[][] {  null, m[ 9],  null } ),  // zxz
90
      new ScrambleState( new int[][] { m[ 8],  null,  null } ),  // zyz
91
      };
92
    }
93

    
94
///////////////////////////////////////////////////////////////////////////////////////////////////
95

    
96
  private int[] createEdges(int size, int vertex)
97
    {
98
    int[] ret = new int[9*size];
99

    
100
    for(int l=0; l<size; l++)
101
      {
102
      ret[9*l  ] = l;
103
      ret[9*l+1] =-1;
104
      ret[9*l+2] = vertex;
105
      ret[9*l+3] = l;
106
      ret[9*l+4] = 1;
107
      ret[9*l+5] = vertex;
108
      ret[9*l+6] = l;
109
      ret[9*l+7] = 2;
110
      ret[9*l+8] = vertex;
111
      }
112

    
113
    return ret;
114
    }
115

    
116
///////////////////////////////////////////////////////////////////////////////////////////////////
117

    
118
  private void initializeQuats()
119
    {
120
    mQuats = new Static4D[]
121
         {
122
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
123
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
124
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
125
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
126

    
127
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
128
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
129
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
130
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
131
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
132
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
133
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
134
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
135
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
136
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
137
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
138
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
139

    
140
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
141
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
142
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
143
         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
144
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
145
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
146
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
147
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
148
         };
149
    }
150

    
151
///////////////////////////////////////////////////////////////////////////////////////////////////
152

    
153
  int[] getSolvedQuats(int cubit, int numLayers)
154
    {
155
    if( mQuats ==null ) initializeQuats();
156
    int status = retCubitSolvedStatus(cubit,numLayers);
157
    return status<0 ? null : buildSolvedQuats(MovementCube.FACE_AXIS[status], mQuats);
158
    }
159

    
160
///////////////////////////////////////////////////////////////////////////////////////////////////
161

    
162
  ObjectShape getObjectShape(int cubit, int numLayers)
163
    {
164
    int extraI, extraV, num;
165
    float height;
166

    
167
    switch(numLayers)
168
      {
169
      case 2 : num = 6; extraI = 2; extraV = 2; height = 0.045f; break;
170
      case 3 : num = 5; extraI = 2; extraV = 2; height = 0.045f; break;
171
      case 4 : num = 5; extraI = 1; extraV = 1; height = 0.045f; break;
172
      default: num = 5; extraI = 0; extraV = 0; height = 0.045f; break;
173
      }
174

    
175
    double[][] vertices = new double[][]
176
          {
177
              { 0.5, 0.5, 0.5 },
178
              { 0.5, 0.5,-0.5 },
179
              { 0.5,-0.5, 0.5 },
180
              { 0.5,-0.5,-0.5 },
181
              {-0.5, 0.5, 0.5 },
182
              {-0.5, 0.5,-0.5 },
183
              {-0.5,-0.5, 0.5 },
184
              {-0.5,-0.5,-0.5 },
185
          };
186

    
187
    int[][] vert_indices = new int[][]
188
          {
189
              {2,3,1,0},
190
              {7,6,4,5},
191
              {4,0,1,5},
192
              {7,3,2,6},
193
              {6,2,0,4},
194
              {3,7,5,1}
195
          };
196

    
197
    float[][] bands     = new float[][] { {height,35,0.5f,0.7f,num,extraI,extraV} };
198
    int[] bandIndices   = new int[] { 0,0,0,0,0,0};
199
    float[][] corners   = new float[][] { {0.036f,0.12f} };
200
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
201
    float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
202
    int[] centerIndices = new int[] { 0,0,0,0,0,0,0,0 };
203

    
204
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
205
    }
206

    
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208

    
209
  Static4D getQuat(int cubit, int numLayers)
210
    {
211
    if( mQuats ==null ) initializeQuats();
212
    return mQuats[0];
213
    }
214

    
215
///////////////////////////////////////////////////////////////////////////////////////////////////
216

    
217
  int getNumCubitVariants(int numLayers)
218
    {
219
    return 1;
220
    }
221

    
222
///////////////////////////////////////////////////////////////////////////////////////////////////
223

    
224
  int getCubitVariant(int cubit, int numLayers)
225
    {
226
    return 0;
227
    }
228

    
229
///////////////////////////////////////////////////////////////////////////////////////////////////
230

    
231
  int getColor(int face)
232
    {
233
    return FACE_COLORS[face];
234
    }
235

    
236
///////////////////////////////////////////////////////////////////////////////////////////////////
237

    
238
  ObjectSticker retSticker(int face)
239
    {
240
    if( mStickers==null )
241
      {
242
      final float[][] STICKERS = new float[][]  { { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f } };
243
      final float radius = 0.10f;
244
      final float stroke = 0.08f;
245
      final float[] radii = {radius,radius,radius,radius};
246
      mStickers = new ObjectSticker[STICKERS.length];
247
      mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke );
248
      }
249

    
250
    return mStickers[face/NUM_FACES];
251
    }
252

    
253
///////////////////////////////////////////////////////////////////////////////////////////////////
254

    
255
  float[][] getCubitPositions(int numLayers)
256
    {
257
    int numCubits = numLayers>1 ? 6*numLayers*numLayers - 12*numLayers + 8 : 1;
258
    float[][] tmp = new float[numCubits][];
259

    
260
    float diff = 0.5f*(numLayers-1);
261
    int currentPosition = 0;
262

    
263
    for(int x = 0; x<numLayers; x++)
264
      for(int y = 0; y<numLayers; y++)
265
        for(int z = 0; z<numLayers; z++)
266
          if( x==0 || x==numLayers-1 || y==0 || y==numLayers-1 || z==0 || z==numLayers-1 )
267
            {
268
            tmp[currentPosition++] = new float[] {x-diff,y-diff,z-diff};
269
            }
270

    
271
    return tmp;
272
    }
273

    
274
///////////////////////////////////////////////////////////////////////////////////////////////////
275

    
276
  Static4D[] getQuats()
277
    {
278
    if( mQuats ==null ) initializeQuats();
279
    return mQuats;
280
    }
281

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

    
284
  boolean shouldResetTextureMaps()
285
    {
286
    return false;
287
    }
288

    
289
///////////////////////////////////////////////////////////////////////////////////////////////////
290

    
291
  int getNumFaces()
292
    {
293
    return FACE_COLORS.length;
294
    }
295

    
296
///////////////////////////////////////////////////////////////////////////////////////////////////
297

    
298
  float[][] getCuts(int numLayers)
299
    {
300
    float[][] cuts = new float[3][numLayers-1];
301

    
302
    for(int i=0; i<numLayers-1; i++)
303
      {
304
      float cut = (2-numLayers)*0.5f + i;
305
      cuts[0][i] = cut;
306
      cuts[1][i] = cut;
307
      cuts[2][i] = cut;
308
      }
309

    
310
    return cuts;
311
    }
312

    
313
///////////////////////////////////////////////////////////////////////////////////////////////////
314

    
315
  int getSolvedFunctionIndex()
316
    {
317
    return 0;
318
    }
319

    
320
///////////////////////////////////////////////////////////////////////////////////////////////////
321

    
322
  int getNumStickerTypes(int numLayers)
323
    {
324
    return 1;
325
    }
326

    
327
///////////////////////////////////////////////////////////////////////////////////////////////////
328

    
329
  int getNumCubitFaces()
330
    {
331
    return FACE_COLORS.length;
332
    }
333

    
334
///////////////////////////////////////////////////////////////////////////////////////////////////
335

    
336
  float getScreenRatio()
337
    {
338
    return 0.5f;
339
    }
340

    
341
///////////////////////////////////////////////////////////////////////////////////////////////////
342

    
343
  int getFaceColor(int cubit, int cubitface, int numLayers)
344
    {
345
    return CUBITS[cubit].mRotationRow[cubitface/2] == (cubitface%2==0 ? (1<<(numLayers-1)):1) ? cubitface : NUM_TEXTURES;
346
    }
347

    
348
///////////////////////////////////////////////////////////////////////////////////////////////////
349

    
350
  float returnMultiplier()
351
    {
352
    return getNumLayers();
353
    }
354

    
355
///////////////////////////////////////////////////////////////////////////////////////////////////
356
// PUBLIC API
357

    
358
  public Static3D[] getRotationAxis()
359
    {
360
    return ROT_AXIS;
361
    }
362

    
363
///////////////////////////////////////////////////////////////////////////////////////////////////
364

    
365
  public int[] getBasicAngle()
366
    {
367
    if( mBasicAngle==null ) mBasicAngle = new int[] { 4,4,4 };
368
    return mBasicAngle;
369
    }
370

    
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372

    
373
  private void initializeScrambling()
374
    {
375
    int numLayers = getNumLayers();
376

    
377
    if( mScrambleTable ==null )
378
      {
379
      mScrambleTable = new int[NUM_AXIS][numLayers];
380
      }
381
    if( mNumOccurences ==null )
382
      {
383
      int max=0;
384

    
385
      for (ScrambleState mState : mStates)
386
        {
387
        int tmp = mState.getTotal(-1);
388
        if (max < tmp) max = tmp;
389
        }
390

    
391
      mNumOccurences = new int[max];
392
      }
393

    
394
    for(int i=0; i<NUM_AXIS; i++)
395
      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
396
    }
397

    
398
///////////////////////////////////////////////////////////////////////////////////////////////////
399

    
400
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
401
    {
402
    if( curr==0 )
403
      {
404
      mCurrState     = 0;
405
      mIndexExcluded =-1;
406
      initializeScrambling();
407
      }
408

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

    
411
    scramble[curr][0] = info[0];
412
    scramble[curr][1] = info[1];
413
    scramble[curr][2] = info[2];
414

    
415
    mCurrState     = info[3];
416
    mIndexExcluded = info[0];
417
    }
418

    
419
///////////////////////////////////////////////////////////////////////////////////////////////////
420

    
421
  public int getObjectName(int numLayers)
422
    {
423
    switch(numLayers)
424
      {
425
      case 2: return R.string.cube2;
426
      case 3: return R.string.cube3;
427
      case 4: return R.string.cube4;
428
      case 5: return R.string.cube5;
429
      }
430
    return R.string.cube3;
431
    }
432

    
433
///////////////////////////////////////////////////////////////////////////////////////////////////
434

    
435
  public int getInventor(int numLayers)
436
    {
437
    switch(numLayers)
438
      {
439
      case 2: return R.string.cube2_inventor;
440
      case 3: return R.string.cube3_inventor;
441
      case 4: return R.string.cube4_inventor;
442
      case 5: return R.string.cube5_inventor;
443
      }
444
    return R.string.cube3_inventor;
445
    }
446

    
447
///////////////////////////////////////////////////////////////////////////////////////////////////
448

    
449
  public int getComplexity(int numLayers)
450
    {
451
    switch(numLayers)
452
      {
453
      case 2: return 4;
454
      case 3: return 6;
455
      case 4: return 8;
456
      case 5: return 10;
457
      }
458
    return 6;
459
    }
460
}
(22-22/41)