Project

General

Profile

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

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

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
import android.graphics.Canvas;
24
import android.graphics.Paint;
25

    
26
import org.distorted.helpers.FactoryCubit;
27
import org.distorted.helpers.FactorySticker;
28
import org.distorted.library.effect.MatrixEffectQuaternion;
29
import org.distorted.library.main.DistortedEffects;
30
import org.distorted.library.main.DistortedTexture;
31
import org.distorted.library.mesh.MeshBase;
32
import org.distorted.library.mesh.MeshSquare;
33
import org.distorted.library.type.Static3D;
34
import org.distorted.library.type.Static4D;
35
import org.distorted.main.R;
36

    
37
import java.util.Random;
38

    
39
///////////////////////////////////////////////////////////////////////////////////////////////////
40

    
41
public class TwistyRedi extends TwistyObject
42
{
43
  private static final int FACES_PER_CUBIT =6;
44

    
45
  // the four rotation axis of a RubikRedi. Must be normalized.
46
  static final Static3D[] ROT_AXIS = new Static3D[]
47
         {
48
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
49
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
50
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
51
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
52
         };
53

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

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

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

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

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

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

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

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

    
136
  private static MeshBase mCornerMesh, mEdgeMesh;
137

    
138
///////////////////////////////////////////////////////////////////////////////////////////////////
139

    
140
  TwistyRedi(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
141
             DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
142
    {
143
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.REDI, res, scrWidth);
144
    }
145

    
146
///////////////////////////////////////////////////////////////////////////////////////////////////
147
// TODO
148

    
149
  double[][] getVertices(int cubitType)
150
    {
151
    return null;
152
    }
153

    
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155
// TODO
156

    
157
  int[][] getVertIndexes(int cubitType)
158
    {
159
    return null;
160
    }
161

    
162
///////////////////////////////////////////////////////////////////////////////////////////////////
163

    
164
  int getNumCubitTypes(int numLayers)
165
    {
166
    return 2;
167
    }
168

    
169
///////////////////////////////////////////////////////////////////////////////////////////////////
170

    
171
  float getScreenRatio()
172
    {
173
    return 0.50f;
174
    }
175

    
176
///////////////////////////////////////////////////////////////////////////////////////////////////
177

    
178
  Static4D[] getQuats()
179
    {
180
    return QUATS;
181
    }
182

    
183
///////////////////////////////////////////////////////////////////////////////////////////////////
184

    
185
  int getNumFaces()
186
    {
187
    return FACE_COLORS.length;
188
    }
189

    
190
///////////////////////////////////////////////////////////////////////////////////////////////////
191

    
192
  boolean shouldResetTextureMaps()
193
    {
194
    return false;
195
    }
196

    
197
///////////////////////////////////////////////////////////////////////////////////////////////////
198

    
199
  int getNumStickerTypes(int numLayers)
200
    {
201
    return 2;
202
    }
203

    
204
///////////////////////////////////////////////////////////////////////////////////////////////////
205

    
206
  float[] getCuts(int size)
207
    {
208
    float[] cuts = new float[2];
209

    
210
    cuts[0] = -SQ3/3 -0.05f;
211
    cuts[1] = +SQ3/3 +0.05f;
212

    
213
    return cuts;
214
    }
215

    
216
///////////////////////////////////////////////////////////////////////////////////////////////////
217

    
218
  int getNumCubitFaces()
219
    {
220
    return FACES_PER_CUBIT;
221
    }
222

    
223
///////////////////////////////////////////////////////////////////////////////////////////////////
224

    
225
  float[][] getCubitPositions(int size)
226
    {
227
    return CENTERS;
228
    }
229

    
230
///////////////////////////////////////////////////////////////////////////////////////////////////
231

    
232
  private Static4D getQuat(int cubit)
233
    {
234
    switch(cubit)
235
      {
236
      case  0: return QUATS[0];                          //  unit quat
237
      case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
238
      case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
239
      case  3: return QUATS[1];                          // 180 along X
240
      case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
241
      case  5: return QUATS[2];                          // 180 along Y
242
      case  6: return QUATS[3];                          // 180 along Z
243
      case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
244

    
245
      case  8: return QUATS[0];
246
      case  9: return QUATS[5];
247
      case 10: return QUATS[3];
248
      case 11: return QUATS[11];
249
      case 12: return QUATS[4];
250
      case 13: return QUATS[7];
251
      case 14: return QUATS[9];
252
      case 15: return QUATS[10];
253
      case 16: return QUATS[2];
254
      case 17: return QUATS[8];
255
      case 18: return QUATS[1];
256
      case 19: return QUATS[6];
257
      }
258

    
259
    return null;
260
    }
261

    
262
///////////////////////////////////////////////////////////////////////////////////////////////////
263

    
264
  MeshBase createCubitMesh(int cubit, int numLayers)
265
    {
266
    MeshBase mesh;
267

    
268
    if( cubit<8 )
269
      {
270
      if( mCornerMesh==null ) mCornerMesh = FactoryCubit.getInstance().createRediCornerMesh();
271
      mesh = mCornerMesh.copy(true);
272
      }
273
    else
274
      {
275
      if( mEdgeMesh==null ) mEdgeMesh = FactoryCubit.getInstance().createRediEdgeMesh();
276
      mesh = mEdgeMesh.copy(true);
277
      }
278

    
279
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit), new Static3D(0,0,0) );
280
    mesh.apply(quat,0xffffffff,0);
281

    
282
    return mesh;
283
    }
284

    
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286

    
287
  int getFaceColor(int cubit, int cubitface, int size)
288
    {
289
    return mFaceMap[cubit][cubitface];
290
    }
291

    
292
///////////////////////////////////////////////////////////////////////////////////////////////////
293

    
294
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
295
    {
296
    int COLORS = FACE_COLORS.length;
297
    FactorySticker factory = FactorySticker.getInstance();
298

    
299
    if( face<COLORS )
300
      {
301
      float F =  0.5f;
302
      float R = 0.10f;
303
      float S = 0.10f;
304
      float[] vertices = { -F,-F, +F,-F, +F,+F, -F,+F};
305

    
306
      factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[face], R);
307
      }
308
    else
309
      {
310
      float F = 0.25f;
311
      float R = 0.05f;
312
      float S = 0.05f;
313
      float[] vertices = { -F,+F, -F,-F, 0, -2*F, +F,-F, +F,+F };
314

    
315
      factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[face-COLORS], R);
316
      }
317
    }
318

    
319
///////////////////////////////////////////////////////////////////////////////////////////////////
320

    
321
  float returnMultiplier()
322
    {
323
    return 2.0f;
324
    }
325

    
326
///////////////////////////////////////////////////////////////////////////////////////////////////
327

    
328
  float[] getRowChances(int numLayers)
329
    {
330
    float[] chances = new float[3];
331

    
332
    chances[0] = 0.5f;
333
    chances[1] = 0.5f;
334
    chances[2] = 1.0f;
335

    
336
    return chances;
337
    }
338

    
339
///////////////////////////////////////////////////////////////////////////////////////////////////
340
// PUBLIC API
341

    
342
  public Static3D[] getRotationAxis()
343
    {
344
    return ROT_AXIS;
345
    }
346

    
347
///////////////////////////////////////////////////////////////////////////////////////////////////
348

    
349
  public int getBasicAngle()
350
    {
351
    return 3;
352
    }
353

    
354
///////////////////////////////////////////////////////////////////////////////////////////////////
355

    
356
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
357
    {
358
    if( num==0 )
359
      {
360
      scramble[num][0] = rnd.nextInt(ROTATION_AXIS.length);
361
      scramble[num][1] = rnd.nextFloat()<=0.5f ? 0:2;
362
      }
363
    else
364
      {
365
      int newVector = rnd.nextInt(ROTATION_AXIS.length-1);
366
      scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
367
      scramble[num][1] = (scramble[num-1][0]+scramble[num][0]==3 ? 2-scramble[num-1][1] : scramble[num-1][1]);
368
      }
369

    
370
    switch( rnd.nextInt(2) )
371
      {
372
      case 0: scramble[num][2] = -1; break;
373
      case 1: scramble[num][2] =  1; break;
374
      }
375
    }
376

    
377
///////////////////////////////////////////////////////////////////////////////////////////////////
378
// The Redi is solved if and only if:
379
//
380
// ??
381

    
382
  public boolean isSolved()
383
    {
384
    int q = CUBITS[0].mQuatIndex;
385

    
386
    return ( CUBITS[ 1].mQuatIndex == q &&
387
             CUBITS[ 2].mQuatIndex == q &&
388
             CUBITS[ 3].mQuatIndex == q &&
389
             CUBITS[ 4].mQuatIndex == q &&
390
             CUBITS[ 5].mQuatIndex == q &&
391
             CUBITS[ 6].mQuatIndex == q &&
392
             CUBITS[ 7].mQuatIndex == q &&
393
             CUBITS[ 8].mQuatIndex == q &&
394
             CUBITS[ 9].mQuatIndex == q &&
395
             CUBITS[10].mQuatIndex == q &&
396
             CUBITS[11].mQuatIndex == q &&
397
             CUBITS[12].mQuatIndex == q &&
398
             CUBITS[13].mQuatIndex == q &&
399
             CUBITS[14].mQuatIndex == q &&
400
             CUBITS[15].mQuatIndex == q &&
401
             CUBITS[16].mQuatIndex == q &&
402
             CUBITS[17].mQuatIndex == q &&
403
             CUBITS[18].mQuatIndex == q &&
404
             CUBITS[19].mQuatIndex == q  );
405
    }
406

    
407
///////////////////////////////////////////////////////////////////////////////////////////////////
408
// only needed for solvers - there are no Redi solvers ATM)
409

    
410
  public String retObjectString()
411
    {
412
    return "";
413
    }
414

    
415
///////////////////////////////////////////////////////////////////////////////////////////////////
416

    
417
  public int getObjectName(int numLayers)
418
    {
419
    return R.string.redi2;
420
    }
421

    
422
///////////////////////////////////////////////////////////////////////////////////////////////////
423

    
424
  public int getInventor(int numLayers)
425
    {
426
    return R.string.redi2_inventor;
427
    }
428

    
429
///////////////////////////////////////////////////////////////////////////////////////////////////
430

    
431
  public int getComplexity(int numLayers)
432
    {
433
    return 4;
434
    }
435
}
(31-31/33)