Project

General

Profile

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

magiccube / src / main / java / org / distorted / patterns / RubikPattern.java @ 6f2a942e

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 nameStr, moveStr;
158
    private int[][] moves;
159
    private int curMove;
160
    private int numMove;
161
    private boolean mCanRotate;
162
    private boolean mInitialized;
163

    
164
  /////////////////////////////////////////////////////////////
165

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

    
174
  /////////////////////////////////////////////////////////////
175

    
176
    private int[][] movesParser(String moves)
177
      {
178
      numMove = moves.length()/4;
179
      curMove=numMove;
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 nameStr;
203
      }
204

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

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

    
216
      return numMove;
217
      }
218

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

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

    
230
      return curMove;
231
      }
232

    
233
  /////////////////////////////////////////////////////////////
234

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

    
244
      curMove++;
245
      RubikObject object = post.getObject();
246

    
247
      if( mCanRotate )
248
        {
249
        if( curMove>numMove )
250
          {
251
          curMove= 0;
252
          post.initializeObject(null);
253
          }
254
        else
255
          {
256
          mCanRotate = false;
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
          post.addRotation(this, axis, rowBitmap, angle, numRot*DURATION_MILLIS);
265
          }
266
        }
267
      else
268
        {
269
        android.util.Log.e("pattern", "failed to make Move!");
270
        curMove--;
271
        }
272
      }
273

    
274
  /////////////////////////////////////////////////////////////
275

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

    
285
      curMove--;
286
      RubikObject object = post.getObject();
287

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

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

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

    
315
  /////////////////////////////////////////////////////////////
316

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

    
326
      curMove = numMove;
327
      return moves;
328
      }
329

    
330
  /////////////////////////////////////////////////////////////
331

    
332
    public void onActionFinished(final long effectID)
333
      {
334
      mCanRotate = true;
335
      }
336
    }
337

    
338
///////////////////////////////////////////////////////////////////////////////////////////////////
339

    
340
  private RubikPattern()
341
    {
342
    mCategories = new Vector[NUM_CUBES];
343

    
344
    initializeCategories(0, RubikPatternData2.patterns);
345
    initializeCategories(1, RubikPatternData3.patterns);
346
    initializeCategories(2, RubikPatternData4.patterns);
347
    initializeCategories(3, RubikPatternData5.patterns);
348
    }
349

    
350
///////////////////////////////////////////////////////////////////////////////////////////////////
351

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

    
360
    numCategories[num]=0;
361

    
362
    for(String p: pat)
363
      {
364
      colon = p.indexOf(':');
365

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

    
382
///////////////////////////////////////////////////////////////////////////////////////////////////
383
// PUBLIC API
384
///////////////////////////////////////////////////////////////////////////////////////////////////
385

    
386
  public static RubikPattern getInstance()
387
    {
388
    if( mThis==null )
389
      {
390
      mThis = new RubikPattern();
391
      }
392

    
393
    return mThis;
394
    }
395

    
396
///////////////////////////////////////////////////////////////////////////////////////////////////
397

    
398
  public int getNumCategories(int size)
399
    {
400
    return size>=0 && size<NUM_CUBES ? numCategories[size] : 0;
401
    }
402

    
403
///////////////////////////////////////////////////////////////////////////////////////////////////
404

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

    
413
    return null;
414
    }
415

    
416
///////////////////////////////////////////////////////////////////////////////////////////////////
417

    
418
  public void rememberCategory(int size,int num)
419
    {
420
    if( size>=0 && size<NUM_CUBES )
421
      {
422
      currentCategory[size] = num;
423
      }
424
    }
425

    
426
///////////////////////////////////////////////////////////////////////////////////////////////////
427

    
428
  public int recallCategory(int size)
429
    {
430
    return size>=0 && size<NUM_CUBES ? currentCategory[size] : 0;
431
    }
432

    
433
///////////////////////////////////////////////////////////////////////////////////////////////////
434

    
435
  public String getPatternName(int size, int cat, int pat)
436
    {
437
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
438
      {
439
      Category c = mCategories[size].elementAt(cat);
440
      return c!=null ? c.getPatternName(pat) : null;
441
      }
442

    
443
    return null;
444
    }
445

    
446
///////////////////////////////////////////////////////////////////////////////////////////////////
447

    
448
  public int getNumPatterns(int size, int num )
449
    {
450
    if( size>=0 && size<NUM_CUBES && num>=0 && num< numCategories[size] )
451
      {
452
      Category c = mCategories[size].elementAt(num);
453
      return c!=null ? c.getNumPatterns() : 0;
454
      }
455

    
456
    return 0;
457
    }
458

    
459
///////////////////////////////////////////////////////////////////////////////////////////////////
460

    
461
  public int getCurMove(int size, int cat, int pat)
462
    {
463
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
464
      {
465
      Category c = mCategories[size].elementAt(cat);
466
      return c!=null ? c.getPatternCurMove(pat):0;
467
      }
468

    
469
    return 0;
470
    }
471

    
472
///////////////////////////////////////////////////////////////////////////////////////////////////
473

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

    
482
    return 0;
483
    }
484

    
485
///////////////////////////////////////////////////////////////////////////////////////////////////
486

    
487
  public void makeMove(RubikPostRender post, int size, int cat, int pat)
488
    {
489
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
490
      {
491
      Category c = mCategories[size].elementAt(cat);
492
      if( c!=null ) c.makeMove(post,pat);
493
      }
494
    }
495

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

    
498
  public void backMove(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.backMove(post,pat);
504
      }
505
    }
506

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

    
509
  public int[][] getMoves(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 ) return c.getMoves(pat);
515
      }
516

    
517
    return null;
518
    }
519
}
(1-1/5)