Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyIvy.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 TwistyIvy extends TwistyObject
42
{
43
  private static final int FACES_PER_CUBIT =6;
44

    
45
  // the four rotation axis of a RubikIvy. 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 RubikIvy
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 int[][] mFaceMap =
80
         {
81
           {  4, 2, 0, 12,12,12 },
82
           {  5, 2, 1, 12,12,12 },
83
           {  4, 3, 1, 12,12,12 },
84
           {  5, 3, 0, 12,12,12 },
85

    
86
           {  6, 12,12,12,12,12 },
87
           {  7, 12,12,12,12,12 },
88
           {  8, 12,12,12,12,12 },
89
           {  9, 12,12,12,12,12 },
90
           { 10, 12,12,12,12,12 },
91
           { 11, 12,12,12,12,12 },
92
         };
93

    
94
  private static MeshBase mCornerMesh, mFaceMesh;
95

    
96
///////////////////////////////////////////////////////////////////////////////////////////////////
97

    
98
  TwistyIvy(int size, Static4D quat, DistortedTexture texture,
99
            MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
100
    {
101
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.IVY, res, scrWidth);
102
    }
103

    
104
///////////////////////////////////////////////////////////////////////////////////////////////////
105
// don't use this
106

    
107
  double[][] getVertices(int cubitType)
108
    {
109
    return null;
110
    }
111

    
112
///////////////////////////////////////////////////////////////////////////////////////////////////
113
// don't use this
114

    
115
  int[][] getVertIndexes(int cubitType)
116
    {
117
    return null;
118
    }
119

    
120
///////////////////////////////////////////////////////////////////////////////////////////////////
121

    
122
  int getNumCubitTypes(int numLayers)
123
    {
124
    return 2;
125
    }
126

    
127
///////////////////////////////////////////////////////////////////////////////////////////////////
128

    
129
  float getScreenRatio()
130
    {
131
    return 1.0f;
132
    }
133

    
134
///////////////////////////////////////////////////////////////////////////////////////////////////
135

    
136
  Static4D[] getQuats()
137
    {
138
    return QUATS;
139
    }
140

    
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142

    
143
  int getNumFaces()
144
    {
145
    return FACE_COLORS.length;
146
    }
147

    
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149

    
150
  boolean shouldResetTextureMaps()
151
    {
152
    return false;
153
    }
154

    
155
///////////////////////////////////////////////////////////////////////////////////////////////////
156

    
157
  int getNumStickerTypes(int numLayers)
158
    {
159
    return 2;
160
    }
161

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

    
164
  float[] getCuts(int numLayers)
165
    {
166
    float[] cuts = new float[1];
167
    cuts[0] = 0.0f;
168

    
169
    return cuts;
170
    }
171

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

    
174
  int getNumCubitFaces()
175
    {
176
    return FACES_PER_CUBIT;
177
    }
178

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

    
181
  float[][] getCubitPositions(int numLayers)
182
    {
183
    final float DIST_CORNER = (numLayers-1)*0.50f;
184
    final float DIST_CENTER = (numLayers-1)*0.50f;
185

    
186
    final float[][] CENTERS = new float[10][];
187

    
188
    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
189
    CENTERS[1] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
190
    CENTERS[2] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
191
    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
192
    CENTERS[4] = new float[] { DIST_CENTER,           0,           0 };
193
    CENTERS[5] = new float[] {-DIST_CENTER,           0,           0 };
194
    CENTERS[6] = new float[] {           0, DIST_CENTER,           0 };
195
    CENTERS[7] = new float[] {           0,-DIST_CENTER,           0 };
196
    CENTERS[8] = new float[] {           0,           0, DIST_CENTER };
197
    CENTERS[9] = new float[] {           0,           0,-DIST_CENTER };
198

    
199
    return CENTERS;
200
    }
201

    
202
///////////////////////////////////////////////////////////////////////////////////////////////////
203

    
204
  private int getQuat(int cubit)
205
    {
206
    switch(cubit)
207
      {
208
      case  0: return 0;
209
      case  1: return 2;
210
      case  2: return 3;
211
      case  3: return 1;
212

    
213
      case  4: return 8;
214
      case  5: return 11;
215
      case  6: return 10;
216
      case  7: return 9;
217
      case  8: return 0;
218
      case  9: return 2;
219
      }
220

    
221
    return 0;
222
    }
223

    
224
///////////////////////////////////////////////////////////////////////////////////////////////////
225

    
226
  MeshBase createCubitMesh(int cubit, int numLayers)
227
    {
228
    MeshBase mesh;
229

    
230
    if( cubit<4 )
231
      {
232
      if( mCornerMesh==null ) mCornerMesh = FactoryCubit.getInstance().createIvyCornerMesh();
233
      mesh = mCornerMesh.copy(true);
234
      }
235
    else
236
      {
237
      if( mFaceMesh==null ) mFaceMesh = FactoryCubit.getInstance().createIvyFaceMesh();
238
      mesh = mFaceMesh.copy(true);
239
      }
240

    
241
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( QUATS[getQuat(cubit)], new Static3D(0,0,0) );
242
    mesh.apply(quat,0xffffffff,0);
243

    
244
    return mesh;
245
    }
246

    
247
///////////////////////////////////////////////////////////////////////////////////////////////////
248

    
249
  int getFaceColor(int cubit, int cubitface, int numLayers)
250
    {
251
    return mFaceMap[cubit][cubitface];
252
    }
253

    
254
///////////////////////////////////////////////////////////////////////////////////////////////////
255

    
256
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
257
    {
258
    int COLORS = FACE_COLORS.length;
259
    FactorySticker factory = FactorySticker.getInstance();
260
    float S = 0.08f;
261
    float R = 0.12f;
262

    
263
    if( face<COLORS )
264
      {
265
      factory.drawIvyCornerSticker(canvas, paint, left, top, FACE_COLORS[face%COLORS], S, R);
266
      }
267
    else
268
      {
269
      factory.drawIvyCenterSticker(canvas, paint, left, top, FACE_COLORS[face%COLORS], S, R);
270
      }
271
    }
272

    
273
///////////////////////////////////////////////////////////////////////////////////////////////////
274

    
275
  float returnMultiplier()
276
    {
277
    return 2.0f;
278
    }
279

    
280
///////////////////////////////////////////////////////////////////////////////////////////////////
281

    
282
  float[] getRowChances(int numLayers)
283
    {
284
    float[] chances = new float[2];
285
    chances[0] = 0.5f;
286
    chances[1] = 1.0f;
287

    
288
    return chances;
289
    }
290

    
291
///////////////////////////////////////////////////////////////////////////////////////////////////
292
// PUBLIC API
293

    
294
  public Static3D[] getRotationAxis()
295
    {
296
    return ROT_AXIS;
297
    }
298

    
299
///////////////////////////////////////////////////////////////////////////////////////////////////
300

    
301
  public int getBasicAngle()
302
    {
303
    return 3;
304
    }
305

    
306
///////////////////////////////////////////////////////////////////////////////////////////////////
307

    
308
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
309
    {
310
    if( num==0 )
311
      {
312
      scramble[num][0] = rnd.nextInt(ROTATION_AXIS.length);
313
      }
314
    else
315
      {
316
      int newVector = rnd.nextInt(ROTATION_AXIS.length-1);
317
      scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
318
      }
319

    
320
    float rowFloat = rnd.nextFloat();
321

    
322
    for(int row=0; row<mRowChances.length; row++)
323
      {
324
      if( rowFloat<=mRowChances[row] )
325
        {
326
        scramble[num][1] = row;
327
        break;
328
        }
329
      }
330

    
331
    switch( rnd.nextInt(2) )
332
      {
333
      case 0: scramble[num][2] = -1; break;
334
      case 1: scramble[num][2] =  1; break;
335
      }
336
    }
337

    
338
///////////////////////////////////////////////////////////////////////////////////////////////////
339
// The Ivy is solved if and only if:
340
//
341
// 1) all 4 of its corner cubits are rotated with the same quat
342
// 2) all its face cubits are rotated with the same quat like the corner ones,
343
//    and optionally they also might be upside down.
344
//
345
// i.e.
346
// cubits [4] and [5] - might be extra QUAT[1]
347
// cubits [6] and [7] - might be extra QUAT[2]
348
// cubits [8] and [9] - might be extra QUAT[3]
349

    
350
  public boolean isSolved()
351
    {
352
    int q1,q = CUBITS[0].mQuatIndex;
353

    
354
    if( CUBITS[1].mQuatIndex == q &&
355
        CUBITS[2].mQuatIndex == q &&
356
        CUBITS[3].mQuatIndex == q  )
357
      {
358
      q1 = mulQuat(q,1);
359
      if( CUBITS[4].mQuatIndex != q && CUBITS[4].mQuatIndex != q1 ) return false;
360
      if( CUBITS[5].mQuatIndex != q && CUBITS[5].mQuatIndex != q1 ) return false;
361

    
362
      q1 = mulQuat(q,2);
363
      if( CUBITS[6].mQuatIndex != q && CUBITS[6].mQuatIndex != q1 ) return false;
364
      if( CUBITS[7].mQuatIndex != q && CUBITS[7].mQuatIndex != q1 ) return false;
365

    
366
      q1 = mulQuat(q,3);
367
      if( CUBITS[8].mQuatIndex != q && CUBITS[8].mQuatIndex != q1 ) return false;
368
      if( CUBITS[9].mQuatIndex != q && CUBITS[9].mQuatIndex != q1 ) return false;
369

    
370
      return true;
371
      }
372

    
373
    return false;
374
    }
375

    
376
///////////////////////////////////////////////////////////////////////////////////////////////////
377
// only needed for solvers - there are no Ivy solvers ATM)
378

    
379
  public String retObjectString()
380
    {
381
    return "";
382
    }
383

    
384
///////////////////////////////////////////////////////////////////////////////////////////////////
385

    
386
  public int getObjectName(int numLayers)
387
    {
388
    return R.string.ivy2;
389
    }
390

    
391
///////////////////////////////////////////////////////////////////////////////////////////////////
392

    
393
  public int getInventor(int numLayers)
394
    {
395
    return R.string.ivy2_inventor;
396
    }
397

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

    
400
  public int getComplexity(int numLayers)
401
    {
402
    return 1;
403
    }
404
}
(25-25/33)