Project

General

Profile

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

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

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
    private boolean mCanRotate;
162

    
163
  /////////////////////////////////////////////////////////////
164

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

    
173
  /////////////////////////////////////////////////////////////
174

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

    
179
      int digit0, digit1, digit2;
180
      int[][] result = new int[numMove][3];
181

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

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

    
193
      return result;
194
      }
195

    
196
  /////////////////////////////////////////////////////////////
197

    
198
    String getName()
199
      {
200
      return name;
201
      }
202

    
203
  /////////////////////////////////////////////////////////////
204

    
205
    int getNumMove()
206
      {
207
      return numMove;
208
      }
209

    
210
  /////////////////////////////////////////////////////////////
211

    
212
    int getCurMove()
213
      {
214
      return curMove;
215
      }
216

    
217
  /////////////////////////////////////////////////////////////
218

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

    
224
      if( mCanRotate )
225
        {
226
        if( curMove>numMove )
227
          {
228
          curMove= 0;
229
          post.initializeObject(null);
230
          }
231
        else
232
          {
233
          mCanRotate = false;
234

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

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

    
251
  /////////////////////////////////////////////////////////////
252

    
253
    void backMove(RubikPostRender post)
254
      {
255
      curMove--;
256
      RubikObject object = post.getObject();
257

    
258
      if( mCanRotate )
259
        {
260
        if( curMove<0 )
261
          {
262
          curMove=numMove;
263
          post.initializeObject(moves);
264
          }
265
        else
266
          {
267
          mCanRotate = false;
268

    
269
          int axis     =moves[curMove][0];
270
		      int rowBitmap=moves[curMove][1];
271
		      int bareAngle=moves[curMove][2];
272
          int angle    = bareAngle*(360/object.getBasicAngle());
273
          int numRot   = Math.abs(bareAngle);
274

    
275
          post.addRotation(this, axis, rowBitmap, -angle, numRot*DURATION_MILLIS);
276
          }
277
        }
278
      else
279
        {
280
        android.util.Log.e("pattern", "failed to back Move!");
281
        curMove++;
282
        }
283
      }
284

    
285
  /////////////////////////////////////////////////////////////
286

    
287
    int[][] getMoves()
288
      {
289
      return moves;
290
      }
291

    
292
  /////////////////////////////////////////////////////////////
293

    
294
    public void onActionFinished(final long effectID)
295
      {
296
      mCanRotate = true;
297
      }
298
    }
299

    
300
///////////////////////////////////////////////////////////////////////////////////////////////////
301

    
302
  private RubikPattern()
303
    {
304
    mCategories = new Vector[NUM_CUBES];
305

    
306
    initializeCategories(0, RubikPatternData2.patterns);
307
    initializeCategories(1, RubikPatternData3.patterns);
308
    initializeCategories(2, RubikPatternData4.patterns);
309
    initializeCategories(3, RubikPatternData5.patterns);
310
    }
311

    
312
///////////////////////////////////////////////////////////////////////////////////////////////////
313

    
314
  private void initializeCategories(int num, String[] pat)
315
    {
316
    int colon;
317
    mCategories[num] = new Vector<>();
318
    Category cat=null;
319
    String name, pattern;
320
    Pattern patt;
321

    
322
    numCategories[num]=0;
323

    
324
    for(String p: pat)
325
      {
326
      colon = p.indexOf(':');
327

    
328
      if( colon==-1 )
329
        {
330
        cat = new Category(p);
331
        mCategories[num].addElement(cat);
332
        numCategories[num]++;
333
        }
334
      else
335
        {
336
        pattern = p.substring(colon+1);
337
        name    = p.substring(0,colon);
338
        patt = new Pattern(name,pattern);
339
        cat.addPattern(patt);
340
        }
341
      }
342
    }
343

    
344
///////////////////////////////////////////////////////////////////////////////////////////////////
345
// PUBLIC API
346
///////////////////////////////////////////////////////////////////////////////////////////////////
347

    
348
  public static RubikPattern getInstance()
349
    {
350
    if( mThis==null )
351
      {
352
      mThis = new RubikPattern();
353
      }
354

    
355
    return mThis;
356
    }
357

    
358
///////////////////////////////////////////////////////////////////////////////////////////////////
359

    
360
  public int getNumCategories(int size)
361
    {
362
    return size>=0 && size<NUM_CUBES ? numCategories[size] : 0;
363
    }
364

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

    
367
  public String getCategoryName(int size,int num)
368
    {
369
    if( size>=0 && size<NUM_CUBES && num>=0 && num< numCategories[size] )
370
      {
371
      Category c = mCategories[size].elementAt(num);
372
      return c!=null ? c.getName() : null;
373
      }
374

    
375
    return null;
376
    }
377

    
378
///////////////////////////////////////////////////////////////////////////////////////////////////
379

    
380
  public void rememberCategory(int size,int num)
381
    {
382
    if( size>=0 && size<NUM_CUBES )
383
      {
384
      currentCategory[size] = num;
385
      }
386
    }
387

    
388
///////////////////////////////////////////////////////////////////////////////////////////////////
389

    
390
  public int recallCategory(int size)
391
    {
392
    return size>=0 && size<NUM_CUBES ? currentCategory[size] : 0;
393
    }
394

    
395
///////////////////////////////////////////////////////////////////////////////////////////////////
396

    
397
  public String getPatternName(int size, int cat, int pat)
398
    {
399
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
400
      {
401
      Category c = mCategories[size].elementAt(cat);
402
      return c!=null ? c.getPatternName(pat) : null;
403
      }
404

    
405
    return null;
406
    }
407

    
408
///////////////////////////////////////////////////////////////////////////////////////////////////
409

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

    
418
    return 0;
419
    }
420

    
421
///////////////////////////////////////////////////////////////////////////////////////////////////
422

    
423
  public int getCurMove(int size, int cat, int pat)
424
    {
425
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
426
      {
427
      Category c = mCategories[size].elementAt(cat);
428
      return c!=null ? c.getPatternCurMove(pat):0;
429
      }
430

    
431
    return 0;
432
    }
433

    
434
///////////////////////////////////////////////////////////////////////////////////////////////////
435

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

    
444
    return 0;
445
    }
446

    
447
///////////////////////////////////////////////////////////////////////////////////////////////////
448

    
449
  public void makeMove(RubikPostRender post, int size, int cat, int pat)
450
    {
451
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
452
      {
453
      Category c = mCategories[size].elementAt(cat);
454
      if( c!=null ) c.makeMove(post,pat);
455
      }
456
    }
457

    
458
///////////////////////////////////////////////////////////////////////////////////////////////////
459

    
460
  public void backMove(RubikPostRender post, int size, int cat, int pat)
461
    {
462
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
463
      {
464
      Category c = mCategories[size].elementAt(cat);
465
      if( c!=null ) c.backMove(post,pat);
466
      }
467
    }
468

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

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

    
479
    return null;
480
    }
481
}
(1-1/5)