Project

General

Profile

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

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

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
          mCanRotate = false;
259

    
260
          int axis     =moves[curMove-1][0];
261
		      int rowBitmap=moves[curMove-1][1];
262
		      int bareAngle=moves[curMove-1][2];
263
          int angle    = bareAngle*(360/object.getBasicAngle());
264
          int numRot   = Math.abs(bareAngle);
265

    
266
          post.addRotation(this, axis, rowBitmap, angle, numRot*DURATION_MILLIS);
267
          }
268
        }
269
      else
270
        {
271
        android.util.Log.e("pattern", "failed to make Move!");
272
        curMove--;
273
        }
274
      }
275

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

    
278
    void backMove(RubikPostRender post)
279
      {
280
      if( !mInitialized )
281
        {
282
        mInitialized = true;
283
        moves = movesParser(moveStr);
284
        moveStr = null;
285
        }
286

    
287
      curMove--;
288
      RubikObject object = post.getObject();
289

    
290
      if( mCanRotate )
291
        {
292
        if( curMove<0 )
293
          {
294
          curMove=numMove;
295
          post.initializeObject(moves);
296
          }
297
        else
298
          {
299
          mCanRotate = false;
300

    
301
          int axis     =moves[curMove][0];
302
		      int rowBitmap=moves[curMove][1];
303
		      int bareAngle=moves[curMove][2];
304
          int angle    = bareAngle*(360/object.getBasicAngle());
305
          int numRot   = Math.abs(bareAngle);
306

    
307
          post.addRotation(this, axis, rowBitmap, -angle, numRot*DURATION_MILLIS);
308
          }
309
        }
310
      else
311
        {
312
        android.util.Log.e("pattern", "failed to back Move!");
313
        curMove++;
314
        }
315
      }
316

    
317
  /////////////////////////////////////////////////////////////
318

    
319
    int[][] reInitialize()
320
      {
321
      if( !mInitialized )
322
        {
323
        mInitialized = true;
324
        moves = movesParser(moveStr);
325
        moveStr = null;
326
        }
327

    
328
      mCanRotate = true;
329
      curMove = numMove;
330
      return moves;
331
      }
332

    
333
  /////////////////////////////////////////////////////////////
334

    
335
    public void onActionFinished(final long effectID)
336
      {
337
      mCanRotate = true;
338
      }
339
    }
340

    
341
///////////////////////////////////////////////////////////////////////////////////////////////////
342

    
343
  private RubikPattern()
344
    {
345
    mCategories = new Vector[NUM_CUBES];
346

    
347
    initializeCategories(0, RubikPatternData2.patterns);
348
    initializeCategories(1, RubikPatternData3.patterns);
349
    initializeCategories(2, RubikPatternData4.patterns);
350
    initializeCategories(3, RubikPatternData5.patterns);
351
    }
352

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

    
355
  private void initializeCategories(int num, String[] pat)
356
    {
357
    int colon;
358
    mCategories[num] = new Vector<>();
359
    Category cat=null;
360
    String name, pattern;
361
    Pattern patt;
362

    
363
    numCategories[num]=0;
364

    
365
    for(String p: pat)
366
      {
367
      colon = p.indexOf(':');
368

    
369
      if( colon==-1 )
370
        {
371
        cat = new Category(p);
372
        mCategories[num].addElement(cat);
373
        numCategories[num]++;
374
        }
375
      else
376
        {
377
        pattern = p.substring(colon+1);
378
        name    = p.substring(0,colon);
379
        patt = new Pattern(name,pattern);
380
        cat.addPattern(patt);
381
        }
382
      }
383
    }
384

    
385
///////////////////////////////////////////////////////////////////////////////////////////////////
386
// PUBLIC API
387
///////////////////////////////////////////////////////////////////////////////////////////////////
388

    
389
  public static RubikPattern getInstance()
390
    {
391
    if( mThis==null )
392
      {
393
      mThis = new RubikPattern();
394
      }
395

    
396
    return mThis;
397
    }
398

    
399
///////////////////////////////////////////////////////////////////////////////////////////////////
400

    
401
  public int getNumCategories(int size)
402
    {
403
    return size>=0 && size<NUM_CUBES ? numCategories[size] : 0;
404
    }
405

    
406
///////////////////////////////////////////////////////////////////////////////////////////////////
407

    
408
  public String getCategoryName(int size,int num)
409
    {
410
    if( size>=0 && size<NUM_CUBES && num>=0 && num< numCategories[size] )
411
      {
412
      Category c = mCategories[size].elementAt(num);
413
      return c!=null ? c.getName() : null;
414
      }
415

    
416
    return null;
417
    }
418

    
419
///////////////////////////////////////////////////////////////////////////////////////////////////
420

    
421
  public void rememberState(int size,int num, int scrollPos)
422
    {
423
    if( size>=0 && size<NUM_CUBES )
424
      {
425
      currentCategory[size] = num;
426
      currentScrollPos[size]= scrollPos;
427
      }
428
    }
429

    
430
///////////////////////////////////////////////////////////////////////////////////////////////////
431

    
432
  public int recallCategory(int size)
433
    {
434
    return size>=0 && size<NUM_CUBES ? currentCategory[size] : 0;
435
    }
436

    
437
///////////////////////////////////////////////////////////////////////////////////////////////////
438

    
439
  public int recallScrollPos(int size)
440
    {
441
    return size>=0 && size<NUM_CUBES ? currentScrollPos[size] : 0;
442
    }
443

    
444
///////////////////////////////////////////////////////////////////////////////////////////////////
445

    
446
  public String getPatternName(int size, int cat, int pat)
447
    {
448
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
449
      {
450
      Category c = mCategories[size].elementAt(cat);
451
      return c!=null ? c.getPatternName(pat) : null;
452
      }
453

    
454
    return null;
455
    }
456

    
457
///////////////////////////////////////////////////////////////////////////////////////////////////
458

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

    
467
    return 0;
468
    }
469

    
470
///////////////////////////////////////////////////////////////////////////////////////////////////
471

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

    
480
    return 0;
481
    }
482

    
483
///////////////////////////////////////////////////////////////////////////////////////////////////
484

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

    
493
    return 0;
494
    }
495

    
496
///////////////////////////////////////////////////////////////////////////////////////////////////
497

    
498
  public void makeMove(RubikPostRender post, int size, int cat, int pat)
499
    {
500
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
501
      {
502
      Category c = mCategories[size].elementAt(cat);
503
      if( c!=null ) c.makeMove(post,pat);
504
      }
505
    }
506

    
507
///////////////////////////////////////////////////////////////////////////////////////////////////
508

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

    
518
///////////////////////////////////////////////////////////////////////////////////////////////////
519

    
520
  public int[][] reInitialize(int size, int cat, int pat)
521
    {
522
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
523
      {
524
      Category c = mCategories[size].elementAt(cat);
525
      if( c!=null ) return c.reInitialize(pat);
526
      }
527

    
528
    return null;
529
    }
530
}
(1-1/5)