Project

General

Profile

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

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

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 1f9772f3 Leszek Koltunski
import org.distorted.objects.RubikObjectList;
27 f0e87514 Leszek Koltunski
28 82ce8e64 Leszek Koltunski
import java.util.UUID;
29
30 82d6e038 Leszek Koltunski
import static org.distorted.objects.RubikObjectList.MAX_NUM_OBJECTS;
31 1f9772f3 Leszek Koltunski
import static org.distorted.objects.RubikObjectList.NUM_OBJECTS;
32 8e3898c8 Leszek Koltunski
import static org.distorted.objects.RubikObjectList.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 82ce8e64 Leszek Koltunski
  private int mDeviceID;
50 f0e87514 Leszek Koltunski
51
///////////////////////////////////////////////////////////////////////////////////////////////////
52
53 714292f1 Leszek Koltunski
  private RubikScores()
54 f0e87514 Leszek Koltunski
    {
55 82d6e038 Leszek Koltunski
    mRecords   = new long[NUM_OBJECTS][MAX_NUM_OBJECTS][MAX_LEVEL];
56
    mSubmitted = new int [NUM_OBJECTS][MAX_NUM_OBJECTS][MAX_LEVEL];
57 f0e87514 Leszek Koltunski
58
    for(int i=0; i<NUM_OBJECTS; i++)
59 82d6e038 Leszek Koltunski
      for(int j=0; j<MAX_NUM_OBJECTS; j++)
60 85b09df4 Leszek Koltunski
        for(int k=0; k<MAX_LEVEL; k++)
61 f0e87514 Leszek Koltunski
          {
62 286d73ae Leszek Koltunski
          mRecords[i][j][k]   = NO_RECORD;
63
          mSubmitted[i][j][k] = 0;
64 f0e87514 Leszek Koltunski
          }
65 c3ffcf58 Leszek Koltunski
66 f895e77a Leszek Koltunski
    mName = "";
67 82ce8e64 Leszek Koltunski
    mCountry = "un";
68
69 c3ffcf58 Leszek Koltunski
    mNameIsVerified = false;
70 82ce8e64 Leszek Koltunski
71 c3ffcf58 Leszek Koltunski
    mNumPlays= -1;
72
    mNumRuns = -1;
73 82ce8e64 Leszek Koltunski
    mDeviceID= -1;
74 f0e87514 Leszek Koltunski
    }
75
76 17f9a695 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
77
78
  private int privateGetDeviceID()
79
    {
80
    int id;
81
82
    try
83
      {
84
      String s = UUID.randomUUID().toString();
85 874c37b1 Leszek Koltunski
      id = s.hashCode();
86 17f9a695 Leszek Koltunski
      }
87
    catch(Exception ex)
88
      {
89
      id = 0;
90
      android.util.Log.e("scores", "Exception in getDeviceID()");
91
      }
92
93
    return id<0 ? -id : id;
94
    }
95
96
///////////////////////////////////////////////////////////////////////////////////////////////////
97
98
  private String getUnsubmittedList(int mode)
99
    {
100
    RubikObjectList list;
101
    StringBuilder builder = new StringBuilder();
102
    boolean first = true;
103
    int[] sizes;
104
    int length;
105
106
    for(int object=0; object<NUM_OBJECTS; object++)
107
      {
108
      list = RubikObjectList.getObject(object);
109
      sizes = list.getSizes();
110
      length = sizes.length;
111
112
      for(int size=0; size<length; size++)
113
        {
114 8e3898c8 Leszek Koltunski
        for(int level=0; level<MAX_LEVEL; level++)
115 17f9a695 Leszek Koltunski
          {
116 8e3898c8 Leszek Koltunski
          if( mSubmitted[object][size][level]==0 && mRecords[object][size][level]<NO_RECORD )
117 17f9a695 Leszek Koltunski
            {
118
            if( !first ) builder.append(',');
119
            else         first=false;
120
121
            switch(mode)
122
              {
123
              case 0: builder.append(list.name());
124
                      builder.append("_");
125
                      builder.append(sizes[size]);
126
                      break;
127 8e3898c8 Leszek Koltunski
              case 1: builder.append(level);
128 17f9a695 Leszek Koltunski
                      break;
129 8e3898c8 Leszek Koltunski
              case 2: builder.append(mRecords[object][size][level]);
130 17f9a695 Leszek Koltunski
                      break;
131
              }
132
            }
133
          }
134
        }
135
      }
136
137
    return builder.toString();
138
    }
139
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141
// PUBLIC API
142 714292f1 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
143
144
  public static RubikScores getInstance()
145
    {
146
    if( mThis==null )
147
      {
148
      mThis = new RubikScores();
149
      }
150
151
    return mThis;
152
    }
153
154 f0e87514 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
155
156
  public void savePreferences(SharedPreferences.Editor editor)
157
    {
158
    StringBuilder builder = new StringBuilder();
159
    RubikObjectList list;
160
    int[] sizes;
161
    int length;
162
163 8e3898c8 Leszek Koltunski
    for(int level=0; level<MAX_LEVEL; level++)
164 f0e87514 Leszek Koltunski
      {
165
      builder.setLength(0);
166
167
      for(int object=0; object<NUM_OBJECTS; object++)
168
        {
169
        list = RubikObjectList.getObject(object);
170
        sizes = list.getSizes();
171
        length = sizes.length;
172
173
        for(int size=0; size<length; size++)
174
          {
175
          builder.append(list.name());
176
          builder.append("_");
177
          builder.append(sizes[size]);
178
          builder.append("=");
179 8e3898c8 Leszek Koltunski
          builder.append(mRecords[object][size][level]);
180 286d73ae Leszek Koltunski
          builder.append(",");
181 8e3898c8 Leszek Koltunski
          builder.append(mSubmitted[object][size][level]);
182 f0e87514 Leszek Koltunski
          builder.append(" ");
183
          }
184
        }
185
186 8e3898c8 Leszek Koltunski
      editor.putString("scores_record"+level, builder.toString());
187 f0e87514 Leszek Koltunski
      }
188 c3ffcf58 Leszek Koltunski
189
    editor.putString("scores_name"  , mName  );
190
    editor.putBoolean("scores_isVerified", mNameIsVerified);
191
    editor.putInt("scores_numPlays", mNumPlays);
192
    editor.putInt("scores_numRuns" , mNumRuns);
193 82ce8e64 Leszek Koltunski
    editor.putInt("scores_deviceid", mDeviceID);
194 f0e87514 Leszek Koltunski
    }
195
196
///////////////////////////////////////////////////////////////////////////////////////////////////
197
198
  public void restorePreferences(SharedPreferences preferences)
199
    {
200 286d73ae Leszek Koltunski
    String recordStr, subStr, nameStr, sizeStr, timeStr, submStr;
201
    int start, end, equals, underscore, comma;
202 53f23b64 Leszek Koltunski
    int object, sizeIndex, subm;
203 1c90c64a Leszek Koltunski
    long time;
204 f0e87514 Leszek Koltunski
205 8e3898c8 Leszek Koltunski
    for(int level=0; level<MAX_LEVEL; level++)
206 f0e87514 Leszek Koltunski
      {
207
      start = end = 0;
208 8e3898c8 Leszek Koltunski
      recordStr = preferences.getString("scores_record"+level, "");
209 f0e87514 Leszek Koltunski
210
      while( end!=-1 )
211
        {
212
        end = recordStr.indexOf(" ", start);
213
214
        if( end==-1 ) subStr = recordStr.substring(start);
215
        else          subStr = recordStr.substring(start,end);
216
217
        start = end+1;
218
219
        underscore = subStr.indexOf("_");
220
        equals = subStr.indexOf("=");
221 286d73ae Leszek Koltunski
        comma = subStr.indexOf(",");
222 f0e87514 Leszek Koltunski
223 286d73ae Leszek Koltunski
        if( underscore>=0 && equals>=0 && comma>=0 )
224 f0e87514 Leszek Koltunski
          {
225
          nameStr = subStr.substring(0,underscore);
226
          sizeStr = subStr.substring(underscore+1, equals);
227 286d73ae Leszek Koltunski
          timeStr = subStr.substring(equals+1,comma);
228
          submStr = subStr.substring(comma+1);
229 f0e87514 Leszek Koltunski
230
          object = RubikObjectList.getOrdinal(nameStr);
231
232 4c0cd600 Leszek Koltunski
          if( object>=0 && object< NUM_OBJECTS )
233 f0e87514 Leszek Koltunski
            {
234 53f23b64 Leszek Koltunski
            sizeIndex = RubikObjectList.getSizeIndex(object,Integer.parseInt(sizeStr));
235 4c0cd600 Leszek Koltunski
            time = Long.parseLong(timeStr);
236
            subm = Integer.parseInt(submStr);
237
238 82d6e038 Leszek Koltunski
            if( sizeIndex>=0 && sizeIndex<MAX_NUM_OBJECTS && subm>=0 && subm<=1 )
239 4c0cd600 Leszek Koltunski
              {
240 8e3898c8 Leszek Koltunski
              mRecords  [object][sizeIndex][level] = time;
241
              mSubmitted[object][sizeIndex][level] = subm;
242 4c0cd600 Leszek Koltunski
              }
243
            else
244 f0e87514 Leszek Koltunski
              {
245 53f23b64 Leszek Koltunski
              android.util.Log.e("solv", "error: size="+sizeIndex+" subm="+subm);
246 f0e87514 Leszek Koltunski
              }
247
            }
248
          else
249
            {
250 4c0cd600 Leszek Koltunski
            android.util.Log.e("solv", "error: object="+object);
251 f0e87514 Leszek Koltunski
            }
252
          }
253
        }
254
      }
255 c3ffcf58 Leszek Koltunski
256 f895e77a Leszek Koltunski
    mName           = preferences.getString("scores_name"  , "" );
257 c3ffcf58 Leszek Koltunski
    mNameIsVerified = preferences.getBoolean("scores_isVerified", false);
258
    mNumPlays       = preferences.getInt("scores_numPlays", 0);
259
    mNumRuns        = preferences.getInt("scores_numRuns" , 0);
260 82ce8e64 Leszek Koltunski
    mDeviceID       = preferences.getInt("scores_deviceid",-1);
261
262 17f9a695 Leszek Koltunski
    if( mDeviceID==-1 ) mDeviceID = privateGetDeviceID();
263 f0e87514 Leszek Koltunski
    }
264
265
///////////////////////////////////////////////////////////////////////////////////////////////////
266
267 8e3898c8 Leszek Koltunski
  public boolean setRecord(int object, int size, int level, long timeTaken)
268 f0e87514 Leszek Koltunski
    {
269
    int maxsize = RubikObjectList.getObject(object).getSizes().length;
270
271 8e3898c8 Leszek Koltunski
    if( object>=0 && object<NUM_OBJECTS && size>=0 && size<maxsize && level>=1 && level<=MAX_LEVEL )
272 f0e87514 Leszek Koltunski
      {
273 8e3898c8 Leszek Koltunski
      if( mRecords[object][size][level-1]> timeTaken )
274 f0e87514 Leszek Koltunski
        {
275 8e3898c8 Leszek Koltunski
        mRecords  [object][size][level-1] = timeTaken;
276
        mSubmitted[object][size][level-1] = 0;
277 e41e7dc3 Leszek Koltunski
        return true;
278 f0e87514 Leszek Koltunski
        }
279
      }
280 e41e7dc3 Leszek Koltunski
281
    return false;
282 f0e87514 Leszek Koltunski
    }
283 714292f1 Leszek Koltunski
284 c3ffcf58 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
285
286
  public void incrementNumPlays()
287
    {
288
    mNumPlays++;
289
    }
290
291
///////////////////////////////////////////////////////////////////////////////////////////////////
292
293
  public void incrementNumRuns()
294
    {
295
    mNumRuns++;
296
    }
297
298
///////////////////////////////////////////////////////////////////////////////////////////////////
299
300
  public void setName(String newName)
301
    {
302
    mName = newName;
303
    }
304
305
///////////////////////////////////////////////////////////////////////////////////////////////////
306
307 17f9a695 Leszek Koltunski
  void successfulSubmit()
308 c3ffcf58 Leszek Koltunski
    {
309
    mNameIsVerified = true;
310 1c90c64a Leszek Koltunski
311 4895fff6 Leszek Koltunski
    for(int i=0; i<NUM_OBJECTS; i++)
312 82d6e038 Leszek Koltunski
      for(int j=0; j<MAX_NUM_OBJECTS; j++)
313 85b09df4 Leszek Koltunski
        for(int k=0; k<MAX_LEVEL; k++)
314 4895fff6 Leszek Koltunski
          {
315
          mSubmitted[i][j][k]=1;
316
          }
317 1c90c64a Leszek Koltunski
    }
318
319 286d73ae Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
320
321 82ce8e64 Leszek Koltunski
  public void setCountry(Context context)
322 286d73ae Leszek Koltunski
    {
323 82ce8e64 Leszek Koltunski
    TelephonyManager tM =((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE));
324 286d73ae Leszek Koltunski
325 82ce8e64 Leszek Koltunski
    if( tM!=null )
326 286d73ae Leszek Koltunski
      {
327 82ce8e64 Leszek Koltunski
      mCountry = tM.getSimCountryIso();
328
329
      if( mCountry==null || mCountry.length()<=1 )
330
        {
331
        mCountry = tM.getNetworkCountryIso();
332
        }
333
      }
334
335
    // Special case: Dominicana. Its ISO-3166-alpha-2 country code is 'do' which we can't have here
336 874c37b1 Leszek Koltunski
    // because we later on map this to a resource name (the flag) and 'do' is a reserved Java keyword
337 82ce8e64 Leszek Koltunski
    // and can't be a resource name.
338
339
    if( mCountry.equals("do") ) mCountry = "dm";
340
    }
341
342 874c37b1 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
343
344
  public void setCountry(String country)
345
    {
346
    mCountry = country;
347
348
    if( mCountry.equals("do") ) mCountry = "dm";  // see above
349
    }
350
351 714292f1 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
352
353 8e3898c8 Leszek Koltunski
  public long getRecord(int object, int size, int level)
354 714292f1 Leszek Koltunski
    {
355
    int maxsize = RubikObjectList.getObject(object).getSizes().length;
356
357 8e3898c8 Leszek Koltunski
    if( object>=0 && object<NUM_OBJECTS && size>=0 && size<maxsize && level>=0 && level<MAX_LEVEL )
358 714292f1 Leszek Koltunski
      {
359 8e3898c8 Leszek Koltunski
      return mRecords[object][size][level];
360 714292f1 Leszek Koltunski
      }
361
362
    return -1;
363
    }
364 c3ffcf58 Leszek Koltunski
365 286d73ae Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
366
367 8e3898c8 Leszek Koltunski
  public boolean isSubmitted(int object, int size, int level)
368 286d73ae Leszek Koltunski
    {
369
    int maxsize = RubikObjectList.getObject(object).getSizes().length;
370
371 8e3898c8 Leszek Koltunski
    if( object>=0 && object<NUM_OBJECTS && size>=0 && size<maxsize && level>=0 && level<MAX_LEVEL )
372 286d73ae Leszek Koltunski
      {
373 8e3898c8 Leszek Koltunski
      return mSubmitted[object][size][level]==1;
374 286d73ae Leszek Koltunski
      }
375
376
    return false;
377
    }
378
379 17f9a695 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
380
381
  int getDeviceID()
382
    {
383
    return mDeviceID;
384
    }
385
386 c3ffcf58 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
387 1c90c64a Leszek Koltunski
388 4895fff6 Leszek Koltunski
  boolean isVerified()
389 1c90c64a Leszek Koltunski
    {
390
    return mNameIsVerified;
391
    }
392
393
///////////////////////////////////////////////////////////////////////////////////////////////////
394 c3ffcf58 Leszek Koltunski
395 4895fff6 Leszek Koltunski
  int getNumPlays()
396 c3ffcf58 Leszek Koltunski
    {
397
    return mNumPlays;
398
    }
399
400
///////////////////////////////////////////////////////////////////////////////////////////////////
401
402 4895fff6 Leszek Koltunski
  int getNumRuns()
403 c3ffcf58 Leszek Koltunski
    {
404
    return mNumRuns;
405
    }
406
407
///////////////////////////////////////////////////////////////////////////////////////////////////
408
409
  public String getName()
410
    {
411
    return mName;
412
    }
413
414
///////////////////////////////////////////////////////////////////////////////////////////////////
415
416 82ce8e64 Leszek Koltunski
  public String getCountry()
417 c3ffcf58 Leszek Koltunski
    {
418 82ce8e64 Leszek Koltunski
    return mCountry;
419 c3ffcf58 Leszek Koltunski
    }
420 4895fff6 Leszek Koltunski
421
///////////////////////////////////////////////////////////////////////////////////////////////////
422
423 17f9a695 Leszek Koltunski
  boolean thereAreUnsubmittedRecords()
424 4895fff6 Leszek Koltunski
    {
425
    RubikObjectList list;
426
    int length;
427
428
    for(int object=0; object<NUM_OBJECTS; object++)
429
      {
430
      list = RubikObjectList.getObject(object);
431 17f9a695 Leszek Koltunski
      length = list.getSizes().length;
432 4895fff6 Leszek Koltunski
433
      for(int size=0; size<length; size++)
434 8e3898c8 Leszek Koltunski
        for(int level=0; level<MAX_LEVEL; level++)
435 4c0cd600 Leszek Koltunski
          {
436 8e3898c8 Leszek Koltunski
          if( mSubmitted[object][size][level]==0 && mRecords[object][size][level]<NO_RECORD )
437 4895fff6 Leszek Koltunski
            {
438 17f9a695 Leszek Koltunski
            return true;
439 4895fff6 Leszek Koltunski
            }
440 4c0cd600 Leszek Koltunski
          }
441 4895fff6 Leszek Koltunski
      }
442
443 17f9a695 Leszek Koltunski
    return false;
444 4895fff6 Leszek Koltunski
    }
445
446
///////////////////////////////////////////////////////////////////////////////////////////////////
447
448
  String getUnsubmittedObjlist()
449
    {
450
    return getUnsubmittedList(0);
451
    }
452
453
///////////////////////////////////////////////////////////////////////////////////////////////////
454
455
  String getUnsubmittedLevellist()
456
    {
457
    return getUnsubmittedList(1);
458
    }
459
460
///////////////////////////////////////////////////////////////////////////////////////////////////
461
462
  String getUnsubmittedTimelist()
463
    {
464
    return getUnsubmittedList(2);
465
    }
466 f0e87514 Leszek Koltunski
  }