Project

General

Profile

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

magiccube / src / main / java / org / distorted / scores / RubikScores.java @ a4259b7f

1 f0e87514 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20
package org.distorted.scores;
21
22 82ce8e64 Leszek Koltunski
import android.content.Context;
23 f0e87514 Leszek Koltunski
import android.content.SharedPreferences;
24 82ce8e64 Leszek Koltunski
import android.telephony.TelephonyManager;
25 1c90c64a Leszek Koltunski
26 9c2f0c91 Leszek Koltunski
import org.distorted.objects.ObjectList;
27 f0e87514 Leszek Koltunski
28 82ce8e64 Leszek Koltunski
import java.util.UUID;
29
30 9c2f0c91 Leszek Koltunski
import static org.distorted.objects.ObjectList.MAX_NUM_OBJECTS;
31
import static org.distorted.objects.ObjectList.NUM_OBJECTS;
32
import static org.distorted.objects.ObjectList.MAX_LEVEL;
33 f0e87514 Leszek Koltunski
34
///////////////////////////////////////////////////////////////////////////////////////////////////
35 82ce8e64 Leszek Koltunski
// hold my own scores, and some other statistics.
36 f0e87514 Leszek Koltunski
37
public class RubikScores
38
  {
39 1c90c64a Leszek Koltunski
  public static final long NO_RECORD = Long.MAX_VALUE;
40 714292f1 Leszek Koltunski
  private static RubikScores mThis;
41
42 f0e87514 Leszek Koltunski
  private long[][][] mRecords;
43 286d73ae Leszek Koltunski
  private int [][][] mSubmitted;
44
45 82ce8e64 Leszek Koltunski
  private String mName, mCountry;
46 c3ffcf58 Leszek Koltunski
  private boolean mNameIsVerified;
47
  private int mNumRuns;
48
  private int mNumPlays;
49 e06e1b7e Leszek Koltunski
  private int mNumReviews;
50 82ce8e64 Leszek Koltunski
  private int mDeviceID;
51 f0e87514 Leszek Koltunski
52
///////////////////////////////////////////////////////////////////////////////////////////////////
53
54 714292f1 Leszek Koltunski
  private RubikScores()
55 f0e87514 Leszek Koltunski
    {
56 82d6e038 Leszek Koltunski
    mRecords   = new long[NUM_OBJECTS][MAX_NUM_OBJECTS][MAX_LEVEL];
57
    mSubmitted = new int [NUM_OBJECTS][MAX_NUM_OBJECTS][MAX_LEVEL];
58 f0e87514 Leszek Koltunski
59
    for(int i=0; i<NUM_OBJECTS; i++)
60 82d6e038 Leszek Koltunski
      for(int j=0; j<MAX_NUM_OBJECTS; j++)
61 85b09df4 Leszek Koltunski
        for(int k=0; k<MAX_LEVEL; k++)
62 f0e87514 Leszek Koltunski
          {
63 286d73ae Leszek Koltunski
          mRecords[i][j][k]   = NO_RECORD;
64
          mSubmitted[i][j][k] = 0;
65 f0e87514 Leszek Koltunski
          }
66 c3ffcf58 Leszek Koltunski
67 f895e77a Leszek Koltunski
    mName = "";
68 82ce8e64 Leszek Koltunski
    mCountry = "un";
69
70 c3ffcf58 Leszek Koltunski
    mNameIsVerified = false;
71 82ce8e64 Leszek Koltunski
72 e06e1b7e Leszek Koltunski
    mNumPlays   = -1;
73
    mNumRuns    = -1;
74
    mDeviceID   = -1;
75
    mNumReviews =  0;
76 f0e87514 Leszek Koltunski
    }
77
78 17f9a695 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
79
80
  private int privateGetDeviceID()
81
    {
82
    int id;
83
84
    try
85
      {
86
      String s = UUID.randomUUID().toString();
87 874c37b1 Leszek Koltunski
      id = s.hashCode();
88 17f9a695 Leszek Koltunski
      }
89
    catch(Exception ex)
90
      {
91
      id = 0;
92
      android.util.Log.e("scores", "Exception in getDeviceID()");
93
      }
94
95
    return id<0 ? -id : id;
96
    }
97
98
///////////////////////////////////////////////////////////////////////////////////////////////////
99 e06e1b7e Leszek Koltunski
100
  synchronized void successfulSubmit()
101
    {
102
    mNameIsVerified = true;
103
104
    for(int i=0; i<NUM_OBJECTS; i++)
105
      for(int j=0; j<MAX_NUM_OBJECTS; j++)
106
        for(int k=0; k<MAX_LEVEL; k++)
107
          {
108
          mSubmitted[i][j][k]=1;
109
          }
110
    }
111
112 714292f1 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
113
114 e06e1b7e Leszek Koltunski
  int getDeviceID()
115 714292f1 Leszek Koltunski
    {
116 e06e1b7e Leszek Koltunski
    return mDeviceID;
117
    }
118 714292f1 Leszek Koltunski
119 e06e1b7e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
120
121
  boolean isVerified()
122
    {
123
    return mNameIsVerified;
124 714292f1 Leszek Koltunski
    }
125
126 f0e87514 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
127
128 e06e1b7e Leszek Koltunski
  synchronized boolean thereAreUnsubmittedRecords()
129 f0e87514 Leszek Koltunski
    {
130 9c2f0c91 Leszek Koltunski
    ObjectList list;
131 f0e87514 Leszek Koltunski
    int length;
132
133 e06e1b7e Leszek Koltunski
    for(int object=0; object<NUM_OBJECTS; object++)
134 f0e87514 Leszek Koltunski
      {
135 e06e1b7e Leszek Koltunski
      list = ObjectList.getObject(object);
136
      length = list.getSizes().length;
137 f0e87514 Leszek Koltunski
138 e06e1b7e Leszek Koltunski
      for(int size=0; size<length; size++)
139
        for(int level=0; level<MAX_LEVEL; level++)
140 f0e87514 Leszek Koltunski
          {
141 e06e1b7e Leszek Koltunski
          if( mSubmitted[object][size][level]==0 && mRecords[object][size][level]<NO_RECORD )
142
            {
143
            return true;
144
            }
145 f0e87514 Leszek Koltunski
          }
146
      }
147 c3ffcf58 Leszek Koltunski
148 e06e1b7e Leszek Koltunski
    return false;
149 f0e87514 Leszek Koltunski
    }
150
151
///////////////////////////////////////////////////////////////////////////////////////////////////
152
153 e06e1b7e Leszek Koltunski
  synchronized String getRecordList(String strObj, String strLvl, String strTim)
154 f0e87514 Leszek Koltunski
    {
155 e06e1b7e Leszek Koltunski
    ObjectList list;
156
    StringBuilder builderObj = new StringBuilder();
157
    StringBuilder builderLvl = new StringBuilder();
158
    StringBuilder builderTim = new StringBuilder();
159
    boolean first = true;
160
    int[] sizes;
161
    int length;
162 f0e87514 Leszek Koltunski
163 e06e1b7e Leszek Koltunski
    for(int object=0; object<NUM_OBJECTS; object++)
164 f0e87514 Leszek Koltunski
      {
165 e06e1b7e Leszek Koltunski
      list = ObjectList.getObject(object);
166
      sizes = list.getSizes();
167
      length = sizes.length;
168 f0e87514 Leszek Koltunski
169 e06e1b7e Leszek Koltunski
      for(int size=0; size<length; size++)
170 f0e87514 Leszek Koltunski
        {
171 e06e1b7e Leszek Koltunski
        for(int level=0; level<MAX_LEVEL; level++)
172 f0e87514 Leszek Koltunski
          {
173 e06e1b7e Leszek Koltunski
          if( mSubmitted[object][size][level]==0 && mRecords[object][size][level]<NO_RECORD )
174 f0e87514 Leszek Koltunski
            {
175 e06e1b7e Leszek Koltunski
            if( !first )
176 4c0cd600 Leszek Koltunski
              {
177 e06e1b7e Leszek Koltunski
              builderObj.append(',');
178
              builderLvl.append(',');
179
              builderTim.append(',');
180 4c0cd600 Leszek Koltunski
              }
181
            else
182 f0e87514 Leszek Koltunski
              {
183 e06e1b7e Leszek Koltunski
              first=false;
184 f0e87514 Leszek Koltunski
              }
185 e06e1b7e Leszek Koltunski
186
            builderObj.append(list.name());
187
            builderObj.append("_");
188
            builderObj.append(sizes[size]);
189
            builderLvl.append(level);
190
            builderTim.append(mRecords[object][size][level]);
191 f0e87514 Leszek Koltunski
            }
192
          }
193
        }
194
      }
195 c3ffcf58 Leszek Koltunski
196 e06e1b7e Leszek Koltunski
    return strObj+builderObj.toString()+strLvl+builderLvl.toString()+strTim+builderTim.toString();
197
    }
198 82ce8e64 Leszek Koltunski
199 e06e1b7e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
200
// Public API
201
///////////////////////////////////////////////////////////////////////////////////////////////////
202
203
  public synchronized long getRecord(int object, int size, int level)
204
    {
205
    int maxsize = ObjectList.getObject(object).getSizes().length;
206
207
    if( object>=0 && object<NUM_OBJECTS && size>=0 && size<maxsize && level>=0 && level<MAX_LEVEL )
208
      {
209
      return mRecords[object][size][level];
210
      }
211
212
    return -1;
213 f0e87514 Leszek Koltunski
    }
214
215
///////////////////////////////////////////////////////////////////////////////////////////////////
216
217 e06e1b7e Leszek Koltunski
  public synchronized boolean isSubmitted(int object, int size, int level)
218 f0e87514 Leszek Koltunski
    {
219 9c2f0c91 Leszek Koltunski
    int maxsize = ObjectList.getObject(object).getSizes().length;
220 f0e87514 Leszek Koltunski
221 e06e1b7e Leszek Koltunski
    if( object>=0 && object<NUM_OBJECTS && size>=0 && size<maxsize && level>=0 && level<MAX_LEVEL )
222 f0e87514 Leszek Koltunski
      {
223 e06e1b7e Leszek Koltunski
      return mSubmitted[object][size][level]==1;
224 f0e87514 Leszek Koltunski
      }
225 e41e7dc3 Leszek Koltunski
226
    return false;
227 f0e87514 Leszek Koltunski
    }
228 714292f1 Leszek Koltunski
229 c3ffcf58 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
230
231 e06e1b7e Leszek Koltunski
  public int getNumPlays()
232 c3ffcf58 Leszek Koltunski
    {
233 e06e1b7e Leszek Koltunski
    return mNumPlays;
234 c3ffcf58 Leszek Koltunski
    }
235
236
///////////////////////////////////////////////////////////////////////////////////////////////////
237
238 e06e1b7e Leszek Koltunski
  public int getNumRuns()
239 c3ffcf58 Leszek Koltunski
    {
240 e06e1b7e Leszek Koltunski
    return mNumRuns;
241 c3ffcf58 Leszek Koltunski
    }
242
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244
245 e06e1b7e Leszek Koltunski
  public int getNumReviews()
246 c3ffcf58 Leszek Koltunski
    {
247 e06e1b7e Leszek Koltunski
    return mNumReviews;
248 c3ffcf58 Leszek Koltunski
    }
249
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251
252 e06e1b7e Leszek Koltunski
  public String getName()
253 c3ffcf58 Leszek Koltunski
    {
254 e06e1b7e Leszek Koltunski
    return mName;
255
    }
256 1c90c64a Leszek Koltunski
257 e06e1b7e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
258
259
  public String getCountry()
260
    {
261
    return mCountry;
262 1c90c64a Leszek Koltunski
    }
263
264 286d73ae Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
265
266 e06e1b7e Leszek Koltunski
  public void incrementNumPlays()
267 286d73ae Leszek Koltunski
    {
268 e06e1b7e Leszek Koltunski
    mNumPlays++;
269
    }
270 286d73ae Leszek Koltunski
271 e06e1b7e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
272 82ce8e64 Leszek Koltunski
273 e06e1b7e Leszek Koltunski
  public void incrementNumRuns()
274
    {
275
    mNumRuns++;
276
    }
277 82ce8e64 Leszek Koltunski
278 e06e1b7e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
279 82ce8e64 Leszek Koltunski
280 e06e1b7e Leszek Koltunski
  public void incrementNumReviews()
281
    {
282
    mNumReviews++;
283
    }
284
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286
287
  public void setName(String newName)
288
    {
289
    mName = newName;
290 82ce8e64 Leszek Koltunski
    }
291
292 874c37b1 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
293
294
  public void setCountry(String country)
295
    {
296
    mCountry = country;
297
298
    if( mCountry.equals("do") ) mCountry = "dm";  // see above
299
    }
300
301 d7e539d0 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
302
303 6570171b Leszek Koltunski
  public synchronized boolean isSolved(int object, int size, int level)
304 d7e539d0 Leszek Koltunski
    {
305 9c2f0c91 Leszek Koltunski
    int maxsize = ObjectList.getObject(object).getSizes().length;
306 d7e539d0 Leszek Koltunski
307
    if( object>=0 && object<NUM_OBJECTS && size>=0 && size<maxsize && level>=0 && level<MAX_LEVEL )
308
      {
309
      return mRecords[object][size][level]<NO_RECORD;
310
      }
311
312
    return false;
313
    }
314
315 714292f1 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
316
317 e06e1b7e Leszek Koltunski
  public void setCountry(Context context)
318 714292f1 Leszek Koltunski
    {
319 e06e1b7e Leszek Koltunski
    TelephonyManager tM =((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE));
320 714292f1 Leszek Koltunski
321 e06e1b7e Leszek Koltunski
    if( tM!=null )
322 714292f1 Leszek Koltunski
      {
323 e06e1b7e Leszek Koltunski
      mCountry = tM.getSimCountryIso();
324
325
      if( mCountry==null || mCountry.length()<=1 )
326
        {
327
        mCountry = tM.getNetworkCountryIso();
328
        }
329 714292f1 Leszek Koltunski
      }
330
331 e06e1b7e Leszek Koltunski
    // Special case: Dominicana. Its ISO-3166-alpha-2 country code is 'do' which we can't have here
332
    // because we later on map this to a resource name (the flag) and 'do' is a reserved Java keyword
333
    // and can't be a resource name.
334
335
    if( mCountry.equals("do") ) mCountry = "dm";
336 714292f1 Leszek Koltunski
    }
337 c3ffcf58 Leszek Koltunski
338 286d73ae Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
339
340 e06e1b7e Leszek Koltunski
  public static RubikScores getInstance()
341 286d73ae Leszek Koltunski
    {
342 e06e1b7e Leszek Koltunski
    if( mThis==null )
343 286d73ae Leszek Koltunski
      {
344 e06e1b7e Leszek Koltunski
      mThis = new RubikScores();
345 286d73ae Leszek Koltunski
      }
346
347 e06e1b7e Leszek Koltunski
    return mThis;
348 286d73ae Leszek Koltunski
    }
349
350 17f9a695 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
351
352 e06e1b7e Leszek Koltunski
  public synchronized void savePreferences(SharedPreferences.Editor editor)
353 17f9a695 Leszek Koltunski
    {
354 e06e1b7e Leszek Koltunski
    StringBuilder builder = new StringBuilder();
355
    ObjectList list;
356
    int[] sizes;
357
    int length;
358 1c90c64a Leszek Koltunski
359 e06e1b7e Leszek Koltunski
    for(int level=0; level<MAX_LEVEL; level++)
360
      {
361
      builder.setLength(0);
362 1c90c64a Leszek Koltunski
363 e06e1b7e Leszek Koltunski
      for(int object=0; object<NUM_OBJECTS; object++)
364
        {
365
        list = ObjectList.getObject(object);
366
        sizes = list.getSizes();
367
        length = sizes.length;
368 c3ffcf58 Leszek Koltunski
369 e06e1b7e Leszek Koltunski
        for(int size=0; size<length; size++)
370
          {
371
          builder.append(list.name());
372
          builder.append("_");
373
          builder.append(sizes[size]);
374
          builder.append("=");
375
          builder.append(mRecords[object][size][level]);
376
          builder.append(",");
377
          builder.append(mSubmitted[object][size][level]);
378
          builder.append(" ");
379
          }
380
        }
381 c3ffcf58 Leszek Koltunski
382 e06e1b7e Leszek Koltunski
      editor.putString("scores_record"+level, builder.toString());
383
      }
384 c3ffcf58 Leszek Koltunski
385 e06e1b7e Leszek Koltunski
    editor.putString("scores_name"  , mName  );
386
    editor.putBoolean("scores_isVerified", mNameIsVerified);
387
    editor.putInt("scores_numPlays", mNumPlays);
388
    editor.putInt("scores_numRuns" , mNumRuns);
389
    editor.putInt("scores_deviceid", mDeviceID);
390
    editor.putInt("scores_review"  , mNumReviews);
391 c3ffcf58 Leszek Koltunski
    }
392
393
///////////////////////////////////////////////////////////////////////////////////////////////////
394
395 e06e1b7e Leszek Koltunski
  public synchronized void restorePreferences(SharedPreferences preferences)
396 c3ffcf58 Leszek Koltunski
    {
397 e06e1b7e Leszek Koltunski
    String recordStr, subStr, nameStr, sizeStr, timeStr, submStr;
398
    int start, end, equals, underscore, comma;
399
    int object, sizeIndex, subm;
400
    long time;
401 c3ffcf58 Leszek Koltunski
402 e06e1b7e Leszek Koltunski
    for(int level=0; level<MAX_LEVEL; level++)
403
      {
404
      start = end = 0;
405
      recordStr = preferences.getString("scores_record"+level, "");
406 c3ffcf58 Leszek Koltunski
407 e06e1b7e Leszek Koltunski
      while( end!=-1 )
408
        {
409
        end = recordStr.indexOf(" ", start);
410 4895fff6 Leszek Koltunski
411 e06e1b7e Leszek Koltunski
        if( end==-1 ) subStr = recordStr.substring(start);
412
        else          subStr = recordStr.substring(start,end);
413 4895fff6 Leszek Koltunski
414 e06e1b7e Leszek Koltunski
        start = end+1;
415 4895fff6 Leszek Koltunski
416 e06e1b7e Leszek Koltunski
        underscore = subStr.indexOf("_");
417
        equals = subStr.indexOf("=");
418
        comma = subStr.indexOf(",");
419 4895fff6 Leszek Koltunski
420 e06e1b7e Leszek Koltunski
        if( underscore>=0 && equals>=0 && comma>=0 )
421 4c0cd600 Leszek Koltunski
          {
422 e06e1b7e Leszek Koltunski
          nameStr = subStr.substring(0,underscore);
423
          sizeStr = subStr.substring(underscore+1, equals);
424
          timeStr = subStr.substring(equals+1,comma);
425
          submStr = subStr.substring(comma+1);
426
427
          object = ObjectList.getOrdinal(nameStr);
428
429
          if( object>=0 && object< NUM_OBJECTS )
430 4895fff6 Leszek Koltunski
            {
431 e06e1b7e Leszek Koltunski
            sizeIndex = ObjectList.getSizeIndex(object,Integer.parseInt(sizeStr));
432
            time = Long.parseLong(timeStr);
433
            subm = Integer.parseInt(submStr);
434
435
            if( sizeIndex>=0 && sizeIndex<MAX_NUM_OBJECTS && subm>=0 && subm<=1 )
436
              {
437
              mRecords  [object][sizeIndex][level] = time;
438
              mSubmitted[object][sizeIndex][level] = subm;
439
              }
440
            else
441
              {
442
              android.util.Log.e("scores", "error: size="+sizeIndex+" subm="+subm);
443
              }
444
            }
445
          else
446
            {
447
            android.util.Log.e("scores", "error: object="+object);
448 4895fff6 Leszek Koltunski
            }
449 4c0cd600 Leszek Koltunski
          }
450 e06e1b7e Leszek Koltunski
        }
451 4895fff6 Leszek Koltunski
      }
452
453 e06e1b7e Leszek Koltunski
    mName           = preferences.getString("scores_name"  , "" );
454
    mNameIsVerified = preferences.getBoolean("scores_isVerified", false);
455
    mNumPlays       = preferences.getInt("scores_numPlays", 0);
456
    mNumRuns        = preferences.getInt("scores_numRuns" , 0);
457
    mDeviceID       = preferences.getInt("scores_deviceid",-1);
458 a4259b7f Leszek Koltunski
    mNumReviews     = preferences.getInt("scores_review"  ,-3);
459 e06e1b7e Leszek Koltunski
460
    if( mDeviceID==-1 ) mDeviceID = privateGetDeviceID();
461 4895fff6 Leszek Koltunski
    }
462
463
///////////////////////////////////////////////////////////////////////////////////////////////////
464
465 e06e1b7e Leszek Koltunski
  public synchronized boolean setRecord(int object, int size, int level, long timeTaken)
466 4895fff6 Leszek Koltunski
    {
467 e06e1b7e Leszek Koltunski
    int maxsize = ObjectList.getObject(object).getSizes().length;
468 4895fff6 Leszek Koltunski
469 e06e1b7e Leszek Koltunski
    if( object>=0 && object<NUM_OBJECTS && size>=0 && size<maxsize && level>=1 && level<=MAX_LEVEL )
470 6570171b Leszek Koltunski
      {
471 e06e1b7e Leszek Koltunski
      if( mRecords[object][size][level-1]> timeTaken )
472 6570171b Leszek Koltunski
        {
473 e06e1b7e Leszek Koltunski
        mRecords  [object][size][level-1] = timeTaken;
474
        mSubmitted[object][size][level-1] = 0;
475
        return true;
476 6570171b Leszek Koltunski
        }
477
      }
478 4895fff6 Leszek Koltunski
479 e06e1b7e Leszek Koltunski
    return false;
480 4895fff6 Leszek Koltunski
    }
481 f0e87514 Leszek Koltunski
  }