Project

General

Profile

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

magiccube / src / main / java / org / distorted / patterns / RubikPattern.java @ 48145a5b

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.ArrayList;
26
import java.util.List;
27

    
28
///////////////////////////////////////////////////////////////////////////////////////////////////
29

    
30
public class RubikPattern
31
{
32
  private static final int DURATION_MILLIS = 800;
33

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

    
38
  private int[] numCategories   = new int[NUM_CUBES];
39
  private int[] currentCategory = new int[NUM_CUBES];
40
  private int[] currentScrollPos= new int[NUM_CUBES];
41

    
42
  private List<List<Category>> mCategories;
43
  private static RubikPattern mThis;
44

    
45
///////////////////////////////////////////////////////////////////////////////////////////////////
46

    
47
  private static class Category
48
    {
49
    private String[] mLines;
50
    private int numPatterns;
51
    private ArrayList<Pattern> mPatterns;
52
    private boolean mInitialized;
53

    
54
  /////////////////////////////////////////////////////////////
55

    
56
    Category(String[] lines)
57
      {
58
      mLines=lines;
59
      numPatterns=lines.length-1;
60
      mPatterns = new ArrayList<>();
61
      mInitialized = false;
62
      }
63

    
64
  /////////////////////////////////////////////////////////////
65

    
66
    void initialize()
67
      {
68
      int colon;
69
      String moves, name;
70
      Pattern pattern;
71

    
72
      for(int i=0; i<numPatterns; i++)
73
        {
74
        colon = mLines[i+1].indexOf(":");
75

    
76
        if( colon!=-1 )
77
          {
78
          moves   = mLines[i+1].substring(colon+1);
79
          name    = mLines[i+1].substring(0,colon);
80
          pattern = new Pattern(name,moves);
81

    
82
          mPatterns.add(pattern);
83
          }
84
        else
85
          {
86
          numPatterns--;
87
          }
88
        }
89

    
90
      mInitialized = true;
91
      }
92

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

    
95
    int getNumPatterns()
96
      {
97
      return numPatterns;
98
      }
99

    
100
  /////////////////////////////////////////////////////////////
101

    
102
    String getName()
103
      {
104
      return mLines[0];
105
      }
106

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

    
109
    String getPatternName(int pattern)
110
      {
111
      if( !mInitialized ) initialize();
112

    
113
      if( pattern>=0 && pattern<numPatterns )
114
        {
115
        Pattern p = mPatterns.get(pattern);
116
        return  p!=null ? p.getName():"";
117
        }
118

    
119
      return "";
120
      }
121

    
122
  /////////////////////////////////////////////////////////////
123

    
124
    int getPatternCurMove(int pattern)
125
      {
126
      if( !mInitialized ) initialize();
127

    
128
      if( pattern>=0 && pattern<numPatterns )
129
        {
130
        Pattern p = mPatterns.get(pattern);
131
        return  p!=null ? p.getCurMove():-1;
132
        }
133

    
134
      return -1;
135
      }
136

    
137
  /////////////////////////////////////////////////////////////
138

    
139
    int getPatternNumMove(int pattern)
140
      {
141
      if( !mInitialized ) initialize();
142

    
143
      if( pattern>=0 && pattern<numPatterns )
144
        {
145
        Pattern p = mPatterns.get(pattern);
146
        return  p!=null ? p.getNumMove():-1;
147
        }
148

    
149
      return -1;
150
      }
151

    
152
  /////////////////////////////////////////////////////////////
153

    
154
    void makeMove(RubikPostRender post, int pattern)
155
      {
156
      if( !mInitialized ) initialize();
157

    
158
      if( pattern>=0 && pattern<numPatterns )
159
        {
160
        Pattern p = mPatterns.get(pattern);
161
        if( p!=null ) p.makeMove(post);
162
        }
163
      }
164

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

    
167
    void backMove(RubikPostRender post, int pattern)
168
      {
169
      if( !mInitialized ) initialize();
170

    
171
      if( pattern>=0 && pattern<numPatterns )
172
        {
173
        Pattern p = mPatterns.get(pattern);
174
        if( p!=null ) p.backMove(post);
175
        }
176
      }
177

    
178
  /////////////////////////////////////////////////////////////
179

    
180
    int[][] reInitialize(int pattern)
181
      {
182
      if( !mInitialized ) initialize();
183

    
184
      if( pattern>=0 && pattern<numPatterns )
185
        {
186
        Pattern p = mPatterns.get(pattern);
187
        if( p!=null ) return p.reInitialize();
188
        }
189

    
190
      return null;
191
      }
192
    }
193

    
194
///////////////////////////////////////////////////////////////////////////////////////////////////
195

    
196
  private static class Pattern implements RubikPostRender.ActionFinishedListener
197
    {
198
    private String nameStr, moveStr;
199
    private int[][] moves;
200
    private int curMove;
201
    private int numMove;
202
    private boolean mCanRotate;
203
    private boolean mInitialized;
204

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

    
207
    Pattern(String n, String m)
208
      {
209
      nameStr = n;
210
      moveStr = m;
211
      mCanRotate   = true;
212
      mInitialized = false;
213
      }
214

    
215
  /////////////////////////////////////////////////////////////
216

    
217
    private void initialize()
218
      {
219
      numMove = moveStr.length()/4;
220
      moves   = new int[numMove][3];
221
      curMove = numMove;
222

    
223
      int digit0, digit1, digit2;
224

    
225
      for(int i=0; i<numMove; i++)
226
        {
227
        digit0 = moveStr.charAt(4*i+1)-'0';
228
        digit1 = moveStr.charAt(4*i+2)-'0';
229
        digit2 = moveStr.charAt(4*i+3)-'0';
230

    
231
        moves[i][0] = (10*digit0+digit1)/32;
232
        moves[i][1] = (10*digit0+digit1)%32;
233
        moves[i][2] = 2-digit2;
234
        }
235

    
236
      moveStr = null;
237
      mInitialized = true;
238
      }
239

    
240
  /////////////////////////////////////////////////////////////
241

    
242
    String getName()
243
      {
244
      return nameStr;
245
      }
246

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

    
249
    int getNumMove()
250
      {
251
      if( !mInitialized ) initialize();
252

    
253
      return numMove;
254
      }
255

    
256
  /////////////////////////////////////////////////////////////
257

    
258
    int getCurMove()
259
      {
260
      if( !mInitialized ) initialize();
261

    
262
      return curMove;
263
      }
264

    
265
  /////////////////////////////////////////////////////////////
266

    
267
    void makeMove(RubikPostRender post)
268
      {
269
      if( !mInitialized ) initialize();
270

    
271
      curMove++;
272
      RubikObject object = post.getObject();
273

    
274
      if( mCanRotate )
275
        {
276
        if( curMove>numMove )
277
          {
278
          curMove= 0;
279
          post.initializeObject(null);
280
          }
281
        else
282
          {
283
          int axis     =moves[curMove-1][0];
284
		      int rowBitmap=moves[curMove-1][1];
285
		      int bareAngle=moves[curMove-1][2];
286
          int angle    = bareAngle*(360/object.getBasicAngle());
287
          int numRot   = Math.abs(bareAngle);
288

    
289
          if( angle!=0 )
290
            {
291
            mCanRotate = false;
292
            post.addRotation(this, axis, rowBitmap, angle, numRot*DURATION_MILLIS);
293
            }
294
          else
295
            {
296
            android.util.Log.e("pattern", "error: pattern "+nameStr+" move "+(curMove-1)+" angle 0");
297
            }
298
          }
299
        }
300
      else
301
        {
302
        android.util.Log.e("pattern", "failed to make Move!");
303
        curMove--;
304
        }
305
      }
306

    
307
  /////////////////////////////////////////////////////////////
308

    
309
    void backMove(RubikPostRender post)
310
      {
311
      if( !mInitialized ) initialize();
312

    
313
      curMove--;
314
      RubikObject object = post.getObject();
315

    
316
      if( mCanRotate )
317
        {
318
        if( curMove<0 )
319
          {
320
          curMove=numMove;
321
          post.initializeObject(moves);
322
          }
323
        else
324
          {
325
          int axis     =moves[curMove][0];
326
		      int rowBitmap=moves[curMove][1];
327
		      int bareAngle=moves[curMove][2];
328
          int angle    = bareAngle*(360/object.getBasicAngle());
329
          int numRot   = Math.abs(bareAngle);
330

    
331
          if( angle!=0 )
332
            {
333
            mCanRotate = false;
334
            post.addRotation(this, axis, rowBitmap, -angle, numRot*DURATION_MILLIS);
335
            }
336
          else
337
            {
338
            android.util.Log.e("pattern", "error: pattern "+nameStr+" move "+curMove+" angle 0");
339
            }
340
          }
341
        }
342
      else
343
        {
344
        android.util.Log.e("pattern", "failed to back Move!");
345
        curMove++;
346
        }
347
      }
348

    
349
  /////////////////////////////////////////////////////////////
350

    
351
    int[][] reInitialize()
352
      {
353
      if( !mInitialized ) initialize();
354

    
355
      mCanRotate = true;
356
      curMove = numMove;
357
      return moves;
358
      }
359

    
360
  /////////////////////////////////////////////////////////////
361

    
362
    public void onActionFinished(final long effectID)
363
      {
364
      mCanRotate = true;
365
      }
366
    }
367

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

    
370
  private RubikPattern()
371
    {
372
    mCategories = new ArrayList<>();
373

    
374
    initializeCategories(0, RubikPatternCube2.patterns);
375
    initializeCategories(1, RubikPatternCube3.patterns);
376
    initializeCategories(2, RubikPatternCube4.patterns);
377
    initializeCategories(3, RubikPatternCube5.patterns);
378
    }
379

    
380
///////////////////////////////////////////////////////////////////////////////////////////////////
381

    
382
  private void initializeCategories(int num, String[][] pat)
383
    {
384
    List<Category> list = new ArrayList<>();
385
    Category cat;
386

    
387
    for(String[] lines: pat)
388
      {
389
      cat = new Category(lines);
390
      list.add(cat);
391
      }
392

    
393
    mCategories.add(num,list);
394
    numCategories[num]=pat.length;
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 tab)
414
    {
415
    return tab>=0 && tab<NUM_CUBES ? numCategories[tab] : 0;
416
    }
417

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

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

    
428
    return null;
429
    }
430

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

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

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

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

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

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

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

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

    
466
    return null;
467
    }
468

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

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

    
479
    return 0;
480
    }
481

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

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

    
492
    return 0;
493
    }
494

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

    
497
  public int getNumMoves(int tab, int cat, int pat)
498
    {
499
    if( tab>=0 && tab<NUM_CUBES && cat>=0 && cat< numCategories[tab] )
500
      {
501
      Category c = mCategories.get(tab).get(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 tab, int cat, int pat)
511
    {
512
    if( tab>=0 && tab<NUM_CUBES && cat>=0 && cat< numCategories[tab] )
513
      {
514
      Category c = mCategories.get(tab).get(cat);
515
      if( c!=null ) c.makeMove(post,pat);
516
      }
517
    }
518

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

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

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

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

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