Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / RubikObjectList.java @ 6142069a

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 objectAlreadyBought(String shortName)
364
    {
365
    RubikObject o = getObject(shortName);
366
    return ( o!=null && o.isFree() );
367
    }
368

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

    
371
  public static void buyAll()
372
    {
373
    mFreeBoughtObjects = "*";
374
    if( SHOW_SOLVED_DEBUG ) android.util.Log.e("D", "all objects marked as bought");
375

    
376
    for(int i=0; i<mNumObjects; i++)
377
      {
378
      RubikObject o = mObjects.get(i);
379
      o.markFree();
380
      }
381
    }
382

    
383
///////////////////////////////////////////////////////////////////////////////////////////////////
384

    
385
  public static boolean buyObject(String shortName)
386
    {
387
    RubikObject o = getObject(shortName);
388

    
389
    if( o!=null && !o.isFree() )
390
      {
391
      if( SHOW_SOLVED_DEBUG ) android.util.Log.e("D", "object "+shortName+" marked as bought");
392
      o.markFree();
393
      String add = mFreeBoughtObjects.length()==0 ? shortName : (","+shortName);
394
      mFreeBoughtObjects += add;
395
      return true;
396
      }
397

    
398
    return false;
399
    }
400

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

    
403
  public static boolean solveObject(String shortName)
404
    {
405
    RubikObject object = getObject(shortName);
406
    return solveObject(object,shortName);
407
    }
408

    
409
///////////////////////////////////////////////////////////////////////////////////////////////////
410

    
411
  public static void savePreferences(SharedPreferences.Editor editor)
412
    {
413
    RubikObject obj = getObject(mObject);
414
    if( obj!=null ) editor.putString("rol_objName", obj.getUpperName() );
415

    
416
    int numDownloaded = mDownloadedObjects.size();
417

    
418
    if( numDownloaded>0 )
419
      {
420
      StringBuilder downloadedObjects = new StringBuilder();
421

    
422
      for(int i=0; i<numDownloaded; i++)
423
        {
424
        if( i>0 ) downloadedObjects.append(',');
425

    
426
        DownloadedObject object = mDownloadedObjects.get(i);
427
        downloadedObjects.append(object.shortName);
428
        downloadedObjects.append(' ');
429
        downloadedObjects.append(object.numScrambles);
430
        downloadedObjects.append(' ');
431
        downloadedObjects.append(object.objectMinor);
432
        downloadedObjects.append(' ');
433
        downloadedObjects.append(object.extrasMinor);
434
        downloadedObjects.append(' ');
435
        downloadedObjects.append(object.icon   ? "1":"0");
436
        downloadedObjects.append(' ');
437
        downloadedObjects.append(object.object ? "1":"0");
438
        downloadedObjects.append(' ');
439
        downloadedObjects.append(object.extras ? "1":"0");
440
        downloadedObjects.append(' ');
441
        downloadedObjects.append(object.free ? "true":"false");
442
        }
443

    
444
      String objects = downloadedObjects.toString();
445
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "saving: "+objects);
446
      editor.putString("rol_downloaded", objects );
447
      }
448
    else
449
      {
450
      editor.putString("rol_downloaded", "" );
451
      }
452

    
453
    editor.putString("rol_freeSolved", mFreeSolvedObjects);
454
    editor.putString("rol_freeBought", mFreeBoughtObjects);
455

    
456
    if( SHOW_SOLVED_DEBUG )
457
      {
458
      android.util.Log.e("D", "saving solved objects: "+mFreeSolvedObjects);
459
      android.util.Log.e("D", "saving bought objects: "+mFreeBoughtObjects);
460
      }
461
    }
462

    
463
///////////////////////////////////////////////////////////////////////////////////////////////////
464

    
465
  public static void restorePreferences(Context context, SharedPreferences preferences, boolean justStarted)
466
    {
467
    if( mThis==null ) mThis = new RubikObjectList();
468

    
469
    String downloaded = preferences.getString("rol_downloaded","");
470

    
471
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", downloaded);
472

    
473
    if( !downloaded.equals(""))
474
      {
475
      String[] dObjects = downloaded.split(",");
476

    
477
      for(String dObj : dObjects)
478
        {
479
        String[] parts = dObj.split(" ");
480
        int length = parts.length;
481

    
482
        if( length==7 || length==8 )
483
          {
484
          String name = parts[0];
485
          String scra = parts[1];
486
          String objM = parts[2];
487
          String extM = parts[3];
488
          String icon = parts[4];
489
          String obje = parts[5];
490
          String extr = parts[6];
491
          boolean isFree = (length==7 || Boolean.parseBoolean(parts[7]));
492

    
493
          int scrambles = Integer.parseInt(scra);
494
          int oMinor    = Integer.parseInt(objM);
495
          int eMinor    = Integer.parseInt(extM);
496

    
497
          boolean bIcon = icon.equals("1");
498
          boolean bObje = obje.equals("1");
499
          boolean bExtr = extr.equals("1");
500

    
501
          addDownloadedObject(context,name,scrambles,isFree,oMinor,eMinor,bIcon,bObje,bExtr);
502
          }
503
        }
504
      }
505

    
506
    RubikObject object = getObject(DEF_OBJECT);
507
    String defName = object==null ? "CUBE_3" : object.getUpperName();
508
    String objName= preferences.getString("rol_objName",defName);
509
    mObject = getOrdinal(objName);
510
    if( mObject<0 || mObject>=mNumObjects ) mObject = DEF_OBJECT;
511

    
512
    if( justStarted) restoreFreedObjects(preferences);
513
    }
514

    
515
///////////////////////////////////////////////////////////////////////////////////////////////////
516

    
517
  public static void restoreMeshState(SharedPreferences preferences)
518
    {
519
    for(int i=0; i<mNumObjects; i++)
520
      {
521
      RubikObject obj = getObject(i);
522

    
523
      if( obj!=null )
524
        {
525
        String name  = obj.getUpperName();
526
        int meshState= preferences.getInt("rol_"+name,MESH_NICE);
527
        obj.setMeshState(meshState);
528
        }
529
      }
530
    }
531

    
532
///////////////////////////////////////////////////////////////////////////////////////////////////
533

    
534
  public static void setObjectFreeState()
535
    {
536
    int numUnclaimed = getNumUnclaimedSolves();
537

    
538
    if( numUnclaimed>0 )
539
      {
540
      int marked = markAllSolvedAsFree();
541
      int stillUnclaimed = numUnclaimed-marked;
542
      if( stillUnclaimed>0) markAsFree(stillUnclaimed);
543
      }
544
    }
545

    
546
///////////////////////////////////////////////////////////////////////////////////////////////////
547

    
548
  public static boolean setCurrObject(int ordinal)
549
    {
550
    if( mObject!=ordinal )
551
      {
552
      mObject = ordinal;
553
      return true;
554
      }
555

    
556
    return false;
557
    }
558

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

    
561
  public static int getCurrObject()
562
    {
563
    return mObject;
564
    }
565

    
566
///////////////////////////////////////////////////////////////////////////////////////////////////
567

    
568
  public static String getCurrentName()
569
    {
570
    RubikObject object = mObjects.get(mObject);
571
    return object==null ? "" : object.getUpperName();
572
    }
573

    
574
///////////////////////////////////////////////////////////////////////////////////////////////////
575

    
576
  public static RubikObject getObject(int ordinal)
577
    {
578
    if( mThis==null ) mThis = new RubikObjectList();
579
    return ordinal>=0 && ordinal<mNumObjects ? mObjects.get(ordinal) : null;
580
    }
581

    
582
///////////////////////////////////////////////////////////////////////////////////////////////////
583

    
584
  public static RubikObject getObject(String shortUpperName)
585
    {
586
    if( mThis==null ) mThis = new RubikObjectList();
587

    
588
    for(int i=0; i<mNumObjects; i++)
589
      {
590
      RubikObject object = mObjects.get(i);
591
      if( object.getUpperName().equals(shortUpperName) )
592
        {
593
        return object;
594
        }
595
      }
596

    
597
    return null;
598
    }
599

    
600
///////////////////////////////////////////////////////////////////////////////////////////////////
601

    
602
  public static int getNumObjects()
603
    {
604
    if( mThis==null ) mThis = new RubikObjectList();
605
    return mNumObjects;
606
    }
607

    
608
///////////////////////////////////////////////////////////////////////////////////////////////////
609

    
610
  public static int getOrdinal(String name)
611
    {
612
    if( mThis==null ) mThis = new RubikObjectList();
613

    
614
    String lowerName = name.toLowerCase(Locale.ENGLISH);
615

    
616
    for(int i=0; i<mNumObjects; i++)
617
      {
618
      RubikObject obj = mObjects.get(i);
619
      if( obj.getLowerName().equals(lowerName) ) return i;
620
      }
621

    
622
    return -1;
623
    }
624

    
625
///////////////////////////////////////////////////////////////////////////////////////////////////
626

    
627
  public static int getNumExtrasObjects()
628
    {
629
    return mNumExtras;
630
    }
631

    
632
///////////////////////////////////////////////////////////////////////////////////////////////////
633

    
634
  public static int getNumTutorialObjects()
635
    {
636
    return mNumExtras;
637
    }
638

    
639
///////////////////////////////////////////////////////////////////////////////////////////////////
640

    
641
  public static int getObjectOrdinal(int extrasOrdinal)
642
    {
643
    for(int i=extrasOrdinal; i<mNumObjects; i++)
644
      {
645
      RubikObject object = getObject(i);
646
      int extOrd = object!=null ? object.getExtrasOrdinal() : -1;
647
      if( extOrd==extrasOrdinal ) return i;
648
      }
649

    
650
    return -1;
651
    }
652

    
653
///////////////////////////////////////////////////////////////////////////////////////////////////
654

    
655
  public static int getExtrasOrdinal(int objectOrdinal)
656
    {
657
    RubikObject object = getObject(objectOrdinal);
658
    return object!=null ? object.getExtrasOrdinal() : -1;
659
    }
660

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

    
663
  public static int getTutorialOrdinal(int objectOrdinal)
664
    {
665
    RubikObject object = getObject(objectOrdinal);
666
    return object!=null ? object.getExtrasOrdinal() : -1;
667
    }
668

    
669
///////////////////////////////////////////////////////////////////////////////////////////////////
670

    
671
  public static int getLocalObjectMinor(int objectOrdinal)
672
    {
673
    RubikObject object = getObject(objectOrdinal);
674
    return object!=null ? object.getObjectMinor() : -1;
675
    }
676

    
677
///////////////////////////////////////////////////////////////////////////////////////////////////
678

    
679
  public static int getLocalExtrasMinor(int objectOrdinal)
680
    {
681
    RubikObject object = getObject(objectOrdinal);
682
    return object!=null ? object.getExtrasMinor() : -1;
683
    }
684
}
(2-2/2)