Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyRedi.java @ 749ef882

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

    
148
  float getScreenRatio()
149
    {
150
    return 0.50f;
151
    }
152

    
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154

    
155
  Static4D[] getQuats()
156
    {
157
    return QUATS;
158
    }
159

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

    
162
  int getNumFaces()
163
    {
164
    return FACE_COLORS.length;
165
    }
166

    
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168

    
169
  boolean shouldResetTextureMaps()
170
    {
171
    return false;
172
    }
173

    
174
///////////////////////////////////////////////////////////////////////////////////////////////////
175

    
176
  int getNumStickerTypes(int numLayers)
177
    {
178
    return 2;
179
    }
180

    
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182

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

    
187
    cuts[0] = -SQ3/3 -0.05f;
188
    cuts[1] = +SQ3/3 +0.05f;
189

    
190
    return cuts;
191
    }
192

    
193
///////////////////////////////////////////////////////////////////////////////////////////////////
194

    
195
  int getNumCubitFaces()
196
    {
197
    return FACES_PER_CUBIT;
198
    }
199

    
200
///////////////////////////////////////////////////////////////////////////////////////////////////
201

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

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

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

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

    
236
    return null;
237
    }
238

    
239
///////////////////////////////////////////////////////////////////////////////////////////////////
240

    
241
  MeshBase createCubitMesh(int cubit, int numLayers)
242
    {
243
    MeshBase mesh;
244

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

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

    
259
    return mesh;
260
    }
261

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

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

    
269
///////////////////////////////////////////////////////////////////////////////////////////////////
270

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

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

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

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

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

    
298
  float returnMultiplier()
299
    {
300
    return 2.0f;
301
    }
302

    
303
///////////////////////////////////////////////////////////////////////////////////////////////////
304

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

    
309
    chances[0] = 0.5f;
310
    chances[1] = 0.5f;
311
    chances[2] = 1.0f;
312

    
313
    return chances;
314
    }
315

    
316
///////////////////////////////////////////////////////////////////////////////////////////////////
317
// PUBLIC API
318

    
319
  public Static3D[] getRotationAxis()
320
    {
321
    return ROT_AXIS;
322
    }
323

    
324
///////////////////////////////////////////////////////////////////////////////////////////////////
325

    
326
  public int getBasicAngle()
327
    {
328
    return 3;
329
    }
330

    
331
///////////////////////////////////////////////////////////////////////////////////////////////////
332

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

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

    
354
///////////////////////////////////////////////////////////////////////////////////////////////////
355
// The Redi is solved if and only if:
356
//
357
// ??
358

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

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

    
384
///////////////////////////////////////////////////////////////////////////////////////////////////
385
// only needed for solvers - there are no Redi solvers ATM)
386

    
387
  public String retObjectString()
388
    {
389
    return "";
390
    }
391

    
392
///////////////////////////////////////////////////////////////////////////////////////////////////
393

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

    
399
///////////////////////////////////////////////////////////////////////////////////////////////////
400

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

    
406
///////////////////////////////////////////////////////////////////////////////////////////////////
407

    
408
  public int getComplexity(int numLayers)
409
    {
410
    return 4;
411
    }
412
}
(31-31/33)