Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyIvy.java @ 7d8cc029

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

    
106
  float getScreenRatio()
107
    {
108
    return 1.0f;
109
    }
110

    
111
///////////////////////////////////////////////////////////////////////////////////////////////////
112

    
113
  Static4D[] getQuats()
114
    {
115
    return QUATS;
116
    }
117

    
118
///////////////////////////////////////////////////////////////////////////////////////////////////
119

    
120
  int getNumFaces()
121
    {
122
    return FACE_COLORS.length;
123
    }
124

    
125
///////////////////////////////////////////////////////////////////////////////////////////////////
126

    
127
  boolean shouldResetTextureMaps()
128
    {
129
    return false;
130
    }
131

    
132
///////////////////////////////////////////////////////////////////////////////////////////////////
133

    
134
  int getNumStickerTypes(int numLayers)
135
    {
136
    return 2;
137
    }
138

    
139
///////////////////////////////////////////////////////////////////////////////////////////////////
140

    
141
  float[] getCuts(int numLayers)
142
    {
143
    float[] cuts = new float[1];
144
    cuts[0] = 0.0f;
145

    
146
    return cuts;
147
    }
148

    
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150

    
151
  int getNumCubitFaces()
152
    {
153
    return FACES_PER_CUBIT;
154
    }
155

    
156
///////////////////////////////////////////////////////////////////////////////////////////////////
157

    
158
  float[][] getCubitPositions(int numLayers)
159
    {
160
    final float DIST_CORNER = (numLayers-1)*0.50f;
161
    final float DIST_CENTER = (numLayers-1)*0.50f;
162

    
163
    final float[][] CENTERS = new float[10][];
164

    
165
    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
166
    CENTERS[1] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
167
    CENTERS[2] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
168
    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
169
    CENTERS[4] = new float[] { DIST_CENTER,           0,           0 };
170
    CENTERS[5] = new float[] {-DIST_CENTER,           0,           0 };
171
    CENTERS[6] = new float[] {           0, DIST_CENTER,           0 };
172
    CENTERS[7] = new float[] {           0,-DIST_CENTER,           0 };
173
    CENTERS[8] = new float[] {           0,           0, DIST_CENTER };
174
    CENTERS[9] = new float[] {           0,           0,-DIST_CENTER };
175

    
176
    return CENTERS;
177
    }
178

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

    
181
  private int getQuat(int cubit)
182
    {
183
    switch(cubit)
184
      {
185
      case  0: return 0;
186
      case  1: return 2;
187
      case  2: return 3;
188
      case  3: return 1;
189

    
190
      case  4: return 8;
191
      case  5: return 11;
192
      case  6: return 10;
193
      case  7: return 9;
194
      case  8: return 0;
195
      case  9: return 2;
196
      }
197

    
198
    return 0;
199
    }
200

    
201
///////////////////////////////////////////////////////////////////////////////////////////////////
202

    
203
  MeshBase createCubitMesh(int cubit, int numLayers)
204
    {
205
    MeshBase mesh;
206

    
207
    if( cubit<4 )
208
      {
209
      if( mCornerMesh==null ) mCornerMesh = FactoryCubit.getInstance().createIvyCornerMesh();
210
      mesh = mCornerMesh.copy(true);
211
      }
212
    else
213
      {
214
      if( mFaceMesh==null ) mFaceMesh = FactoryCubit.getInstance().createIvyFaceMesh();
215
      mesh = mFaceMesh.copy(true);
216
      }
217

    
218
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( QUATS[getQuat(cubit)], new Static3D(0,0,0) );
219
    mesh.apply(quat,0xffffffff,0);
220

    
221
    return mesh;
222
    }
223

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

    
226
  int getFaceColor(int cubit, int cubitface, int numLayers)
227
    {
228
    return mFaceMap[cubit][cubitface];
229
    }
230

    
231
///////////////////////////////////////////////////////////////////////////////////////////////////
232

    
233
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
234
    {
235
    int COLORS = FACE_COLORS.length;
236
    FactorySticker factory = FactorySticker.getInstance();
237
    float S = 0.08f;
238
    float R = 0.12f;
239

    
240
    if( face<COLORS )
241
      {
242
      factory.drawIvyCornerSticker(canvas, paint, left, top, FACE_COLORS[face%COLORS], S, R);
243
      }
244
    else
245
      {
246
      factory.drawIvyCenterSticker(canvas, paint, left, top, FACE_COLORS[face%COLORS], S, R);
247
      }
248
    }
249

    
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251

    
252
  float returnMultiplier()
253
    {
254
    return 2.0f;
255
    }
256

    
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258

    
259
  float[] getRowChances(int numLayers)
260
    {
261
    float[] chances = new float[2];
262
    chances[0] = 0.5f;
263
    chances[1] = 1.0f;
264

    
265
    return chances;
266
    }
267

    
268
///////////////////////////////////////////////////////////////////////////////////////////////////
269
// PUBLIC API
270

    
271
  public Static3D[] getRotationAxis()
272
    {
273
    return ROT_AXIS;
274
    }
275

    
276
///////////////////////////////////////////////////////////////////////////////////////////////////
277

    
278
  public int getBasicAngle()
279
    {
280
    return 3;
281
    }
282

    
283
///////////////////////////////////////////////////////////////////////////////////////////////////
284

    
285
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
286
    {
287
    if( num==0 )
288
      {
289
      scramble[num][0] = rnd.nextInt(ROTATION_AXIS.length);
290
      }
291
    else
292
      {
293
      int newVector = rnd.nextInt(ROTATION_AXIS.length-1);
294
      scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
295
      }
296

    
297
    float rowFloat = rnd.nextFloat();
298

    
299
    for(int row=0; row<mRowChances.length; row++)
300
      {
301
      if( rowFloat<=mRowChances[row] )
302
        {
303
        scramble[num][1] = row;
304
        break;
305
        }
306
      }
307

    
308
    switch( rnd.nextInt(2) )
309
      {
310
      case 0: scramble[num][2] = -1; break;
311
      case 1: scramble[num][2] =  1; break;
312
      }
313
    }
314

    
315
///////////////////////////////////////////////////////////////////////////////////////////////////
316
// The Ivy is solved if and only if:
317
//
318
// 1) all 4 of its corner cubits are rotated with the same quat
319
// 2) all its face cubits are rotated with the same quat like the corner ones,
320
//    and optionally they also might be upside down.
321
//
322
// i.e.
323
// cubits [4] and [5] - might be extra QUAT[1]
324
// cubits [6] and [7] - might be extra QUAT[2]
325
// cubits [8] and [9] - might be extra QUAT[3]
326

    
327
  public boolean isSolved()
328
    {
329
    int q1,q = CUBITS[0].mQuatIndex;
330

    
331
    if( CUBITS[1].mQuatIndex == q &&
332
        CUBITS[2].mQuatIndex == q &&
333
        CUBITS[3].mQuatIndex == q  )
334
      {
335
      q1 = mulQuat(q,1);
336
      if( CUBITS[4].mQuatIndex != q && CUBITS[4].mQuatIndex != q1 ) return false;
337
      if( CUBITS[5].mQuatIndex != q && CUBITS[5].mQuatIndex != q1 ) return false;
338

    
339
      q1 = mulQuat(q,2);
340
      if( CUBITS[6].mQuatIndex != q && CUBITS[6].mQuatIndex != q1 ) return false;
341
      if( CUBITS[7].mQuatIndex != q && CUBITS[7].mQuatIndex != q1 ) return false;
342

    
343
      q1 = mulQuat(q,3);
344
      if( CUBITS[8].mQuatIndex != q && CUBITS[8].mQuatIndex != q1 ) return false;
345
      if( CUBITS[9].mQuatIndex != q && CUBITS[9].mQuatIndex != q1 ) return false;
346

    
347
      return true;
348
      }
349

    
350
    return false;
351
    }
352

    
353
///////////////////////////////////////////////////////////////////////////////////////////////////
354
// only needed for solvers - there are no Ivy solvers ATM)
355

    
356
  public String retObjectString()
357
    {
358
    return "";
359
    }
360

    
361
///////////////////////////////////////////////////////////////////////////////////////////////////
362

    
363
  public int getObjectName(int numLayers)
364
    {
365
    return R.string.ivy2;
366
    }
367

    
368
///////////////////////////////////////////////////////////////////////////////////////////////////
369

    
370
  public int getInventor(int numLayers)
371
    {
372
    return R.string.ivy2_inventor;
373
    }
374

    
375
///////////////////////////////////////////////////////////////////////////////////////////////////
376

    
377
  public int getComplexity(int numLayers)
378
    {
379
    return 1;
380
    }
381
}
(25-25/33)