Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / RubikObjectList.java @ 7e97ea45

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2021 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

    
10
package org.distorted.objects;
11

    
12
import java.util.ArrayList;
13
import java.util.Locale;
14

    
15
import android.content.Context;
16
import android.content.SharedPreferences;
17

    
18
import org.distorted.external.RubikFiles;
19
//import org.distorted.external.RubikScores;
20
import org.distorted.main.RubikActivity;
21
import org.distorted.objectlib.main.ObjectSignatures;
22
import org.distorted.objectlib.main.ObjectType;
23

    
24
import static org.distorted.objectlib.main.TwistyObject.MESH_NICE;
25
import static org.distorted.objectlib.main.ObjectType.NUM_OBJECTS;
26
import static org.distorted.main.RubikActivity.SHOW_DOWNLOADED_DEBUG;
27
//import static org.distorted.main.RubikActivity.SHOW_SOLVED_DEBUG;
28
import static org.distorted.screens.RubikScreenPlay.LEVELS_SHOWN;
29

    
30
///////////////////////////////////////////////////////////////////////////////////////////////////
31

    
32
public class RubikObjectList
33
{
34
  public static final int DEF_OBJECT= ObjectSignatures.CUBE_3;
35
  private static RubikObjectList mThis;
36
  private static int mNumObjects;
37
  private static int mNumExtras;
38
  private static ArrayList<RubikObject> mObjects;
39
  private static int mObject = DEF_OBJECT;
40

    
41
  public static class DownloadedObject
42
    {
43
    String shortName;
44
    boolean icon,object,extras,free;
45
    int numScrambles, objectMinor, extrasMinor;
46

    
47
    DownloadedObject(String sName, int scrambles, boolean isFree, int oMinor, int eMinor, boolean i, boolean o, boolean e)
48
      {
49
      shortName = sName;
50

    
51
      numScrambles= scrambles;
52
      free        = isFree;
53
      objectMinor = oMinor;
54
      extrasMinor = eMinor;
55

    
56
      icon   = i;
57
      object = o;
58
      extras = e;
59
      }
60
    }
61

    
62
  private static ArrayList<DownloadedObject> mDownloadedObjects;
63
  /*
64
  private static String mFreeSolvedObjects;
65
  private static String mFreeBoughtObjects;
66
  private static int mNumFreeSolved;
67
  */
68
///////////////////////////////////////////////////////////////////////////////////////////////////
69

    
70
  private RubikObjectList()
71
    {
72
    mNumObjects    = 0;
73
    mNumExtras     = 0;
74
    //mNumFreeSolved = 0;
75

    
76
    mObjects           = new ArrayList<>();
77
    mDownloadedObjects = new ArrayList<>();
78

    
79
    createBuiltinObjects();
80
    }
81

    
82
///////////////////////////////////////////////////////////////////////////////////////////////////
83

    
84
  private void createBuiltinObjects()
85
    {
86
    for(int i=0; i<NUM_OBJECTS; i++)
87
      {
88
      ObjectType type = ObjectType.getObject(i);
89
      RubikObject obj = new RubikObject(type);
90
      mObjects.add(obj);
91
      mNumObjects++;
92

    
93
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "creating local object "+type.name() );
94

    
95
      if( obj.hasExtras() )
96
        {
97
        if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "has extras "+mNumExtras );
98

    
99
        obj.setExtrasOrdinal(mNumExtras);
100
        mNumExtras++;
101
        }
102
      else
103
        {
104
        if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "no extras");
105
        }
106
      }
107
    }
108

    
109
///////////////////////////////////////////////////////////////////////////////////////////////////
110

    
111
  private static boolean internalAddDownloadedObject(DownloadedObject object)
112
    {
113
    String name = object.shortName;
114

    
115
    for(RubikObject ro : mObjects )
116
      if( ro.getLowerName().equals(name) )
117
        {
118
        return ro.updateObject(object);
119
        }
120

    
121
    RubikObject obj = new RubikObject(object);
122
    mObjects.add(obj);
123
    mNumObjects++;
124
    /*
125
    int numUnclaimed = getNumUnclaimedSolves();
126

    
127
    if( numUnclaimed>0 && !obj.isFree() )
128
      {
129
      String objname = obj.getUpperName();
130
      if( SHOW_SOLVED_DEBUG ) android.util.Log.e("D", "downloadedObject: "+objname+" making it solved. Unclaimed: "+numUnclaimed);
131
      solveObject(obj,objname);
132
      }
133
    */
134
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "creating downloaded object "+obj.getUpperName() );
135

    
136
    if( obj.hasExtras() )
137
      {
138
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "has extras "+mNumExtras );
139

    
140
      obj.setExtrasOrdinal(mNumExtras);
141
      mNumExtras++;
142
      }
143
    else
144
      {
145
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "no extras");
146
      }
147

    
148
    return true;
149
    }
150

    
151
///////////////////////////////////////////////////////////////////////////////////////////////////
152

    
153
  public static int computeNumStars(int level)
154
    {
155
    return level>=LEVELS_SHOWN ? 50 : level;
156
    }
157

    
158
///////////////////////////////////////////////////////////////////////////////////////////////////
159
/*
160
  private static void restoreFreedObjects(SharedPreferences preferences)
161
    {
162
    mFreeSolvedObjects = preferences.getString("rol_freeSolved", "");
163
    mFreeBoughtObjects = preferences.getString("rol_freeBought", "");
164

    
165
    if( SHOW_SOLVED_DEBUG )
166
      {
167
      android.util.Log.e("D", "freeSolved: "+mFreeSolvedObjects);
168
      android.util.Log.e("D", "freeBought: "+mFreeBoughtObjects);
169
      }
170

    
171
    if( mFreeBoughtObjects.length()>0 )
172
      {
173
      if( mFreeBoughtObjects.charAt(0)=='*' )
174
        {
175
        for(int i=0; i<mNumObjects; i++)
176
          {
177
          RubikObject o = mObjects.get(i);
178
          o.markFree();
179
          }
180
        }
181
      else
182
        {
183
        String[] objs = mFreeBoughtObjects.split(",");
184

    
185
        for( String obj : objs )
186
          {
187
          RubikObject o = getObject(obj);
188
          if( o!=null ) o.markFree();
189
          }
190
        }
191
      }
192

    
193
    if( mFreeSolvedObjects.length()>0 )
194
      {
195
      String[] objs = mFreeSolvedObjects.split(",");
196
      mNumFreeSolved = objs.length;
197

    
198
      for( String obj : objs )
199
        {
200
        RubikObject o = getObject(obj);
201
        if( o!=null ) o.markFree();
202
        }
203
      }
204
    }
205

    
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207

    
208
  private static int getNumUnclaimedSolves()
209
    {
210
    RubikScores scores = RubikScores.getInstance();
211
    int numMAXes = scores.numberOfSolvedMAXes();
212
    return numMAXes-mNumFreeSolved;
213
    }
214

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

    
217
  private static int markAllSolvedAsFree()
218
    {
219
    RubikScores scores = RubikScores.getInstance();
220
    int numObjects = RubikObjectList.getNumObjects();
221
    int level = LEVELS_SHOWN;
222
    int ret = 0;
223

    
224
    for(int obj=0; obj<numObjects; obj++)
225
      {
226
      RubikObject object = getObject(obj);
227

    
228
      if( object!=null && !object.isFree() && scores.isSolved(obj,level) )
229
        {
230
        solveObject(object.getUpperName());
231
        ret++;
232
        }
233
      }
234

    
235
    return ret;
236
    }
237

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

    
240
  private static void markAsFree(int numToBeMarked)
241
    {
242
    int numObjects = RubikObjectList.getNumObjects();
243

    
244
    for(int obj=0; obj<numObjects && numToBeMarked>0; obj++)
245
      {
246
      RubikObject object = getObject(obj);
247

    
248
      if( object!=null && !object.isFree() )
249
        {
250
        solveObject(object.getUpperName());
251
        numToBeMarked--;
252
        }
253
      }
254
    }
255

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

    
258
  public static boolean solveObject(RubikObject object, String shortName)
259
    {
260
    if( object!=null && !object.isFree() )
261
      {
262
      if( SHOW_SOLVED_DEBUG ) android.util.Log.e("D", "object "+shortName+" marked as solved");
263
      object.markFree();
264
      String add = mFreeSolvedObjects.length()==0 ? shortName : (","+shortName);
265
      mFreeSolvedObjects += add;
266
      mNumFreeSolved++;
267
      return true;
268
      }
269

    
270
    return false;
271
    }
272
*/
273
///////////////////////////////////////////////////////////////////////////////////////////////////
274
// PUBLIC API
275

    
276
  public static boolean addDownloadedObject(Context context, String shortName, int numScrambles, boolean isFree, int objectMinor,
277
                                         int extrasMinor, boolean icon, boolean object, boolean extras)
278
    {
279
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "New downloaded object "+shortName+" icon="+icon+" object="+object+" extras="+extras);
280

    
281
    for( DownloadedObject obj : mDownloadedObjects )
282
      {
283
      if( obj.shortName.equals(shortName) )
284
        {
285
        obj.icon  |= icon;
286
        obj.object|= object;
287
        obj.extras|= extras;
288

    
289
        if( !obj.object ) objectMinor=-1;
290
        if( !obj.extras ) extrasMinor=-1;
291

    
292
        obj.objectMinor = objectMinor;
293
        obj.extrasMinor = extrasMinor;
294

    
295
        if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "Updating downloaded object "+shortName+" icon="+obj.icon+" object="+obj.object+" extras="+obj.extras);
296

    
297
        try
298
          {
299
          RubikActivity ract = (RubikActivity)context;
300
          ract.reloadObject(shortName);
301
          }
302
        catch(Exception ex)
303
          {
304
          android.util.Log.e("D", "exception trying to reload object: "+ex.getMessage() );
305
          }
306

    
307
        return false;
308
        }
309
      }
310

    
311
    if( !object ) objectMinor=-1;
312
    if( !extras ) extrasMinor=-1;
313

    
314
    DownloadedObject obj = new DownloadedObject(shortName,numScrambles,isFree,objectMinor,extrasMinor,icon,object,extras);
315
    if ( internalAddDownloadedObject(obj) )
316
      {
317
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "Adding new downloaded object "+shortName+" icon="+obj.icon+" object="+obj.object+" extras="+obj.extras);
318
      mDownloadedObjects.add(obj);
319
      return true;
320
      }
321
    else
322
      {
323
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "New downloaded object "+shortName+" is already built-in, deleting");
324
      RubikFiles files = RubikFiles.getInstance();
325
      files.deleteIcon(context,shortName);
326
      files.deleteJsonObject(context,shortName);
327
      files.deleteJsonExtras(context,shortName);
328
      return false;
329
      }
330
    }
331

    
332
///////////////////////////////////////////////////////////////////////////////////////////////////
333

    
334
  public static void setMeshState(int ordinal, int state)
335
    {
336
    if( ordinal>=0 && ordinal<mNumObjects ) mObjects.get(ordinal).setMeshState(state);
337
    }
338

    
339
///////////////////////////////////////////////////////////////////////////////////////////////////
340

    
341
  public static int getMeshState(int ordinal)
342
    {
343
    return (ordinal>=0 && ordinal<mNumObjects) ? mObjects.get(ordinal).getMeshState() : MESH_NICE;
344
    }
345

    
346
///////////////////////////////////////////////////////////////////////////////////////////////////
347

    
348
  public static void saveMeshState(SharedPreferences.Editor editor)
349
    {
350
    for(int i=0; i<mNumObjects; i++)
351
      {
352
      RubikObject obj = getObject(i);
353

    
354
      if( obj!=null )
355
        {
356
        String name = obj.getUpperName();
357
        editor.putInt("rol_"+name, obj.getMeshState() );
358
        }
359
      }
360
    }
361
/*
362
///////////////////////////////////////////////////////////////////////////////////////////////////
363

    
364
  public static boolean allAlreadyBought()
365
    {
366
    return mFreeBoughtObjects.equals("*");
367
    }
368

    
369
///////////////////////////////////////////////////////////////////////////////////////////////////
370

    
371
  public static boolean thereAreLockedObjects()
372
    {
373
    for(int i=0; i<mNumObjects; i++)
374
      {
375
      RubikObject o = mObjects.get(i);
376
      if( !o.isFree() ) return true;
377
      }
378

    
379
    return false;
380
    }
381

    
382
///////////////////////////////////////////////////////////////////////////////////////////////////
383

    
384
  public static boolean objectAlreadyBought(String shortName)
385
    {
386
    RubikObject o = getObject(shortName);
387
    return ( o!=null && o.isFree() );
388
    }
389

    
390
///////////////////////////////////////////////////////////////////////////////////////////////////
391

    
392
  public static void buyAll()
393
    {
394
    mFreeBoughtObjects = "*";
395
    if( SHOW_SOLVED_DEBUG ) android.util.Log.e("D", "all objects marked as bought");
396

    
397
    for(int i=0; i<mNumObjects; i++)
398
      {
399
      RubikObject o = mObjects.get(i);
400
      o.markFree();
401
      }
402
    }
403

    
404
///////////////////////////////////////////////////////////////////////////////////////////////////
405

    
406
  public static boolean buyObject(String shortName)
407
    {
408
    RubikObject o = getObject(shortName);
409

    
410
    if( o!=null && !o.isFree() )
411
      {
412
      if( SHOW_SOLVED_DEBUG ) android.util.Log.e("D", "object "+shortName+" marked as bought");
413
      o.markFree();
414
      String add = mFreeBoughtObjects.length()==0 ? shortName : (","+shortName);
415
      mFreeBoughtObjects += add;
416
      return true;
417
      }
418

    
419
    return false;
420
    }
421

    
422
///////////////////////////////////////////////////////////////////////////////////////////////////
423

    
424
  public static boolean solveObject(String shortName)
425
    {
426
    RubikObject object = getObject(shortName);
427
    return solveObject(object,shortName);
428
    }
429
*/
430
///////////////////////////////////////////////////////////////////////////////////////////////////
431

    
432
  public static void savePreferences(SharedPreferences.Editor editor)
433
    {
434
    RubikObject obj = getObject(mObject);
435
    if( obj!=null ) editor.putString("rol_objName", obj.getUpperName() );
436

    
437
    int numDownloaded = mDownloadedObjects.size();
438

    
439
    if( numDownloaded>0 )
440
      {
441
      StringBuilder downloadedObjects = new StringBuilder();
442

    
443
      for(int i=0; i<numDownloaded; i++)
444
        {
445
        if( i>0 ) downloadedObjects.append(',');
446

    
447
        DownloadedObject object = mDownloadedObjects.get(i);
448
        downloadedObjects.append(object.shortName);
449
        downloadedObjects.append(' ');
450
        downloadedObjects.append(object.numScrambles);
451
        downloadedObjects.append(' ');
452
        downloadedObjects.append(object.objectMinor);
453
        downloadedObjects.append(' ');
454
        downloadedObjects.append(object.extrasMinor);
455
        downloadedObjects.append(' ');
456
        downloadedObjects.append(object.icon   ? "1":"0");
457
        downloadedObjects.append(' ');
458
        downloadedObjects.append(object.object ? "1":"0");
459
        downloadedObjects.append(' ');
460
        downloadedObjects.append(object.extras ? "1":"0");
461
        downloadedObjects.append(' ');
462
        downloadedObjects.append(object.free ? "true":"false");
463
        }
464

    
465
      String objects = downloadedObjects.toString();
466
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "saving: "+objects);
467
      editor.putString("rol_downloaded", objects );
468
      }
469
    else
470
      {
471
      editor.putString("rol_downloaded", "" );
472
      }
473
/*
474
    editor.putString("rol_freeSolved", mFreeSolvedObjects);
475
    editor.putString("rol_freeBought", mFreeBoughtObjects);
476

    
477
    if( SHOW_SOLVED_DEBUG )
478
      {
479
      android.util.Log.e("D", "saving solved objects: "+mFreeSolvedObjects);
480
      android.util.Log.e("D", "saving bought objects: "+mFreeBoughtObjects);
481
      }
482
 */
483
    }
484

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

    
487
  public static void restorePreferences(Context context, SharedPreferences preferences, boolean justStarted)
488
    {
489
    if( mThis==null ) mThis = new RubikObjectList();
490

    
491
    String downloaded = preferences.getString("rol_downloaded","");
492

    
493
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", downloaded);
494

    
495
    if( !downloaded.equals(""))
496
      {
497
      String[] dObjects = downloaded.split(",");
498

    
499
      for(String dObj : dObjects)
500
        {
501
        String[] parts = dObj.split(" ");
502
        int length = parts.length;
503

    
504
        if( length==7 || length==8 )
505
          {
506
          String name = parts[0];
507
          String scra = parts[1];
508
          String objM = parts[2];
509
          String extM = parts[3];
510
          String icon = parts[4];
511
          String obje = parts[5];
512
          String extr = parts[6];
513
          boolean isFree = (length==7 || Boolean.parseBoolean(parts[7]));
514

    
515
          int scrambles = Integer.parseInt(scra);
516
          int oMinor    = Integer.parseInt(objM);
517
          int eMinor    = Integer.parseInt(extM);
518

    
519
          boolean bIcon = icon.equals("1");
520
          boolean bObje = obje.equals("1");
521
          boolean bExtr = extr.equals("1");
522

    
523
          addDownloadedObject(context,name,scrambles,isFree,oMinor,eMinor,bIcon,bObje,bExtr);
524
          }
525
        }
526
      }
527

    
528
    RubikObject object = getObject(DEF_OBJECT);
529
    String defName = object==null ? "CUBE_3" : object.getUpperName();
530
    String objName= preferences.getString("rol_objName",defName);
531
    mObject = getOrdinal(objName);
532
    if( mObject<0 || mObject>=mNumObjects ) mObject = DEF_OBJECT;
533

    
534
//    if( justStarted) restoreFreedObjects(preferences);
535
    }
536

    
537
///////////////////////////////////////////////////////////////////////////////////////////////////
538

    
539
  public static void restoreMeshState(SharedPreferences preferences)
540
    {
541
    for(int i=0; i<mNumObjects; i++)
542
      {
543
      RubikObject obj = getObject(i);
544

    
545
      if( obj!=null )
546
        {
547
        String name  = obj.getUpperName();
548
        int meshState= preferences.getInt("rol_"+name,MESH_NICE);
549
        obj.setMeshState(meshState);
550
        }
551
      }
552
    }
553

    
554
///////////////////////////////////////////////////////////////////////////////////////////////////
555
/*
556
  public static void setObjectFreeState()
557
    {
558
    int numUnclaimed = getNumUnclaimedSolves();
559

    
560
    if( numUnclaimed>0 )
561
      {
562
      int marked = markAllSolvedAsFree();
563
      int stillUnclaimed = numUnclaimed-marked;
564
      if( stillUnclaimed>0) markAsFree(stillUnclaimed);
565
      }
566
    }
567
*/
568
///////////////////////////////////////////////////////////////////////////////////////////////////
569

    
570
  public static boolean setCurrObject(int ordinal)
571
    {
572
    if( mObject!=ordinal )
573
      {
574
      mObject = ordinal;
575
      return true;
576
      }
577

    
578
    return false;
579
    }
580

    
581
///////////////////////////////////////////////////////////////////////////////////////////////////
582

    
583
  public static int getCurrObject()
584
    {
585
    return mObject;
586
    }
587

    
588
///////////////////////////////////////////////////////////////////////////////////////////////////
589

    
590
  public static String getCurrentName()
591
    {
592
    RubikObject object = mObjects.get(mObject);
593
    return object==null ? "" : object.getUpperName();
594
    }
595

    
596
///////////////////////////////////////////////////////////////////////////////////////////////////
597

    
598
  public static RubikObject getObject(int ordinal)
599
    {
600
    if( mThis==null ) mThis = new RubikObjectList();
601
    return ordinal>=0 && ordinal<mNumObjects ? mObjects.get(ordinal) : null;
602
    }
603

    
604
///////////////////////////////////////////////////////////////////////////////////////////////////
605

    
606
  public static RubikObject getObject(String shortUpperName)
607
    {
608
    if( mThis==null ) mThis = new RubikObjectList();
609

    
610
    for(int i=0; i<mNumObjects; i++)
611
      {
612
      RubikObject object = mObjects.get(i);
613
      if( object.getUpperName().equals(shortUpperName) )
614
        {
615
        return object;
616
        }
617
      }
618

    
619
    return null;
620
    }
621

    
622
///////////////////////////////////////////////////////////////////////////////////////////////////
623

    
624
  public static int getNumObjects()
625
    {
626
    if( mThis==null ) mThis = new RubikObjectList();
627
    return mNumObjects;
628
    }
629

    
630
///////////////////////////////////////////////////////////////////////////////////////////////////
631

    
632
  public static int getOrdinal(String name)
633
    {
634
    if( mThis==null ) mThis = new RubikObjectList();
635

    
636
    String lowerName = name.toLowerCase(Locale.ENGLISH);
637

    
638
    for(int i=0; i<mNumObjects; i++)
639
      {
640
      RubikObject obj = mObjects.get(i);
641
      if( obj.getLowerName().equals(lowerName) ) return i;
642
      }
643

    
644
    return -1;
645
    }
646

    
647
///////////////////////////////////////////////////////////////////////////////////////////////////
648

    
649
  public static int getNumExtrasObjects()
650
    {
651
    return mNumExtras;
652
    }
653

    
654
///////////////////////////////////////////////////////////////////////////////////////////////////
655

    
656
  public static int getNumTutorialObjects()
657
    {
658
    return mNumExtras;
659
    }
660

    
661
///////////////////////////////////////////////////////////////////////////////////////////////////
662

    
663
  public static int getObjectOrdinal(int extrasOrdinal)
664
    {
665
    for(int i=extrasOrdinal; i<mNumObjects; i++)
666
      {
667
      RubikObject object = getObject(i);
668
      int extOrd = object!=null ? object.getExtrasOrdinal() : -1;
669
      if( extOrd==extrasOrdinal ) return i;
670
      }
671

    
672
    return -1;
673
    }
674

    
675
///////////////////////////////////////////////////////////////////////////////////////////////////
676

    
677
  public static int getExtrasOrdinal(int objectOrdinal)
678
    {
679
    RubikObject object = getObject(objectOrdinal);
680
    return object!=null ? object.getExtrasOrdinal() : -1;
681
    }
682

    
683
///////////////////////////////////////////////////////////////////////////////////////////////////
684

    
685
  public static int getTutorialOrdinal(int objectOrdinal)
686
    {
687
    RubikObject object = getObject(objectOrdinal);
688
    return object!=null ? object.getExtrasOrdinal() : -1;
689
    }
690

    
691
///////////////////////////////////////////////////////////////////////////////////////////////////
692

    
693
  public static int getLocalObjectMinor(int objectOrdinal)
694
    {
695
    RubikObject object = getObject(objectOrdinal);
696
    return object!=null ? object.getObjectMinor() : -1;
697
    }
698

    
699
///////////////////////////////////////////////////////////////////////////////////////////////////
700

    
701
  public static int getLocalExtrasMinor(int objectOrdinal)
702
    {
703
    RubikObject object = getObject(objectOrdinal);
704
    return object!=null ? object.getExtrasMinor() : -1;
705
    }
706
}
(2-2/2)