Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / RubikObjectList.java @ 0b5e585c

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.main.RubikActivity;
20
import org.distorted.objectlib.json.JsonReader;
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

    
28
///////////////////////////////////////////////////////////////////////////////////////////////////
29

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

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

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

    
50
      numScrambles= scrambles;
51
      difficulty  = diff;
52
      objectMinor = oMinor;
53
      extrasMinor = eMinor;
54

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

    
61
  private static ArrayList<DownloadedObject> mDownloadedObjects;
62
  private static int[][] mDifficultyOrdinals;
63

    
64
///////////////////////////////////////////////////////////////////////////////////////////////////
65

    
66
  private RubikObjectList()
67
    {
68
    mNumObjects= 0;
69
    mNumExtras = 0;
70

    
71
    mObjects           = new ArrayList<>();
72
    mDownloadedObjects = new ArrayList<>();
73

    
74
    createBuiltinObjects();
75
    }
76

    
77
///////////////////////////////////////////////////////////////////////////////////////////////////
78

    
79
  private void createBuiltinObjects()
80
    {
81
    for(int i=0; i<NUM_OBJECTS; i++)
82
      {
83
      ObjectType type = ObjectType.getObject(i);
84
      RubikObject obj = new RubikObject(type);
85
      mObjects.add(obj);
86
      mNumObjects++;
87

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

    
90
      if( obj.hasExtras() )
91
        {
92
        if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "has extras "+mNumExtras );
93

    
94
        obj.setExtrasOrdinal(mNumExtras);
95
        mNumExtras++;
96
        }
97
      else
98
        {
99
        if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "no extras");
100
        }
101
      }
102
    }
103

    
104
///////////////////////////////////////////////////////////////////////////////////////////////////
105

    
106
  private static boolean internalAddDownloadedObject(DownloadedObject object)
107
    {
108
    String name = object.shortName;
109

    
110
    for(RubikObject ro : mObjects )
111
      if( ro.getLowerName().equals(name) )
112
        {
113
        return ro.updateObject(object);
114
        }
115

    
116
    RubikObject obj = new RubikObject(object);
117
    mObjects.add(obj);
118
    mNumObjects++;
119

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

    
122
    if( obj.hasExtras() )
123
      {
124
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "has extras "+mNumExtras );
125

    
126
      obj.setExtrasOrdinal(mNumExtras);
127
      mNumExtras++;
128
      }
129
    else
130
      {
131
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "no extras");
132
      }
133

    
134
    return true;
135
    }
136

    
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138

    
139
  private static void createDifficultyList(int difficulty)
140
    {
141
    int num=0;
142

    
143
    for(int i=0; i<mNumObjects; i++)
144
      {
145
      RubikObject object = mObjects.get(i);
146
      if( object.getDifficulty()==difficulty ) num++;
147
      }
148

    
149
    if( num>0 )
150
      {
151
      mDifficultyOrdinals[difficulty] = new int[num];
152
      num=0;
153

    
154
      for(int i=0; i<mNumObjects; i++)
155
        {
156
        RubikObject object = mObjects.get(i);
157
        if( object.getDifficulty()==difficulty )
158
          {
159
          mDifficultyOrdinals[difficulty][num] = i;
160
          num++;
161
          }
162
        }
163
      }
164
    }
165

    
166
///////////////////////////////////////////////////////////////////////////////////////////////////
167

    
168
  private static int figureOutDifficulty(Context context, String objectName)
169
    {
170
    JsonReader reader = JsonReader.getInstance();
171

    
172
    try
173
      {
174
      reader.readNumScramblesAndComplexity(context,objectName);
175
      return reader.getComplexity();
176
      }
177
    catch(Exception ex)
178
      {
179
      android.util.Log.e("D", "exception "+ex.getMessage()+" trying to read complexity of a puzzle "+objectName);
180
      return 0;
181
      }
182
    }
183

    
184
///////////////////////////////////////////////////////////////////////////////////////////////////
185
// PUBLIC API
186

    
187
  public static boolean addDownloadedObject(Context context, String shortName, int numScrambles, int difficulty, int objectMinor,
188
                                         int extrasMinor, boolean icon, boolean object, boolean extras)
189
    {
190
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "New downloaded object "+shortName+" icon="+icon+" object="+object+" extras="+extras);
191

    
192
    for( DownloadedObject obj : mDownloadedObjects )
193
      {
194
      if( obj.shortName.equals(shortName) )
195
        {
196
        obj.icon  |= icon;
197
        obj.object|= object;
198
        obj.extras|= extras;
199

    
200
        if( !obj.object ) objectMinor=-1;
201
        if( !obj.extras ) extrasMinor=-1;
202

    
203
        obj.objectMinor = objectMinor;
204
        obj.extrasMinor = extrasMinor;
205

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

    
208
        try
209
          {
210
          RubikActivity ract = (RubikActivity)context;
211
          ract.reloadObject(shortName);
212
          }
213
        catch(Exception ex)
214
          {
215
          android.util.Log.e("D", "exception trying to reload object: "+ex.getMessage() );
216
          }
217

    
218
        return false;
219
        }
220
      }
221

    
222
    if( !object ) objectMinor=-1;
223
    if( !extras ) extrasMinor=-1;
224

    
225
    DownloadedObject obj = new DownloadedObject(shortName,numScrambles,difficulty,objectMinor,extrasMinor,icon,object,extras);
226
    if ( internalAddDownloadedObject(obj) )
227
      {
228
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "Adding new downloaded object "+shortName+" icon="+obj.icon+" object="+obj.object+" extras="+obj.extras);
229
      mDownloadedObjects.add(obj);
230
      return true;
231
      }
232
    else
233
      {
234
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "New downloaded object "+shortName+" is already built-in, deleting");
235
      RubikFiles files = RubikFiles.getInstance();
236
      files.deleteIcon(context,shortName);
237
      files.deleteJsonObject(context,shortName);
238
      files.deleteJsonExtras(context,shortName);
239
      return false;
240
      }
241
    }
242

    
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244

    
245
  public static void setMeshState(int ordinal, int state)
246
    {
247
    if( ordinal>=0 && ordinal<mNumObjects ) mObjects.get(ordinal).setMeshState(state);
248
    }
249

    
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251

    
252
  public static int getMeshState(int ordinal)
253
    {
254
    return (ordinal>=0 && ordinal<mNumObjects) ? mObjects.get(ordinal).getMeshState() : MESH_NICE;
255
    }
256

    
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258

    
259
  public static void savePreferences(SharedPreferences.Editor editor)
260
    {
261
    RubikObject obj = getObject(mObject);
262
    if( obj!=null ) editor.putString("rol_objName", obj.getUpperName() );
263

    
264
    int numDownloaded = mDownloadedObjects.size();
265

    
266
    if( numDownloaded>0 )
267
      {
268
      StringBuilder downloadedObjects = new StringBuilder();
269

    
270
      for(int i=0; i<numDownloaded; i++)
271
        {
272
        if( i>0 ) downloadedObjects.append(',');
273

    
274
        DownloadedObject object = mDownloadedObjects.get(i);
275
        downloadedObjects.append(object.shortName);
276
        downloadedObjects.append(' ');
277
        downloadedObjects.append(object.numScrambles);
278
        downloadedObjects.append(' ');
279
        downloadedObjects.append(object.objectMinor);
280
        downloadedObjects.append(' ');
281
        downloadedObjects.append(object.extrasMinor);
282
        downloadedObjects.append(' ');
283
        downloadedObjects.append(object.icon   ? "1":"0");
284
        downloadedObjects.append(' ');
285
        downloadedObjects.append(object.object ? "1":"0");
286
        downloadedObjects.append(' ');
287
        downloadedObjects.append(object.extras ? "1":"0");
288
        downloadedObjects.append(' ');
289
        downloadedObjects.append(object.difficulty);
290
        }
291

    
292
      String objects = downloadedObjects.toString();
293
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "saving: "+objects);
294
      editor.putString("rol_downloaded", objects );
295
      }
296
    else
297
      {
298
      editor.putString("rol_downloaded", "" );
299
      }
300
    }
301

    
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303

    
304
  public static void saveMeshState(SharedPreferences.Editor editor)
305
    {
306
    for(int i=0; i<mNumObjects; i++)
307
      {
308
      RubikObject obj = getObject(i);
309

    
310
      if( obj!=null )
311
        {
312
        String name = obj.getUpperName();
313
        editor.putInt("rol_"+name, obj.getMeshState() );
314
        }
315
      }
316
    }
317

    
318
///////////////////////////////////////////////////////////////////////////////////////////////////
319

    
320
  public static void restorePreferences(Context context, SharedPreferences preferences)
321
    {
322
    if( mThis==null ) mThis = new RubikObjectList();
323

    
324
    String downloaded = preferences.getString("rol_downloaded","");
325

    
326
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", downloaded);
327

    
328
    if( !downloaded.equals(""))
329
      {
330
      String[] dObjects = downloaded.split(",");
331

    
332
      for(String dObj : dObjects)
333
        {
334
        String[] parts = dObj.split(" ");
335

    
336
        if( parts.length==7 || parts.length==8 )
337
          {
338
          String name = parts[0];
339
          String scra = parts[1];
340
          String objM = parts[2];
341
          String extM = parts[3];
342
          String icon = parts[4];
343
          String obje = parts[5];
344
          String extr = parts[6];
345

    
346
          int difficulty= parts.length==7 ? figureOutDifficulty(context,name) : Integer.parseInt(parts[7]);
347
          int scrambles = Integer.parseInt(scra);
348
          int oMinor    = Integer.parseInt(objM);
349
          int eMinor    = Integer.parseInt(extM);
350

    
351
          boolean bIcon = icon.equals("1");
352
          boolean bObje = obje.equals("1");
353
          boolean bExtr = extr.equals("1");
354

    
355
          addDownloadedObject(context,name,scrambles,difficulty,oMinor,eMinor,bIcon,bObje,bExtr);
356
          }
357
        }
358
      }
359

    
360
    RubikObject object = getObject(DEF_OBJECT);
361
    String defName = object==null ? "CUBE_3" : object.getUpperName();
362
    String objName= preferences.getString("rol_objName",defName);
363
    mObject = getOrdinal(objName);
364
    if( mObject<0 || mObject>=mNumObjects ) mObject = DEF_OBJECT;
365
    }
366

    
367
///////////////////////////////////////////////////////////////////////////////////////////////////
368

    
369
  public static void restoreMeshState(SharedPreferences preferences)
370
    {
371
    for(int i=0; i<mNumObjects; i++)
372
      {
373
      RubikObject obj = getObject(i);
374

    
375
      if( obj!=null )
376
        {
377
        String name  = obj.getUpperName();
378
        int meshState= preferences.getInt("rol_"+name,MESH_NICE);
379
        obj.setMeshState(meshState);
380
        }
381
      }
382
    }
383

    
384
///////////////////////////////////////////////////////////////////////////////////////////////////
385

    
386
  public static boolean setCurrObject(int ordinal)
387
    {
388
    if( mObject!=ordinal )
389
      {
390
      mObject = ordinal;
391
      return true;
392
      }
393

    
394
    return false;
395
    }
396

    
397
///////////////////////////////////////////////////////////////////////////////////////////////////
398

    
399
  public static int getCurrObject()
400
    {
401
    return mObject;
402
    }
403

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

    
406
  public static String getCurrentName()
407
    {
408
    RubikObject object = mObjects.get(mObject);
409
    return object==null ? "" : object.getUpperName();
410
    }
411

    
412
///////////////////////////////////////////////////////////////////////////////////////////////////
413

    
414
  public static RubikObject getObject(int ordinal)
415
    {
416
    if( mThis==null ) mThis = new RubikObjectList();
417
    return ordinal>=0 && ordinal<mNumObjects ? mObjects.get(ordinal) : null;
418
    }
419

    
420
///////////////////////////////////////////////////////////////////////////////////////////////////
421

    
422
  public static RubikObject getObject(String shortUpperName)
423
    {
424
    if( mThis==null ) mThis = new RubikObjectList();
425

    
426
    for(int i=0; i<mNumObjects; i++)
427
      {
428
      RubikObject object = mObjects.get(i);
429
      if( object.getUpperName().equals(shortUpperName) )
430
        {
431
        return object;
432
        }
433
      }
434

    
435
    return null;
436
    }
437

    
438
///////////////////////////////////////////////////////////////////////////////////////////////////
439

    
440
  public static int getNumObjects()
441
    {
442
    if( mThis==null ) mThis = new RubikObjectList();
443
    return mNumObjects;
444
    }
445

    
446
///////////////////////////////////////////////////////////////////////////////////////////////////
447

    
448
  public static int getOrdinal(String name)
449
    {
450
    if( mThis==null ) mThis = new RubikObjectList();
451

    
452
    String lowerName = name.toLowerCase(Locale.ENGLISH);
453

    
454
    for(int i=0; i<mNumObjects; i++)
455
      {
456
      RubikObject obj = mObjects.get(i);
457
      if( obj.getLowerName().equals(lowerName) ) return i;
458
      }
459

    
460
    return -1;
461
    }
462

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

    
465
  public static int getNumExtrasObjects()
466
    {
467
    return mNumExtras;
468
    }
469

    
470
///////////////////////////////////////////////////////////////////////////////////////////////////
471

    
472
  public static int getNumTutorialObjects()
473
    {
474
    return mNumExtras;
475
    }
476

    
477
///////////////////////////////////////////////////////////////////////////////////////////////////
478

    
479
  public static int getObjectOrdinal(int extrasOrdinal)
480
    {
481
    for(int i=extrasOrdinal; i<mNumObjects; i++)
482
      {
483
      RubikObject object = getObject(i);
484
      int extOrd = object!=null ? object.getExtrasOrdinal() : -1;
485
      if( extOrd==extrasOrdinal ) return i;
486
      }
487

    
488
    return -1;
489
    }
490

    
491
///////////////////////////////////////////////////////////////////////////////////////////////////
492

    
493
  public static int getExtrasOrdinal(int objectOrdinal)
494
    {
495
    RubikObject object = getObject(objectOrdinal);
496
    return object!=null ? object.getExtrasOrdinal() : -1;
497
    }
498

    
499
///////////////////////////////////////////////////////////////////////////////////////////////////
500

    
501
  public static int getTutorialOrdinal(int objectOrdinal)
502
    {
503
    RubikObject object = getObject(objectOrdinal);
504
    return object!=null ? object.getExtrasOrdinal() : -1;
505
    }
506

    
507
///////////////////////////////////////////////////////////////////////////////////////////////////
508

    
509
  public static int getLocalObjectMinor(int objectOrdinal)
510
    {
511
    RubikObject object = getObject(objectOrdinal);
512
    return object!=null ? object.getObjectMinor() : -1;
513
    }
514

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

    
517
  public static int getLocalExtrasMinor(int objectOrdinal)
518
    {
519
    RubikObject object = getObject(objectOrdinal);
520
    return object!=null ? object.getExtrasMinor() : -1;
521
    }
522

    
523
///////////////////////////////////////////////////////////////////////////////////////////////////
524

    
525
  public static int[] produceListOfOrdinals(int difficulty)
526
    {
527
    if( mDifficultyOrdinals==null )
528
      {
529
      mDifficultyOrdinals = new int[NUM_DIFFICULTIES][];
530
      }
531

    
532
    if( difficulty>=0 && difficulty<NUM_DIFFICULTIES )
533
      {
534
      if( mDifficultyOrdinals[difficulty]==null ) createDifficultyList(difficulty);
535
      }
536

    
537
    return mDifficultyOrdinals[difficulty];
538
    }
539

    
540
}
(2-2/2)