Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / RubikObjectList.java @ 24679c47

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
import org.distorted.screens.RubikScreenPlay;
24

    
25
import static org.distorted.objectlib.main.TwistyObject.MESH_NICE;
26
import static org.distorted.objectlib.main.ObjectType.NUM_OBJECTS;
27
import static org.distorted.main.RubikActivity.SHOW_DOWNLOADED_DEBUG;
28
import static org.distorted.main.RubikActivity.SHOW_SOLVED_DEBUG;
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
  private static String mFreeSolvedObjects;
64
  private static String mFreeBoughtObjects;
65
  private static int mNumFreeSolved;
66

    
67
///////////////////////////////////////////////////////////////////////////////////////////////////
68

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

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

    
78
    createBuiltinObjects();
79
    }
80

    
81
///////////////////////////////////////////////////////////////////////////////////////////////////
82

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

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

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

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

    
108
///////////////////////////////////////////////////////////////////////////////////////////////////
109

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

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

    
120
    RubikObject obj = new RubikObject(object);
121
    mObjects.add(obj);
122
    mNumObjects++;
123

    
124
    int numUnclaimed = getNumUnclaimedSolves();
125

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

    
133
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "creating downloaded object "+obj.getUpperName() );
134

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

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

    
147
    return true;
148
    }
149

    
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151

    
152
  private static void restoreFreedObjects(SharedPreferences preferences)
153
    {
154
    mFreeSolvedObjects = preferences.getString("rol_freeSolved", "");
155
    mFreeBoughtObjects = preferences.getString("rol_freeBought", "");
156

    
157
    if( SHOW_SOLVED_DEBUG )
158
      {
159
      android.util.Log.e("D", "freeSolved: "+mFreeSolvedObjects);
160
      android.util.Log.e("D", "freeBought: "+mFreeBoughtObjects);
161
      }
162

    
163
    if( mFreeBoughtObjects.length()>0 )
164
      {
165
      if( mFreeBoughtObjects.charAt(0)=='*' )
166
        {
167
        for(int i=0; i<mNumObjects; i++)
168
          {
169
          RubikObject o = mObjects.get(i);
170
          o.markFree();
171
          }
172
        }
173
      else
174
        {
175
        String[] objs = mFreeBoughtObjects.split(",");
176

    
177
        for( String obj : objs )
178
          {
179
          RubikObject o = getObject(obj);
180
          if( o!=null ) o.markFree();
181
          }
182
        }
183
      }
184

    
185
    if( mFreeSolvedObjects.length()>0 )
186
      {
187
      String[] objs = mFreeSolvedObjects.split(",");
188
      mNumFreeSolved = objs.length;
189

    
190
      for( String obj : objs )
191
        {
192
        RubikObject o = getObject(obj);
193
        if( o!=null ) o.markFree();
194
        }
195
      }
196
    }
197

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

    
200
  private static int getNumUnclaimedSolves()
201
    {
202
    RubikScores scores = RubikScores.getInstance();
203
    int numMAXes = scores.numberOfSolvedMAXes();
204
    return numMAXes-mNumFreeSolved;
205
    }
206

    
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208

    
209
  private static int markAllSolvedAsFree()
210
    {
211
    RubikScores scores = RubikScores.getInstance();
212
    int numObjects = RubikObjectList.getNumObjects();
213
    int level = RubikScreenPlay.LEVELS_SHOWN;
214
    int ret = 0;
215

    
216
    for(int obj=0; obj<numObjects; obj++)
217
      {
218
      RubikObject object = getObject(obj);
219

    
220
      if( object!=null && !object.isFree() && scores.isSolved(obj,level) )
221
        {
222
        solveObject(object.getUpperName());
223
        ret++;
224
        }
225
      }
226

    
227
    return ret;
228
    }
229

    
230
///////////////////////////////////////////////////////////////////////////////////////////////////
231

    
232
  private static void markAsFree(int numToBeMarked)
233
    {
234
    int numObjects = RubikObjectList.getNumObjects();
235

    
236
    for(int obj=0; obj<numObjects && numToBeMarked>0; obj++)
237
      {
238
      RubikObject object = getObject(obj);
239

    
240
      if( object!=null && !object.isFree() )
241
        {
242
        solveObject(object.getUpperName());
243
        numToBeMarked--;
244
        }
245
      }
246
    }
247

    
248
///////////////////////////////////////////////////////////////////////////////////////////////////
249

    
250
  public static boolean solveObject(RubikObject object, String shortName)
251
    {
252
    if( object!=null && !object.isFree() )
253
      {
254
      if( SHOW_SOLVED_DEBUG ) android.util.Log.e("D", "object "+shortName+" marked as solved");
255
      object.markFree();
256
      String add = mFreeSolvedObjects.length()==0 ? shortName : (","+shortName);
257
      mFreeSolvedObjects += add;
258
      mNumFreeSolved++;
259
      return true;
260
      }
261

    
262
    return false;
263
    }
264

    
265
///////////////////////////////////////////////////////////////////////////////////////////////////
266
// PUBLIC API
267

    
268
  public static boolean addDownloadedObject(Context context, String shortName, int numScrambles, boolean isFree, int objectMinor,
269
                                         int extrasMinor, boolean icon, boolean object, boolean extras)
270
    {
271
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "New downloaded object "+shortName+" icon="+icon+" object="+object+" extras="+extras);
272

    
273
    for( DownloadedObject obj : mDownloadedObjects )
274
      {
275
      if( obj.shortName.equals(shortName) )
276
        {
277
        obj.icon  |= icon;
278
        obj.object|= object;
279
        obj.extras|= extras;
280

    
281
        if( !obj.object ) objectMinor=-1;
282
        if( !obj.extras ) extrasMinor=-1;
283

    
284
        obj.objectMinor = objectMinor;
285
        obj.extrasMinor = extrasMinor;
286

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

    
289
        try
290
          {
291
          RubikActivity ract = (RubikActivity)context;
292
          ract.reloadObject(shortName);
293
          }
294
        catch(Exception ex)
295
          {
296
          android.util.Log.e("D", "exception trying to reload object: "+ex.getMessage() );
297
          }
298

    
299
        return false;
300
        }
301
      }
302

    
303
    if( !object ) objectMinor=-1;
304
    if( !extras ) extrasMinor=-1;
305

    
306
    DownloadedObject obj = new DownloadedObject(shortName,numScrambles,isFree,objectMinor,extrasMinor,icon,object,extras);
307
    if ( internalAddDownloadedObject(obj) )
308
      {
309
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "Adding new downloaded object "+shortName+" icon="+obj.icon+" object="+obj.object+" extras="+obj.extras);
310
      mDownloadedObjects.add(obj);
311
      return true;
312
      }
313
    else
314
      {
315
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "New downloaded object "+shortName+" is already built-in, deleting");
316
      RubikFiles files = RubikFiles.getInstance();
317
      files.deleteIcon(context,shortName);
318
      files.deleteJsonObject(context,shortName);
319
      files.deleteJsonExtras(context,shortName);
320
      return false;
321
      }
322
    }
323

    
324
///////////////////////////////////////////////////////////////////////////////////////////////////
325

    
326
  public static void setMeshState(int ordinal, int state)
327
    {
328
    if( ordinal>=0 && ordinal<mNumObjects ) mObjects.get(ordinal).setMeshState(state);
329
    }
330

    
331
///////////////////////////////////////////////////////////////////////////////////////////////////
332

    
333
  public static int getMeshState(int ordinal)
334
    {
335
    return (ordinal>=0 && ordinal<mNumObjects) ? mObjects.get(ordinal).getMeshState() : MESH_NICE;
336
    }
337

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

    
340
  public static void saveMeshState(SharedPreferences.Editor editor)
341
    {
342
    for(int i=0; i<mNumObjects; i++)
343
      {
344
      RubikObject obj = getObject(i);
345

    
346
      if( obj!=null )
347
        {
348
        String name = obj.getUpperName();
349
        editor.putInt("rol_"+name, obj.getMeshState() );
350
        }
351
      }
352
    }
353

    
354
///////////////////////////////////////////////////////////////////////////////////////////////////
355

    
356
  public static boolean allAlreadyBought()
357
    {
358
    return mFreeBoughtObjects.equals("*");
359
    }
360

    
361
///////////////////////////////////////////////////////////////////////////////////////////////////
362

    
363
  public static boolean thereAreLockedObjects()
364
    {
365
    for(int i=0; i<mNumObjects; i++)
366
      {
367
      RubikObject o = mObjects.get(i);
368
      if( !o.isFree() ) return true;
369
      }
370

    
371
    return false;
372
    }
373

    
374
///////////////////////////////////////////////////////////////////////////////////////////////////
375

    
376
  public static boolean objectAlreadyBought(String shortName)
377
    {
378
    RubikObject o = getObject(shortName);
379
    return ( o!=null && o.isFree() );
380
    }
381

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

    
384
  public static void buyAll()
385
    {
386
    mFreeBoughtObjects = "*";
387
    if( SHOW_SOLVED_DEBUG ) android.util.Log.e("D", "all objects marked as bought");
388

    
389
    for(int i=0; i<mNumObjects; i++)
390
      {
391
      RubikObject o = mObjects.get(i);
392
      o.markFree();
393
      }
394
    }
395

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

    
398
  public static boolean buyObject(String shortName)
399
    {
400
    RubikObject o = getObject(shortName);
401

    
402
    if( o!=null && !o.isFree() )
403
      {
404
      if( SHOW_SOLVED_DEBUG ) android.util.Log.e("D", "object "+shortName+" marked as bought");
405
      o.markFree();
406
      String add = mFreeBoughtObjects.length()==0 ? shortName : (","+shortName);
407
      mFreeBoughtObjects += add;
408
      return true;
409
      }
410

    
411
    return false;
412
    }
413

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

    
416
  public static boolean solveObject(String shortName)
417
    {
418
    RubikObject object = getObject(shortName);
419
    return solveObject(object,shortName);
420
    }
421

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

    
424
  public static void savePreferences(SharedPreferences.Editor editor)
425
    {
426
    RubikObject obj = getObject(mObject);
427
    if( obj!=null ) editor.putString("rol_objName", obj.getUpperName() );
428

    
429
    int numDownloaded = mDownloadedObjects.size();
430

    
431
    if( numDownloaded>0 )
432
      {
433
      StringBuilder downloadedObjects = new StringBuilder();
434

    
435
      for(int i=0; i<numDownloaded; i++)
436
        {
437
        if( i>0 ) downloadedObjects.append(',');
438

    
439
        DownloadedObject object = mDownloadedObjects.get(i);
440
        downloadedObjects.append(object.shortName);
441
        downloadedObjects.append(' ');
442
        downloadedObjects.append(object.numScrambles);
443
        downloadedObjects.append(' ');
444
        downloadedObjects.append(object.objectMinor);
445
        downloadedObjects.append(' ');
446
        downloadedObjects.append(object.extrasMinor);
447
        downloadedObjects.append(' ');
448
        downloadedObjects.append(object.icon   ? "1":"0");
449
        downloadedObjects.append(' ');
450
        downloadedObjects.append(object.object ? "1":"0");
451
        downloadedObjects.append(' ');
452
        downloadedObjects.append(object.extras ? "1":"0");
453
        downloadedObjects.append(' ');
454
        downloadedObjects.append(object.free ? "true":"false");
455
        }
456

    
457
      String objects = downloadedObjects.toString();
458
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "saving: "+objects);
459
      editor.putString("rol_downloaded", objects );
460
      }
461
    else
462
      {
463
      editor.putString("rol_downloaded", "" );
464
      }
465

    
466
    editor.putString("rol_freeSolved", mFreeSolvedObjects);
467
    editor.putString("rol_freeBought", mFreeBoughtObjects);
468

    
469
    if( SHOW_SOLVED_DEBUG )
470
      {
471
      android.util.Log.e("D", "saving solved objects: "+mFreeSolvedObjects);
472
      android.util.Log.e("D", "saving bought objects: "+mFreeBoughtObjects);
473
      }
474
    }
475

    
476
///////////////////////////////////////////////////////////////////////////////////////////////////
477

    
478
  public static void restorePreferences(Context context, SharedPreferences preferences, boolean justStarted)
479
    {
480
    if( mThis==null ) mThis = new RubikObjectList();
481

    
482
    String downloaded = preferences.getString("rol_downloaded","");
483

    
484
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", downloaded);
485

    
486
    if( !downloaded.equals(""))
487
      {
488
      String[] dObjects = downloaded.split(",");
489

    
490
      for(String dObj : dObjects)
491
        {
492
        String[] parts = dObj.split(" ");
493
        int length = parts.length;
494

    
495
        if( length==7 || length==8 )
496
          {
497
          String name = parts[0];
498
          String scra = parts[1];
499
          String objM = parts[2];
500
          String extM = parts[3];
501
          String icon = parts[4];
502
          String obje = parts[5];
503
          String extr = parts[6];
504
          boolean isFree = (length==7 || Boolean.parseBoolean(parts[7]));
505

    
506
          int scrambles = Integer.parseInt(scra);
507
          int oMinor    = Integer.parseInt(objM);
508
          int eMinor    = Integer.parseInt(extM);
509

    
510
          boolean bIcon = icon.equals("1");
511
          boolean bObje = obje.equals("1");
512
          boolean bExtr = extr.equals("1");
513

    
514
          addDownloadedObject(context,name,scrambles,isFree,oMinor,eMinor,bIcon,bObje,bExtr);
515
          }
516
        }
517
      }
518

    
519
    RubikObject object = getObject(DEF_OBJECT);
520
    String defName = object==null ? "CUBE_3" : object.getUpperName();
521
    String objName= preferences.getString("rol_objName",defName);
522
    mObject = getOrdinal(objName);
523
    if( mObject<0 || mObject>=mNumObjects ) mObject = DEF_OBJECT;
524

    
525
    if( justStarted) restoreFreedObjects(preferences);
526
    }
527

    
528
///////////////////////////////////////////////////////////////////////////////////////////////////
529

    
530
  public static void restoreMeshState(SharedPreferences preferences)
531
    {
532
    for(int i=0; i<mNumObjects; i++)
533
      {
534
      RubikObject obj = getObject(i);
535

    
536
      if( obj!=null )
537
        {
538
        String name  = obj.getUpperName();
539
        int meshState= preferences.getInt("rol_"+name,MESH_NICE);
540
        obj.setMeshState(meshState);
541
        }
542
      }
543
    }
544

    
545
///////////////////////////////////////////////////////////////////////////////////////////////////
546

    
547
  public static void setObjectFreeState()
548
    {
549
    int numUnclaimed = getNumUnclaimedSolves();
550

    
551
    if( numUnclaimed>0 )
552
      {
553
      int marked = markAllSolvedAsFree();
554
      int stillUnclaimed = numUnclaimed-marked;
555
      if( stillUnclaimed>0) markAsFree(stillUnclaimed);
556
      }
557
    }
558

    
559
///////////////////////////////////////////////////////////////////////////////////////////////////
560

    
561
  public static boolean setCurrObject(int ordinal)
562
    {
563
    if( mObject!=ordinal )
564
      {
565
      mObject = ordinal;
566
      return true;
567
      }
568

    
569
    return false;
570
    }
571

    
572
///////////////////////////////////////////////////////////////////////////////////////////////////
573

    
574
  public static int getCurrObject()
575
    {
576
    return mObject;
577
    }
578

    
579
///////////////////////////////////////////////////////////////////////////////////////////////////
580

    
581
  public static String getCurrentName()
582
    {
583
    RubikObject object = mObjects.get(mObject);
584
    return object==null ? "" : object.getUpperName();
585
    }
586

    
587
///////////////////////////////////////////////////////////////////////////////////////////////////
588

    
589
  public static RubikObject getObject(int ordinal)
590
    {
591
    if( mThis==null ) mThis = new RubikObjectList();
592
    return ordinal>=0 && ordinal<mNumObjects ? mObjects.get(ordinal) : null;
593
    }
594

    
595
///////////////////////////////////////////////////////////////////////////////////////////////////
596

    
597
  public static RubikObject getObject(String shortUpperName)
598
    {
599
    if( mThis==null ) mThis = new RubikObjectList();
600

    
601
    for(int i=0; i<mNumObjects; i++)
602
      {
603
      RubikObject object = mObjects.get(i);
604
      if( object.getUpperName().equals(shortUpperName) )
605
        {
606
        return object;
607
        }
608
      }
609

    
610
    return null;
611
    }
612

    
613
///////////////////////////////////////////////////////////////////////////////////////////////////
614

    
615
  public static int getNumObjects()
616
    {
617
    if( mThis==null ) mThis = new RubikObjectList();
618
    return mNumObjects;
619
    }
620

    
621
///////////////////////////////////////////////////////////////////////////////////////////////////
622

    
623
  public static int getOrdinal(String name)
624
    {
625
    if( mThis==null ) mThis = new RubikObjectList();
626

    
627
    String lowerName = name.toLowerCase(Locale.ENGLISH);
628

    
629
    for(int i=0; i<mNumObjects; i++)
630
      {
631
      RubikObject obj = mObjects.get(i);
632
      if( obj.getLowerName().equals(lowerName) ) return i;
633
      }
634

    
635
    return -1;
636
    }
637

    
638
///////////////////////////////////////////////////////////////////////////////////////////////////
639

    
640
  public static int getNumExtrasObjects()
641
    {
642
    return mNumExtras;
643
    }
644

    
645
///////////////////////////////////////////////////////////////////////////////////////////////////
646

    
647
  public static int getNumTutorialObjects()
648
    {
649
    return mNumExtras;
650
    }
651

    
652
///////////////////////////////////////////////////////////////////////////////////////////////////
653

    
654
  public static int getObjectOrdinal(int extrasOrdinal)
655
    {
656
    for(int i=extrasOrdinal; i<mNumObjects; i++)
657
      {
658
      RubikObject object = getObject(i);
659
      int extOrd = object!=null ? object.getExtrasOrdinal() : -1;
660
      if( extOrd==extrasOrdinal ) return i;
661
      }
662

    
663
    return -1;
664
    }
665

    
666
///////////////////////////////////////////////////////////////////////////////////////////////////
667

    
668
  public static int getExtrasOrdinal(int objectOrdinal)
669
    {
670
    RubikObject object = getObject(objectOrdinal);
671
    return object!=null ? object.getExtrasOrdinal() : -1;
672
    }
673

    
674
///////////////////////////////////////////////////////////////////////////////////////////////////
675

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

    
682
///////////////////////////////////////////////////////////////////////////////////////////////////
683

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

    
690
///////////////////////////////////////////////////////////////////////////////////////////////////
691

    
692
  public static int getLocalExtrasMinor(int objectOrdinal)
693
    {
694
    RubikObject object = getObject(objectOrdinal);
695
    return object!=null ? object.getExtrasMinor() : -1;
696
    }
697
}
(2-2/2)