Project

General

Profile

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

magiccube / src / main / java / org / distorted / patterns / RubikPattern.java @ 8becce57

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
    String 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 "";
150
      }
151
    }
152

    
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154

    
155
  private static class Pattern implements RubikPostRender.ActionFinishedListener
156
    {
157
    private String name;
158
    private String moves;
159
    private int curMove;
160
    private int numMove;
161

    
162
    private boolean mCanRotate;
163
    private RubikObject mObject;
164

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

    
167
    Pattern(String n, String m)
168
      {
169
      name=n;
170
      moves=m;
171
      numMove = moves.length()/4;
172
      curMove=numMove;
173

    
174
      mCanRotate = true;
175
      }
176

    
177
  /////////////////////////////////////////////////////////////
178

    
179
    String getName()
180
      {
181
      return name;
182
      }
183

    
184
  /////////////////////////////////////////////////////////////
185

    
186
    int getNumMove()
187
      {
188
      return numMove;
189
      }
190

    
191
  /////////////////////////////////////////////////////////////
192

    
193
    int getCurMove()
194
      {
195
      return curMove;
196
      }
197

    
198
  /////////////////////////////////////////////////////////////
199

    
200
    void makeMove(RubikPostRender post)
201
      {
202
      curMove++;
203
      RubikObject object = post.getObject();
204

    
205
      if( curMove>numMove )
206
        {
207
        curMove= 0;
208
        object.initializeObject(moves.substring(0,4*curMove));
209
        }
210
      else
211
        {
212
        if( mCanRotate )
213
          {
214
          mCanRotate = false;
215
          mObject = object;
216

    
217
          String move = moves.substring(4*curMove-4,4*curMove);
218
          int a1=move.charAt(1)-'0';
219
		      int a2=move.charAt(2)-'0';
220
		      int a3=move.charAt(3)-'0';
221

    
222
          int axis      = (10*a1+a2)/32;
223
          int rowBitmap = (10*a1+a2)%32;
224
          int angle     = (2-a3)*(360/object.getBasicAngle());
225
          int numRot    = Math.abs(2-a3);
226

    
227
          post.addRotation(this, axis, rowBitmap, angle, numRot*DURATION_MILLIS);
228
          }
229
        else
230
          {
231
          android.util.Log.e("pattern", "failed to make Move!");
232

    
233
          curMove--;
234
          }
235
        }
236
      }
237

    
238
  /////////////////////////////////////////////////////////////
239

    
240
    void backMove(RubikPostRender post)
241
      {
242
      curMove--;
243
      RubikObject object = post.getObject();
244

    
245
      if( curMove<0 )
246
        {
247
        curMove=numMove;
248
        object.initializeObject(moves.substring(0,4*curMove));
249
        }
250
      else
251
        {
252
        if( mCanRotate )
253
          {
254
          mCanRotate = false;
255
          mObject = object;
256

    
257
          String move = moves.substring(4*curMove,4*curMove+4);
258
          int a1=move.charAt(1)-'0';
259
		      int a2=move.charAt(2)-'0';
260
		      int a3=move.charAt(3)-'0';
261

    
262
          int axis      = (10*a1+a2)/32;
263
          int rowBitmap = (10*a1+a2)%32;
264
          int angle     = (2-a3)*(360/object.getBasicAngle());
265
          int numRot    = Math.abs(2-a3);
266

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

    
277
  /////////////////////////////////////////////////////////////
278

    
279
    String getMoves()
280
      {
281
      return moves.substring(0,4*curMove);
282
      }
283

    
284
  /////////////////////////////////////////////////////////////
285

    
286
    public void onActionFinished(final long effectID)
287
      {
288
      mObject.removeRotationNow();
289
      mCanRotate = true;
290
      }
291
    }
292

    
293
///////////////////////////////////////////////////////////////////////////////////////////////////
294

    
295
  private RubikPattern()
296
    {
297
    mCategories = new Vector[NUM_CUBES];
298

    
299
    initializeCategories(0, RubikPatternData2.patterns);
300
    initializeCategories(1, RubikPatternData3.patterns);
301
    initializeCategories(2, RubikPatternData4.patterns);
302
    initializeCategories(3, RubikPatternData5.patterns);
303
    }
304

    
305
///////////////////////////////////////////////////////////////////////////////////////////////////
306

    
307
  private void initializeCategories(int num, String[] pat)
308
    {
309
    int colon;
310
    mCategories[num] = new Vector<>();
311
    Category cat=null;
312
    String name, pattern;
313
    Pattern patt;
314

    
315
    numCategories[num]=0;
316

    
317
    for(String p: pat)
318
      {
319
      colon = p.indexOf(':');
320

    
321
      if( colon==-1 )
322
        {
323
        cat = new Category(p);
324
        mCategories[num].addElement(cat);
325
        numCategories[num]++;
326
        }
327
      else
328
        {
329
        pattern = p.substring(colon+1);
330
        name    = p.substring(0,colon);
331
        patt = new Pattern(name,pattern);
332
        cat.addPattern(patt);
333
        }
334
      }
335
    }
336

    
337
///////////////////////////////////////////////////////////////////////////////////////////////////
338
// PUBLIC API
339
///////////////////////////////////////////////////////////////////////////////////////////////////
340

    
341
  public static RubikPattern getInstance()
342
    {
343
    if( mThis==null )
344
      {
345
      mThis = new RubikPattern();
346
      }
347

    
348
    return mThis;
349
    }
350

    
351
///////////////////////////////////////////////////////////////////////////////////////////////////
352

    
353
  public int getNumCategories(int size)
354
    {
355
    return size>=0 && size<NUM_CUBES ? numCategories[size] : 0;
356
    }
357

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

    
360
  public String getCategoryName(int size,int num)
361
    {
362
    if( size>=0 && size<NUM_CUBES && num>=0 && num< numCategories[size] )
363
      {
364
      Category c = mCategories[size].elementAt(num);
365
      return c!=null ? c.getName() : null;
366
      }
367

    
368
    return null;
369
    }
370

    
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372

    
373
  public void rememberCategory(int size,int num)
374
    {
375
    if( size>=0 && size<NUM_CUBES )
376
      {
377
      currentCategory[size] = num;
378
      }
379
    }
380

    
381
///////////////////////////////////////////////////////////////////////////////////////////////////
382

    
383
  public int recallCategory(int size)
384
    {
385
    return size>=0 && size<NUM_CUBES ? currentCategory[size] : 0;
386
    }
387

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

    
390
  public String getPatternName(int size, int cat, int pat)
391
    {
392
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
393
      {
394
      Category c = mCategories[size].elementAt(cat);
395
      return c!=null ? c.getPatternName(pat) : null;
396
      }
397

    
398
    return null;
399
    }
400

    
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402

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

    
411
    return 0;
412
    }
413

    
414
///////////////////////////////////////////////////////////////////////////////////////////////////
415

    
416
  public int getCurMove(int size, int cat, int pat)
417
    {
418
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
419
      {
420
      Category c = mCategories[size].elementAt(cat);
421
      return c!=null ? c.getPatternCurMove(pat):0;
422
      }
423

    
424
    return 0;
425
    }
426

    
427
///////////////////////////////////////////////////////////////////////////////////////////////////
428

    
429
  public int getNumMoves(int size, int cat, int pat)
430
    {
431
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
432
      {
433
      Category c = mCategories[size].elementAt(cat);
434
      return c!=null ? c.getPatternNumMove(pat):0;
435
      }
436

    
437
    return 0;
438
    }
439

    
440
///////////////////////////////////////////////////////////////////////////////////////////////////
441

    
442
  public void makeMove(RubikPostRender post, int size, int cat, int pat)
443
    {
444
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
445
      {
446
      Category c = mCategories[size].elementAt(cat);
447
      if( c!=null ) c.makeMove(post,pat);
448
      }
449
    }
450

    
451
///////////////////////////////////////////////////////////////////////////////////////////////////
452

    
453
  public void backMove(RubikPostRender post, int size, int cat, int pat)
454
    {
455
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
456
      {
457
      Category c = mCategories[size].elementAt(cat);
458
      if( c!=null ) c.backMove(post,pat);
459
      }
460
    }
461

    
462
///////////////////////////////////////////////////////////////////////////////////////////////////
463

    
464
  public String getMoves(int size, int cat, int pat)
465
    {
466
    if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
467
      {
468
      Category c = mCategories[size].elementAt(cat);
469
      if( c!=null ) return c.getMoves(pat);
470
      }
471

    
472
    return "";
473
    }
474
}
(1-1/5)