Project

General

Profile

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

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

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
import static org.distorted.effects.scramble.ScrambleEffect.START_AXIS;
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 Static3D[] CENTERS = new Static3D[]
84
         {
85
           new Static3D( DIST_CORNER, DIST_CORNER, DIST_CORNER ),
86
           new Static3D( DIST_CORNER, DIST_CORNER,-DIST_CORNER ),
87
           new Static3D( DIST_CORNER,-DIST_CORNER, DIST_CORNER ),
88
           new Static3D( DIST_CORNER,-DIST_CORNER,-DIST_CORNER ),
89
           new Static3D(-DIST_CORNER, DIST_CORNER, DIST_CORNER ),
90
           new Static3D(-DIST_CORNER, DIST_CORNER,-DIST_CORNER ),
91
           new Static3D(-DIST_CORNER,-DIST_CORNER, DIST_CORNER ),
92
           new Static3D(-DIST_CORNER,-DIST_CORNER,-DIST_CORNER ),
93

    
94
           new Static3D(      0.0f, DIST_EDGE, DIST_EDGE ),
95
           new Static3D( DIST_EDGE,      0.0f, DIST_EDGE ),
96
           new Static3D(      0.0f,-DIST_EDGE, DIST_EDGE ),
97
           new Static3D(-DIST_EDGE,      0.0f, DIST_EDGE ),
98
           new Static3D( DIST_EDGE, DIST_EDGE,      0.0f ),
99
           new Static3D( DIST_EDGE,-DIST_EDGE,      0.0f ),
100
           new Static3D(-DIST_EDGE,-DIST_EDGE,      0.0f ),
101
           new Static3D(-DIST_EDGE, DIST_EDGE,      0.0f ),
102
           new Static3D(      0.0f, DIST_EDGE,-DIST_EDGE ),
103
           new Static3D( DIST_EDGE,      0.0f,-DIST_EDGE ),
104
           new Static3D(      0.0f,-DIST_EDGE,-DIST_EDGE ),
105
           new Static3D(-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, 60, 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
  Static3D[] 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 int randomizeNewRotAxis(Random rnd, int oldRotAxis)
334
    {
335
    int numAxis = ROTATION_AXIS.length;
336

    
337
    if( oldRotAxis == START_AXIS )
338
      {
339
      return rnd.nextInt(numAxis);
340
      }
341
    else
342
      {
343
      int newVector = rnd.nextInt(numAxis-1);
344
      return (newVector>=oldRotAxis ? newVector+1 : newVector);
345
      }
346
    }
347

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

    
350
  public int randomizeNewRow(Random rnd, int oldRotAxis, int oldRow, int newRotAxis)
351
    {
352
    return (oldRotAxis==START_AXIS) ? (rnd.nextFloat()<=0.5f ? 0:2) : (oldRotAxis+newRotAxis==3 ? 2-oldRow : oldRow);
353
    }
354

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

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

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

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

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

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

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

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

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

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

    
409
  public int getComplexity(int numLayers)
410
    {
411
    return 4;
412
    }
413
}
(28-28/30)