Project

General

Profile

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

magiccube / src / main / java / org / distorted / patterns / RubikPattern.java @ a31d25de

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.patterns;
21

    
22
import org.distorted.magic.RubikPostRender;
23
import org.distorted.object.RubikObject;
24

    
25
import java.util.Vector;
26

    
27
///////////////////////////////////////////////////////////////////////////////////////////////////
28

    
29
public class RubikPattern
30
{
31
  private static final int DURATION_MILLIS = 1000;
32

    
33
  public static final int MIN_CUBE  = 2;
34
  public static final int MAX_CUBE  = 5;
35
  public static final int NUM_CUBES = MAX_CUBE-MIN_CUBE+1;
36

    
37
  private int[] numCategories   = new int[NUM_CUBES];
38
  private int[] currentCategory = new int[NUM_CUBES];
39
  private Vector<Category>[] mCategories;
40
  private static RubikPattern mThis;
41

    
42
///////////////////////////////////////////////////////////////////////////////////////////////////
43

    
44
  private static class Category
45
    {
46
    private String name;
47
    private int numPatterns;
48
    private Vector<Pattern> patterns;
49

    
50
  /////////////////////////////////////////////////////////////
51

    
52
    Category(String n)
53
      {
54
      name=n;
55
      numPatterns=0;
56
      patterns = new Vector<>();
57
      }
58

    
59
  /////////////////////////////////////////////////////////////
60

    
61
    void addPattern(Pattern p)
62
      {
63
      patterns.addElement(p);
64
      numPatterns++;
65
      }
66

    
67
  /////////////////////////////////////////////////////////////
68

    
69
    int getNumPatterns()
70
    {
71
    return numPatterns;
72
    }
73

    
74
  /////////////////////////////////////////////////////////////
75

    
76
    String getName()
77
    {
78
    return name;
79
    }
80

    
81
  /////////////////////////////////////////////////////////////
82

    
83
    String getPatternName(int pattern)
84
      {
85
      if( pattern>=0 && pattern<numPatterns )
86
        {
87
        Pattern p = patterns.elementAt(pattern);
88
        return  p!=null ? p.getName():"";
89
        }
90
      return "";
91
      }
92

    
93
  /////////////////////////////////////////////////////////////
94

    
95
    int getPatternCurMove(int pattern)
96
      {
97
      if( pattern>=0 && pattern<numPatterns )
98
        {
99
        Pattern p = patterns.elementAt(pattern);
100
        return  p!=null ? p.getCurMove():-1;
101
        }
102
      return -1;
103
      }
104

    
105
  /////////////////////////////////////////////////////////////
106

    
107
    int getPatternNumMove(int pattern)
108
      {
109
      if( pattern>=0 && pattern<numPatterns )
110
        {
111
        Pattern p = patterns.elementAt(pattern);
112
        return  p!=null ? p.getNumMove():-1;
113
        }
114
      return -1;
115
      }
116

    
117
  /////////////////////////////////////////////////////////////
118

    
119
    void makeMove(RubikPostRender post, int pattern)
120
      {
121
      if( pattern>=0 && pattern<numPatterns )
122
        {
123
        Pattern p = patterns.elementAt(pattern);
124
        if( p!=null ) p.makeMove(post);
125
        }
126
      }
127

    
128
  /////////////////////////////////////////////////////////////
129

    
130
    void backMove(RubikPostRender post, int pattern)
131
      {
132
      if( pattern>=0 && pattern<numPatterns )
133
        {
134
        Pattern p = patterns.elementAt(pattern);
135
        if( p!=null ) p.backMove(post);
136
        }
137
      }
138

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

    
141
    int[][] getMoves(int pattern)
142
      {
143
      if( pattern>=0 && pattern<numPatterns )
144
        {
145
        Pattern p = patterns.elementAt(pattern);
146
        if( p!=null ) return p.getMoves();
147
        }
148

    
149
      return null;
150
      }
151
    }
152

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

    
155
  private static class Pattern implements RubikPostRender.ActionFinishedListener
156
    {
157
    private String name;
158
    private int[][] moves;
159
    private int curMove;
160
    private int numMove;
161

    
162
    private boolean mCanRotate;
163
    private RubikObject mObject;
164

    
165
  /////////////////////////////////////////////////////////////
166

    
167
    Pattern(String n, String m)
168
      {
169
      name=n;
170
      moves= movesParser(m);
171
      curMove=numMove;
172
      mCanRotate = true;
173
      }
174

    
175
  /////////////////////////////////////////////////////////////
176

    
177
    private int[][] movesParser(String moves)
178
      {
179
      numMove = moves.length()/4;
180

    
181
      int digit0, digit1, digit2;
182
      int[][] result = new int[numMove][3];
183

    
184
      for(int i=0; i<numMove; i++)
185
        {
186
        digit0 = moves.charAt(4*i+1)-'0';
187
        digit1 = moves.charAt(4*i+2)-'0';
188
        digit2 = moves.charAt(4*i+3)-'0';
189

    
190
        result[i][0] = (10*digit0+digit1)/32;
191
        result[i][1] = (10*digit0+digit1)%32;
192
        result[i][2] = 2-digit2;
193
        }
194

    
195
      return result;
196
      }
197

    
198
  /////////////////////////////////////////////////////////////
199

    
200
    String getName()
201
      {
202
      return name;
203
      }
204

    
205
  /////////////////////////////////////////////////////////////
206

    
207
    int getNumMove()
208
      {
209
      return numMove;
210
      }
211

    
212
  /////////////////////////////////////////////////////////////
213

    
214
    int getCurMove()
215
      {
216
      return curMove;
217
      }
218

    
219
  /////////////////////////////////////////////////////////////
220

    
221
    void makeMove(RubikPostRender post)
222
      {
223
      curMove++;
224
      RubikObject object = post.getObject();
225

    
226
      if( curMove>numMove )
227
        {
228
        curMove= 0;
229
        object.initializeObject(null);
230
        }
231
      else
232
        {
233
        if( mCanRotate )
234
          {
235
          mCanRotate = false;
236
          mObject = object;
237

    
238
          int axis     =moves[curMove-1][0];
239
		      int rowBitmap=moves[curMove-1][1];
240
		      int bareAngle=moves[curMove-1][2];
241
          int angle    = bareAngle*(360/object.getBasicAngle());
242
          int numRot   = Math.abs(bareAngle);
243

    
244
          post.addRotation(this, axis, rowBitmap, angle, numRot*DURATION_MILLIS);
245
          }
246
        else
247
          {
248
          android.util.Log.e("pattern", "failed to make Move!");
249

    
250
          curMove--;
251
          }
252
        }
253
      }
254

    
255
  /////////////////////////////////////////////////////////////
256

    
257
    void backMove(RubikPostRender post)
258
      {
259
      curMove--;
260
      RubikObject object = post.getObject();
261

    
262
      if( curMove<0 )
263
        {
264
        curMove=numMove;
265
        object.initializeObject(moves);
266
        }
267
      else
268
        {
269
        if( mCanRotate )
270
          {
271
          mCanRotate = false;
272
          mObject = object;
273

    
274
          int axis     =moves[curMove][0];
275
		      int rowBitmap=moves[curMove][1];
276
		      int bareAngle=moves[curMove][2];
277
          int angle    = bareAngle*(360/object.getBasicAngle());
278
          int numRot   = Math.abs(bareAngle);
279

    
280
          post.addRotation(this, axis, rowBitmap, -angle, numRot*DURATION_MILLIS);
281
          }
282
        else
283
          {
284
          android.util.Log.e("pattern", "failed to back Move!");
285
          curMove++;
286
          }
287
        }
288
      }
289

    
290
  /////////////////////////////////////////////////////////////
291

    
292
    int[][] getMoves()
293
      {
294
      return moves;
295
      }
296

    
297
  /////////////////////////////////////////////////////////////
298

    
299
    public void onActionFinished(final long effectID)
300
      {
301
      mObject.removeRotationNow();
302
      mCanRotate = true;
303
      }
304
    }
305

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

    
308
  private RubikPattern()
309
    {
310
    mCategories = new Vector[NUM_CUBES];
311

    
312
    initializeCategories(0, RubikPatternData2.patterns);
313
    initializeCategories(1, RubikPatternData3.patterns);
314
    initializeCategories(2, RubikPatternData4.patterns);
315
    initializeCategories(3, RubikPatternData5.patterns);
316
    }
317

    
318
///////////////////////////////////////////////////////////////////////////////////////////////////
319

    
320
  private void initializeCategories(int num, String[] pat)
321
    {
322
    int colon;
323
    mCategories[num] = new Vector<>();
324
    Category cat=null;
325
    String name, pattern;
326
    Pattern patt;
327

    
328
    numCategories[num]=0;
329

    
330
    for(String p: pat)
331
      {
332
      colon = p.indexOf(':');
333

    
334
      if( colon==-1 )
335
        {
336
        cat = new Category(p);
337
        mCategories[num].addElement(cat);
338
        numCategories[num]++;
339
        }
340
      else
341
        {
342
        pattern = p.substring(colon+1);
343
        name    = p.substring(0,colon);
344
        patt = new Pattern(name,pattern);
345
        cat.addPattern(patt);
346
        }
347
      }
348
    }
349

    
350
///////////////////////////////////////////////////////////////////////////////////////////////////
351
// PUBLIC API
352
///////////////////////////////////////////////////////////////////////////////////////////////////
353

    
354
  public static RubikPattern getInstance()
355
    {
356
    if( mThis==null )
357
      {
358
      mThis = new RubikPattern();
359
      }
360

    
361
    return mThis;
362
    }
363

    
364
///////////////////////////////////////////////////////////////////////////////////////////////////
365

    
366
  public int getNumCategories(int size)
367
    {
368
    return size>=0 && size<NUM_CUBES ? numCategories[size] : 0;
369
    }
370

    
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372

    
373
  public String getCategoryName(int size,int num)
374
    {
375
    if( size>=0 && size<NUM_CUBES && num>=0 && num< numCategories[size] )
376
      {
377
      Category c = mCategories[size].elementAt(num);
378
      return c!=null ? c.getName() : null;
379
      }
380

    
381
    return null;
382
    }
383

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

    
386
  public void rememberCategory(int size,int num)
387
    {
388
    if( size>=0 && size<NUM_CUBES )
389
      {
390
      currentCategory[size] = num;
391
      }
392
    }
393

    
394
///////////////////////////////////////////////////////////////////////////////////////////////////
395

    
396
  public int recallCategory(int size)
397
    {
398
    return size>=0 && size<NUM_CUBES ? currentCategory[size] : 0;
399
    }
400

    
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402

    
403
  public String getPatternName(int size, int cat, int pat)
404
    {
405
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
406
      {
407
      Category c = mCategories[size].elementAt(cat);
408
      return c!=null ? c.getPatternName(pat) : null;
409
      }
410

    
411
    return null;
412
    }
413

    
414
///////////////////////////////////////////////////////////////////////////////////////////////////
415

    
416
  public int getNumPatterns(int size, int num )
417
    {
418
    if( size>=0 && size<NUM_CUBES && num>=0 && num< numCategories[size] )
419
      {
420
      Category c = mCategories[size].elementAt(num);
421
      return c!=null ? c.getNumPatterns() : 0;
422
      }
423

    
424
    return 0;
425
    }
426

    
427
///////////////////////////////////////////////////////////////////////////////////////////////////
428

    
429
  public int getCurMove(int size, int cat, int pat)
430
    {
431
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
432
      {
433
      Category c = mCategories[size].elementAt(cat);
434
      return c!=null ? c.getPatternCurMove(pat):0;
435
      }
436

    
437
    return 0;
438
    }
439

    
440
///////////////////////////////////////////////////////////////////////////////////////////////////
441

    
442
  public int getNumMoves(int size, int cat, int pat)
443
    {
444
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
445
      {
446
      Category c = mCategories[size].elementAt(cat);
447
      return c!=null ? c.getPatternNumMove(pat):0;
448
      }
449

    
450
    return 0;
451
    }
452

    
453
///////////////////////////////////////////////////////////////////////////////////////////////////
454

    
455
  public void makeMove(RubikPostRender post, int size, int cat, int pat)
456
    {
457
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
458
      {
459
      Category c = mCategories[size].elementAt(cat);
460
      if( c!=null ) c.makeMove(post,pat);
461
      }
462
    }
463

    
464
///////////////////////////////////////////////////////////////////////////////////////////////////
465

    
466
  public void backMove(RubikPostRender post, int size, int cat, int pat)
467
    {
468
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
469
      {
470
      Category c = mCategories[size].elementAt(cat);
471
      if( c!=null ) c.backMove(post,pat);
472
      }
473
    }
474

    
475
///////////////////////////////////////////////////////////////////////////////////////////////////
476

    
477
  public int[][] getMoves(int size, int cat, int pat)
478
    {
479
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
480
      {
481
      Category c = mCategories[size].elementAt(cat);
482
      if( c!=null ) return c.getMoves(pat);
483
      }
484

    
485
    return null;
486
    }
487
}
(1-1/5)