Project

General

Profile

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

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

1 49cd8581 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 749ef882 Leszek Koltunski
import org.distorted.helpers.FactoryCubit;
27
import org.distorted.helpers.FactorySticker;
28 49cd8581 Leszek Koltunski
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 6fd4a72c Leszek Koltunski
import org.distorted.main.R;
36 49cd8581 Leszek Koltunski
37
import java.util.Random;
38
39
///////////////////////////////////////////////////////////////////////////////////////////////////
40
41
public class TwistyIvy extends TwistyObject
42
{
43 18a5f95f Leszek Koltunski
  private static final int FACES_PER_CUBIT =6;
44 49cd8581 Leszek Koltunski
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 323b217c Leszek Koltunski
           COLOR_RED   , COLOR_ORANGE
59 49cd8581 Leszek Koltunski
         };
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 18a5f95f Leszek Koltunski
  private static final int[][] mFaceMap =
80 49cd8581 Leszek Koltunski
         {
81 18a5f95f Leszek Koltunski
           {  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 49cd8581 Leszek Koltunski
         };
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 db875721 Leszek Koltunski
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.IVY, res, scrWidth);
102 49cd8581 Leszek Koltunski
    }
103
104 b1f2ccf5 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 49cd8581 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 a64e07d0 Leszek Koltunski
  int getNumStickerTypes(int numLayers)
158 49cd8581 Leszek Koltunski
    {
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 e6cf7283 Leszek Koltunski
  float[][] getCubitPositions(int numLayers)
182 49cd8581 Leszek Koltunski
    {
183
    final float DIST_CORNER = (numLayers-1)*0.50f;
184
    final float DIST_CENTER = (numLayers-1)*0.50f;
185
186 e6cf7283 Leszek Koltunski
    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 49cd8581 Leszek Koltunski
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 a64e07d0 Leszek Koltunski
  MeshBase createCubitMesh(int cubit, int numLayers)
227 49cd8581 Leszek Koltunski
    {
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 18a5f95f Leszek Koltunski
    return mFaceMap[cubit][cubitface];
252 49cd8581 Leszek Koltunski
    }
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 9e5b990e Leszek Koltunski
    float S = 0.08f;
261 886d1ebb Leszek Koltunski
    float R = 0.12f;
262 49cd8581 Leszek Koltunski
263
    if( face<COLORS )
264
      {
265 9e5b990e Leszek Koltunski
      factory.drawIvyCornerSticker(canvas, paint, left, top, FACE_COLORS[face%COLORS], S, R);
266 49cd8581 Leszek Koltunski
      }
267
    else
268
      {
269 9e5b990e Leszek Koltunski
      factory.drawIvyCenterSticker(canvas, paint, left, top, FACE_COLORS[face%COLORS], S, R);
270 49cd8581 Leszek Koltunski
      }
271
    }
272
273
///////////////////////////////////////////////////////////////////////////////////////////////////
274
275
  float returnMultiplier()
276
    {
277
    return 2.0f;
278
    }
279
280
///////////////////////////////////////////////////////////////////////////////////////////////////
281
282 a64e07d0 Leszek Koltunski
  float[] getRowChances(int numLayers)
283 49cd8581 Leszek Koltunski
    {
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 5043d5d0 Leszek Koltunski
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
309 49cd8581 Leszek Koltunski
    {
310 5043d5d0 Leszek Koltunski
    if( num==0 )
311 49cd8581 Leszek Koltunski
      {
312 5043d5d0 Leszek Koltunski
      scramble[num][0] = rnd.nextInt(ROTATION_AXIS.length);
313 49cd8581 Leszek Koltunski
      }
314
    else
315
      {
316 bbc6471c Leszek Koltunski
      int newVector = rnd.nextInt(ROTATION_AXIS.length-1);
317 5043d5d0 Leszek Koltunski
      scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
318 49cd8581 Leszek Koltunski
      }
319
320
    float rowFloat = rnd.nextFloat();
321
322
    for(int row=0; row<mRowChances.length; row++)
323
      {
324 bbc6471c Leszek Koltunski
      if( rowFloat<=mRowChances[row] )
325
        {
326 5043d5d0 Leszek Koltunski
        scramble[num][1] = row;
327 bbc6471c Leszek Koltunski
        break;
328
        }
329 49cd8581 Leszek Koltunski
      }
330
331 5043d5d0 Leszek Koltunski
    switch( rnd.nextInt(2) )
332
      {
333
      case 0: scramble[num][2] = -1; break;
334
      case 1: scramble[num][2] =  1; break;
335
      }
336 49cd8581 Leszek Koltunski
    }
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 6fd4a72c Leszek Koltunski
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 49cd8581 Leszek Koltunski
}