Project

General

Profile

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

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

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 int[] currentScrollPos= new int[NUM_CUBES];
40

    
41
  private Vector<Category>[] mCategories;
42
  private static RubikPattern mThis;
43

    
44
///////////////////////////////////////////////////////////////////////////////////////////////////
45

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

    
52
  /////////////////////////////////////////////////////////////
53

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

    
61
  /////////////////////////////////////////////////////////////
62

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

    
69
  /////////////////////////////////////////////////////////////
70

    
71
    int getNumPatterns()
72
    {
73
    return numPatterns;
74
    }
75

    
76
  /////////////////////////////////////////////////////////////
77

    
78
    String getName()
79
    {
80
    return name;
81
    }
82

    
83
  /////////////////////////////////////////////////////////////
84

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

    
95
  /////////////////////////////////////////////////////////////
96

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

    
107
  /////////////////////////////////////////////////////////////
108

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

    
119
  /////////////////////////////////////////////////////////////
120

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

    
130
  /////////////////////////////////////////////////////////////
131

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

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

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

    
151
      return null;
152
      }
153
    }
154

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

    
157
  private static class Pattern implements RubikPostRender.ActionFinishedListener
158
    {
159
    private String nameStr, moveStr;
160
    private int[][] moves;
161
    private int curMove;
162
    private int numMove;
163
    private boolean mCanRotate;
164
    private boolean mInitialized;
165

    
166
  /////////////////////////////////////////////////////////////
167

    
168
    Pattern(String n, String m)
169
      {
170
      nameStr = n;
171
      moveStr = m;
172
      mCanRotate   = true;
173
      mInitialized = false;
174
      }
175

    
176
  /////////////////////////////////////////////////////////////
177

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

    
183
      int digit0, digit1, digit2;
184
      int[][] result = new int[numMove][3];
185

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

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

    
197
      return result;
198
      }
199

    
200
  /////////////////////////////////////////////////////////////
201

    
202
    String getName()
203
      {
204
      return nameStr;
205
      }
206

    
207
  /////////////////////////////////////////////////////////////
208

    
209
    int getNumMove()
210
      {
211
      if( !mInitialized )
212
        {
213
        mInitialized = true;
214
        moves = movesParser(moveStr);
215
        moveStr = null;
216
        }
217

    
218
      return numMove;
219
      }
220

    
221
  /////////////////////////////////////////////////////////////
222

    
223
    int getCurMove()
224
      {
225
      if( !mInitialized )
226
        {
227
        mInitialized = true;
228
        moves = movesParser(moveStr);
229
        moveStr = null;
230
        }
231

    
232
      return curMove;
233
      }
234

    
235
  /////////////////////////////////////////////////////////////
236

    
237
    void makeMove(RubikPostRender post)
238
      {
239
      if( !mInitialized )
240
        {
241
        mInitialized = true;
242
        moves = movesParser(moveStr);
243
        moveStr = null;
244
        }
245

    
246
      curMove++;
247
      RubikObject object = post.getObject();
248

    
249
      if( mCanRotate )
250
        {
251
        if( curMove>numMove )
252
          {
253
          curMove= 0;
254
          post.initializeObject(null);
255
          }
256
        else
257
          {
258
          int axis     =moves[curMove-1][0];
259
		      int rowBitmap=moves[curMove-1][1];
260
		      int bareAngle=moves[curMove-1][2];
261
          int angle    = bareAngle*(360/object.getBasicAngle());
262
          int numRot   = Math.abs(bareAngle);
263

    
264
          if( angle!=0 )
265
            {
266
            mCanRotate = false;
267
            post.addRotation(this, axis, rowBitmap, angle, numRot*DURATION_MILLIS);
268
            }
269
          else
270
            {
271
            android.util.Log.e("pattern", "error: pattern "+nameStr+" move "+(curMove-1)+" angle 0");
272
            }
273
          }
274
        }
275
      else
276
        {
277
        android.util.Log.e("pattern", "failed to make Move!");
278
        curMove--;
279
        }
280
      }
281

    
282
  /////////////////////////////////////////////////////////////
283

    
284
    void backMove(RubikPostRender post)
285
      {
286
      if( !mInitialized )
287
        {
288
        mInitialized = true;
289
        moves = movesParser(moveStr);
290
        moveStr = null;
291
        }
292

    
293
      curMove--;
294
      RubikObject object = post.getObject();
295

    
296
      if( mCanRotate )
297
        {
298
        if( curMove<0 )
299
          {
300
          curMove=numMove;
301
          post.initializeObject(moves);
302
          }
303
        else
304
          {
305
          int axis     =moves[curMove][0];
306
		      int rowBitmap=moves[curMove][1];
307
		      int bareAngle=moves[curMove][2];
308
          int angle    = bareAngle*(360/object.getBasicAngle());
309
          int numRot   = Math.abs(bareAngle);
310

    
311
          if( angle!=0 )
312
            {
313
            mCanRotate = false;
314
            post.addRotation(this, axis, rowBitmap, -angle, numRot*DURATION_MILLIS);
315
            }
316
          else
317
            {
318
            android.util.Log.e("pattern", "error: pattern "+nameStr+" move "+curMove+" angle 0");
319
            }
320
          }
321
        }
322
      else
323
        {
324
        android.util.Log.e("pattern", "failed to back Move!");
325
        curMove++;
326
        }
327
      }
328

    
329
  /////////////////////////////////////////////////////////////
330

    
331
    int[][] reInitialize()
332
      {
333
      if( !mInitialized )
334
        {
335
        mInitialized = true;
336
        moves = movesParser(moveStr);
337
        moveStr = null;
338
        }
339

    
340
      mCanRotate = true;
341
      curMove = numMove;
342
      return moves;
343
      }
344

    
345
  /////////////////////////////////////////////////////////////
346

    
347
    public void onActionFinished(final long effectID)
348
      {
349
      mCanRotate = true;
350
      }
351
    }
352

    
353
///////////////////////////////////////////////////////////////////////////////////////////////////
354

    
355
  private RubikPattern()
356
    {
357
    mCategories = new Vector[NUM_CUBES];
358

    
359
    initializeCategories(0, RubikPatternData2.patterns);
360
    initializeCategories(1, RubikPatternData3.patterns);
361
    initializeCategories(2, RubikPatternData4.patterns);
362
    initializeCategories(3, RubikPatternData5.patterns);
363
    }
364

    
365
///////////////////////////////////////////////////////////////////////////////////////////////////
366

    
367
  private void initializeCategories(int num, String[] pat)
368
    {
369
    int colon;
370
    mCategories[num] = new Vector<>();
371
    Category cat=null;
372
    String name, pattern;
373
    Pattern patt;
374

    
375
    numCategories[num]=0;
376

    
377
    for(String p: pat)
378
      {
379
      colon = p.indexOf(':');
380

    
381
      if( colon==-1 )
382
        {
383
        cat = new Category(p);
384
        mCategories[num].addElement(cat);
385
        numCategories[num]++;
386
        }
387
      else
388
        {
389
        pattern = p.substring(colon+1);
390
        name    = p.substring(0,colon);
391
        patt = new Pattern(name,pattern);
392
        cat.addPattern(patt);
393
        }
394
      }
395
    }
396

    
397
///////////////////////////////////////////////////////////////////////////////////////////////////
398
// PUBLIC API
399
///////////////////////////////////////////////////////////////////////////////////////////////////
400

    
401
  public static RubikPattern getInstance()
402
    {
403
    if( mThis==null )
404
      {
405
      mThis = new RubikPattern();
406
      }
407

    
408
    return mThis;
409
    }
410

    
411
///////////////////////////////////////////////////////////////////////////////////////////////////
412

    
413
  public int getNumCategories(int size)
414
    {
415
    return size>=0 && size<NUM_CUBES ? numCategories[size] : 0;
416
    }
417

    
418
///////////////////////////////////////////////////////////////////////////////////////////////////
419

    
420
  public String getCategoryName(int size,int num)
421
    {
422
    if( size>=0 && size<NUM_CUBES && num>=0 && num< numCategories[size] )
423
      {
424
      Category c = mCategories[size].elementAt(num);
425
      return c!=null ? c.getName() : null;
426
      }
427

    
428
    return null;
429
    }
430

    
431
///////////////////////////////////////////////////////////////////////////////////////////////////
432

    
433
  public void rememberState(int size,int num, int scrollPos)
434
    {
435
    if( size>=0 && size<NUM_CUBES )
436
      {
437
      currentCategory[size] = num;
438
      currentScrollPos[size]= scrollPos;
439
      }
440
    }
441

    
442
///////////////////////////////////////////////////////////////////////////////////////////////////
443

    
444
  public int recallCategory(int size)
445
    {
446
    return size>=0 && size<NUM_CUBES ? currentCategory[size] : 0;
447
    }
448

    
449
///////////////////////////////////////////////////////////////////////////////////////////////////
450

    
451
  public int recallScrollPos(int size)
452
    {
453
    return size>=0 && size<NUM_CUBES ? currentScrollPos[size] : 0;
454
    }
455

    
456
///////////////////////////////////////////////////////////////////////////////////////////////////
457

    
458
  public String getPatternName(int size, int cat, int pat)
459
    {
460
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
461
      {
462
      Category c = mCategories[size].elementAt(cat);
463
      return c!=null ? c.getPatternName(pat) : null;
464
      }
465

    
466
    return null;
467
    }
468

    
469
///////////////////////////////////////////////////////////////////////////////////////////////////
470

    
471
  public int getNumPatterns(int size, int num )
472
    {
473
    if( size>=0 && size<NUM_CUBES && num>=0 && num< numCategories[size] )
474
      {
475
      Category c = mCategories[size].elementAt(num);
476
      return c!=null ? c.getNumPatterns() : 0;
477
      }
478

    
479
    return 0;
480
    }
481

    
482
///////////////////////////////////////////////////////////////////////////////////////////////////
483

    
484
  public int getCurMove(int size, int cat, int pat)
485
    {
486
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
487
      {
488
      Category c = mCategories[size].elementAt(cat);
489
      return c!=null ? c.getPatternCurMove(pat):0;
490
      }
491

    
492
    return 0;
493
    }
494

    
495
///////////////////////////////////////////////////////////////////////////////////////////////////
496

    
497
  public int getNumMoves(int size, int cat, int pat)
498
    {
499
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
500
      {
501
      Category c = mCategories[size].elementAt(cat);
502
      return c!=null ? c.getPatternNumMove(pat):0;
503
      }
504

    
505
    return 0;
506
    }
507

    
508
///////////////////////////////////////////////////////////////////////////////////////////////////
509

    
510
  public void makeMove(RubikPostRender post, int size, int cat, int pat)
511
    {
512
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
513
      {
514
      Category c = mCategories[size].elementAt(cat);
515
      if( c!=null ) c.makeMove(post,pat);
516
      }
517
    }
518

    
519
///////////////////////////////////////////////////////////////////////////////////////////////////
520

    
521
  public void backMove(RubikPostRender post, int size, int cat, int pat)
522
    {
523
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
524
      {
525
      Category c = mCategories[size].elementAt(cat);
526
      if( c!=null ) c.backMove(post,pat);
527
      }
528
    }
529

    
530
///////////////////////////////////////////////////////////////////////////////////////////////////
531

    
532
  public int[][] reInitialize(int size, int cat, int pat)
533
    {
534
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
535
      {
536
      Category c = mCategories[size].elementAt(cat);
537
      if( c!=null ) return c.reInitialize(pat);
538
      }
539

    
540
    return null;
541
    }
542
}
(1-1/5)