Project

General

Profile

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

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

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.library.effect.MatrixEffectQuaternion;
27
import org.distorted.library.main.DistortedEffects;
28
import org.distorted.library.main.DistortedTexture;
29
import org.distorted.library.mesh.MeshBase;
30
import org.distorted.library.mesh.MeshSquare;
31
import org.distorted.library.type.Static3D;
32
import org.distorted.library.type.Static4D;
33
import org.distorted.main.R;
34

    
35
import java.util.Random;
36

    
37
///////////////////////////////////////////////////////////////////////////////////////////////////
38

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

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

    
52
  private static final int[] FACE_COLORS = new int[]
53
         {
54
           COLOR_YELLOW, COLOR_WHITE,
55
           COLOR_BLUE  , COLOR_GREEN,
56
           COLOR_RED   , COLOR_ORANGE
57
         };
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
  private static final float[][] CENTERS = new float[][]
82
         {
83
             { 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
         };
105

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

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

    
134
  private static MeshBase mCornerMesh, mEdgeMesh;
135

    
136
///////////////////////////////////////////////////////////////////////////////////////////////////
137

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

    
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145

    
146
  float getScreenRatio()
147
    {
148
    return 0.50f;
149
    }
150

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

    
153
  Static4D[] getQuats()
154
    {
155
    return QUATS;
156
    }
157

    
158
///////////////////////////////////////////////////////////////////////////////////////////////////
159

    
160
  int getNumFaces()
161
    {
162
    return FACE_COLORS.length;
163
    }
164

    
165
///////////////////////////////////////////////////////////////////////////////////////////////////
166

    
167
  boolean shouldResetTextureMaps()
168
    {
169
    return false;
170
    }
171

    
172
///////////////////////////////////////////////////////////////////////////////////////////////////
173

    
174
  int getNumStickerTypes(int numLayers)
175
    {
176
    return 2;
177
    }
178

    
179
///////////////////////////////////////////////////////////////////////////////////////////////////
180

    
181
  float[] getCuts(int size)
182
    {
183
    float[] cuts = new float[2];
184

    
185
    cuts[0] = -SQ3/3 -0.05f;
186
    cuts[1] = +SQ3/3 +0.05f;
187

    
188
    return cuts;
189
    }
190

    
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192

    
193
  int getNumCubitFaces()
194
    {
195
    return FACES_PER_CUBIT;
196
    }
197

    
198
///////////////////////////////////////////////////////////////////////////////////////////////////
199

    
200
  float[][] getCubitPositions(int size)
201
    {
202
    return CENTERS;
203
    }
204

    
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206

    
207
  private Static4D getQuat(int cubit)
208
    {
209
    switch(cubit)
210
      {
211
      case  0: return QUATS[0];                          //  unit quat
212
      case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
213
      case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
214
      case  3: return QUATS[1];                          // 180 along X
215
      case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
216
      case  5: return QUATS[2];                          // 180 along Y
217
      case  6: return QUATS[3];                          // 180 along Z
218
      case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
219

    
220
      case  8: return QUATS[0];
221
      case  9: return QUATS[5];
222
      case 10: return QUATS[3];
223
      case 11: return QUATS[11];
224
      case 12: return QUATS[4];
225
      case 13: return QUATS[7];
226
      case 14: return QUATS[9];
227
      case 15: return QUATS[10];
228
      case 16: return QUATS[2];
229
      case 17: return QUATS[8];
230
      case 18: return QUATS[1];
231
      case 19: return QUATS[6];
232
      }
233

    
234
    return null;
235
    }
236

    
237
///////////////////////////////////////////////////////////////////////////////////////////////////
238

    
239
  MeshBase createCubitMesh(int cubit, int numLayers)
240
    {
241
    MeshBase mesh;
242

    
243
    if( cubit<8 )
244
      {
245
      if( mCornerMesh==null ) mCornerMesh = FactoryCubit.getInstance().createRediCornerMesh();
246
      mesh = mCornerMesh.copy(true);
247
      }
248
    else
249
      {
250
      if( mEdgeMesh==null ) mEdgeMesh = FactoryCubit.getInstance().createRediEdgeMesh();
251
      mesh = mEdgeMesh.copy(true);
252
      }
253

    
254
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit), new Static3D(0,0,0) );
255
    mesh.apply(quat,0xffffffff,0);
256

    
257
    return mesh;
258
    }
259

    
260
///////////////////////////////////////////////////////////////////////////////////////////////////
261

    
262
  int getFaceColor(int cubit, int cubitface, int size)
263
    {
264
    return mFaceMap[cubit][cubitface];
265
    }
266

    
267
///////////////////////////////////////////////////////////////////////////////////////////////////
268

    
269
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
270
    {
271
    int COLORS = FACE_COLORS.length;
272
    FactorySticker factory = FactorySticker.getInstance();
273

    
274
    if( face<COLORS )
275
      {
276
      float F =  0.5f;
277
      float R = 0.10f;
278
      float S = 0.10f;
279
      float[] vertices = { -F,-F, +F,-F, +F,+F, -F,+F};
280

    
281
      factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[face], R);
282
      }
283
    else
284
      {
285
      float F = 0.25f;
286
      float R = 0.05f;
287
      float S = 0.05f;
288
      float[] vertices = { -F,+F, -F,-F, 0, -2*F, +F,-F, +F,+F };
289

    
290
      factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[face-COLORS], R);
291
      }
292
    }
293

    
294
///////////////////////////////////////////////////////////////////////////////////////////////////
295

    
296
  float returnMultiplier()
297
    {
298
    return 2.0f;
299
    }
300

    
301
///////////////////////////////////////////////////////////////////////////////////////////////////
302

    
303
  float[] getRowChances(int numLayers)
304
    {
305
    float[] chances = new float[3];
306

    
307
    chances[0] = 0.5f;
308
    chances[1] = 0.5f;
309
    chances[2] = 1.0f;
310

    
311
    return chances;
312
    }
313

    
314
///////////////////////////////////////////////////////////////////////////////////////////////////
315
// PUBLIC API
316

    
317
  public Static3D[] getRotationAxis()
318
    {
319
    return ROT_AXIS;
320
    }
321

    
322
///////////////////////////////////////////////////////////////////////////////////////////////////
323

    
324
  public int getBasicAngle()
325
    {
326
    return 3;
327
    }
328

    
329
///////////////////////////////////////////////////////////////////////////////////////////////////
330

    
331
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
332
    {
333
    if( num==0 )
334
      {
335
      scramble[num][0] = rnd.nextInt(ROTATION_AXIS.length);
336
      scramble[num][1] = rnd.nextFloat()<=0.5f ? 0:2;
337
      }
338
    else
339
      {
340
      int newVector = rnd.nextInt(ROTATION_AXIS.length-1);
341
      scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
342
      scramble[num][1] = (scramble[num-1][0]+scramble[num][0]==3 ? 2-scramble[num-1][1] : scramble[num-1][1]);
343
      }
344

    
345
    switch( rnd.nextInt(2) )
346
      {
347
      case 0: scramble[num][2] = -1; break;
348
      case 1: scramble[num][2] =  1; break;
349
      }
350
    }
351

    
352
///////////////////////////////////////////////////////////////////////////////////////////////////
353
// The Redi is solved if and only if:
354
//
355
// ??
356

    
357
  public boolean isSolved()
358
    {
359
    int q = CUBITS[0].mQuatIndex;
360

    
361
    return ( CUBITS[ 1].mQuatIndex == q &&
362
             CUBITS[ 2].mQuatIndex == q &&
363
             CUBITS[ 3].mQuatIndex == q &&
364
             CUBITS[ 4].mQuatIndex == q &&
365
             CUBITS[ 5].mQuatIndex == q &&
366
             CUBITS[ 6].mQuatIndex == q &&
367
             CUBITS[ 7].mQuatIndex == q &&
368
             CUBITS[ 8].mQuatIndex == q &&
369
             CUBITS[ 9].mQuatIndex == q &&
370
             CUBITS[10].mQuatIndex == q &&
371
             CUBITS[11].mQuatIndex == q &&
372
             CUBITS[12].mQuatIndex == q &&
373
             CUBITS[13].mQuatIndex == q &&
374
             CUBITS[14].mQuatIndex == q &&
375
             CUBITS[15].mQuatIndex == q &&
376
             CUBITS[16].mQuatIndex == q &&
377
             CUBITS[17].mQuatIndex == q &&
378
             CUBITS[18].mQuatIndex == q &&
379
             CUBITS[19].mQuatIndex == q  );
380
    }
381

    
382
///////////////////////////////////////////////////////////////////////////////////////////////////
383
// only needed for solvers - there are no Redi solvers ATM)
384

    
385
  public String retObjectString()
386
    {
387
    return "";
388
    }
389

    
390
///////////////////////////////////////////////////////////////////////////////////////////////////
391

    
392
  public int getObjectName(int numLayers)
393
    {
394
    return R.string.redi2;
395
    }
396

    
397
///////////////////////////////////////////////////////////////////////////////////////////////////
398

    
399
  public int getInventor(int numLayers)
400
    {
401
    return R.string.redi2_inventor;
402
    }
403

    
404
///////////////////////////////////////////////////////////////////////////////////////////////////
405

    
406
  public int getComplexity(int numLayers)
407
    {
408
    return 4;
409
    }
410
}
(33-33/35)