Revision a7d8c3cd
Added by Leszek Koltunski over 2 years ago
src/main/java/org/distorted/network/RubikScores.java | ||
---|---|---|
19 | 19 |
|
20 | 20 |
package org.distorted.network; |
21 | 21 |
|
22 |
import java.util.HashMap; |
|
22 | 23 |
import java.util.UUID; |
23 | 24 |
|
24 | 25 |
import android.content.Context; |
... | ... | |
27 | 28 |
|
28 | 29 |
import com.google.firebase.crashlytics.FirebaseCrashlytics; |
29 | 30 |
|
30 |
import static org.distorted.objectlib.main.ObjectType.NUM_OBJECTS; |
|
31 | 31 |
import static org.distorted.screens.RubikScreenPlay.MAX_LEVEL; |
32 |
|
|
33 |
import org.distorted.objectlib.main.ObjectType; |
|
34 |
|
|
35 | 32 |
import org.distorted.main.BuildConfig; |
33 |
import org.distorted.objects.RubikObject; |
|
34 |
import org.distorted.objects.RubikObjectList; |
|
36 | 35 |
|
37 | 36 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
38 | 37 |
// hold my own scores, and some other statistics. |
39 | 38 |
|
40 | 39 |
public class RubikScores |
41 | 40 |
{ |
41 |
public static final int MULT = 1000000; |
|
42 | 42 |
public static final long NO_RECORD = Long.MAX_VALUE; |
43 | 43 |
private static RubikScores mThis; |
44 | 44 |
|
45 |
private final long[][] mRecords; |
|
46 |
private final int [][] mSubmitted; |
|
47 |
|
|
48 | 45 |
private String mName, mCountry; |
49 | 46 |
private boolean mNameIsVerified; |
50 | 47 |
private int mNumRuns; |
... | ... | |
52 | 49 |
private int mNumWins; |
53 | 50 |
private int mDeviceID; |
54 | 51 |
|
52 |
private static class MapValue |
|
53 |
{ |
|
54 |
long record; |
|
55 |
boolean submitted; |
|
56 |
|
|
57 |
MapValue(long rec,int sub) |
|
58 |
{ |
|
59 |
record = rec; |
|
60 |
submitted = sub!=0; |
|
61 |
} |
|
62 |
} |
|
63 |
|
|
64 |
private final HashMap<Integer,MapValue> mMap; |
|
65 |
|
|
55 | 66 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
56 | 67 |
|
57 | 68 |
private RubikScores() |
58 | 69 |
{ |
59 |
mRecords = new long[NUM_OBJECTS][MAX_LEVEL]; |
|
60 |
mSubmitted = new int [NUM_OBJECTS][MAX_LEVEL]; |
|
61 |
|
|
62 |
for(int object=0; object<NUM_OBJECTS; object++) |
|
63 |
for(int level=0; level<MAX_LEVEL; level++) |
|
64 |
{ |
|
65 |
mRecords[object][level] = NO_RECORD; |
|
66 |
mSubmitted[object][level] = 0; |
|
67 |
} |
|
70 |
mMap = new HashMap<>(); |
|
68 | 71 |
|
69 | 72 |
mName = ""; |
70 | 73 |
mCountry = "un"; |
... | ... | |
77 | 80 |
mNumWins = 0; |
78 | 81 |
} |
79 | 82 |
|
83 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
84 |
|
|
85 |
private int mapKey(int object,int level) |
|
86 |
{ |
|
87 |
return object*MULT + level; |
|
88 |
} |
|
89 |
|
|
80 | 90 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
81 | 91 |
|
82 | 92 |
private int privateGetDeviceID() |
... | ... | |
103 | 113 |
{ |
104 | 114 |
mNameIsVerified = true; |
105 | 115 |
|
106 |
for(int object=0; object<NUM_OBJECTS; object++)
|
|
107 |
for(int level=0; level<MAX_LEVEL; level++)
|
|
108 |
{
|
|
109 |
mSubmitted[object][level]=1;
|
|
110 |
}
|
|
116 |
for(int key: mMap.keySet())
|
|
117 |
{
|
|
118 |
MapValue value = mMap.get(key);
|
|
119 |
if( value!=null ) value.submitted = true;
|
|
120 |
} |
|
111 | 121 |
} |
112 | 122 |
|
113 | 123 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
121 | 131 |
|
122 | 132 |
synchronized boolean thereAreUnsubmittedRecords() |
123 | 133 |
{ |
124 |
for(int object=0; object<NUM_OBJECTS; object++)
|
|
125 |
for(int level=0; level<MAX_LEVEL; level++)
|
|
126 |
{
|
|
127 |
if( mSubmitted[object][level]==0 && mRecords[object][level]<NO_RECORD ) return true;
|
|
128 |
}
|
|
134 |
for(int key: mMap.keySet())
|
|
135 |
{
|
|
136 |
MapValue value = mMap.get(key);
|
|
137 |
if( value!=null && !value.submitted && value.record<NO_RECORD) return true;
|
|
138 |
} |
|
129 | 139 |
|
130 | 140 |
return false; |
131 | 141 |
} |
... | ... | |
139 | 149 |
StringBuilder builderTim = new StringBuilder(); |
140 | 150 |
boolean first = true; |
141 | 151 |
|
142 |
for(int object=0; object<NUM_OBJECTS; object++)
|
|
152 |
for(int key: mMap.keySet())
|
|
143 | 153 |
{ |
144 |
String name = ObjectType.getObject(object).name();
|
|
154 |
MapValue value = mMap.get(key);
|
|
145 | 155 |
|
146 |
for(int level=0; level<MAX_LEVEL; level++)
|
|
156 |
if( value!=null && !value.submitted && value.record<NO_RECORD)
|
|
147 | 157 |
{ |
148 |
if( mSubmitted[object][level]==0 && mRecords[object][level]<NO_RECORD )
|
|
158 |
if( !first )
|
|
149 | 159 |
{ |
150 |
if( !first ) |
|
151 |
{ |
|
152 |
builderObj.append(','); |
|
153 |
builderLvl.append(','); |
|
154 |
builderTim.append(','); |
|
155 |
} |
|
156 |
first=false; |
|
160 |
builderObj.append(','); |
|
161 |
builderLvl.append(','); |
|
162 |
builderTim.append(','); |
|
163 |
} |
|
164 |
first=false; |
|
157 | 165 |
|
158 |
builderObj.append(name); |
|
159 |
builderLvl.append(level); |
|
160 |
builderTim.append(mRecords[object][level]); |
|
166 |
RubikObject object = RubikObjectList.getObject(key/MULT); |
|
167 |
|
|
168 |
if( object!=null ) |
|
169 |
{ |
|
170 |
builderObj.append(object.getName()); |
|
171 |
builderLvl.append(key%MULT); |
|
172 |
builderTim.append(value.record); |
|
161 | 173 |
} |
162 | 174 |
} |
163 | 175 |
} |
... | ... | |
167 | 179 |
|
168 | 180 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
169 | 181 |
// Public API |
170 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
171 |
|
|
172 |
public synchronized long getRecord(int obj, int level) |
|
173 |
{ |
|
174 |
return (obj>=0 && obj<NUM_OBJECTS && level>=0 && level<MAX_LEVEL) ? mRecords[obj][level] : -1; |
|
175 |
} |
|
176 |
|
|
177 | 182 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
178 | 183 |
|
179 | 184 |
public boolean isVerified() |
... | ... | |
240 | 245 |
|
241 | 246 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
242 | 247 |
|
243 |
public synchronized boolean isSolved(int obj, int level) |
|
248 |
public synchronized boolean setRecord(int object, int level, long record) |
|
249 |
{ |
|
250 |
int key = mapKey(object,level)-1; // -1 - historical reasons; previous versions saved it like this. |
|
251 |
MapValue oldValue = mMap.get(key); |
|
252 |
|
|
253 |
if( oldValue==null ) |
|
254 |
{ |
|
255 |
MapValue value = new MapValue(record,0); |
|
256 |
mMap.put(key,value); |
|
257 |
return true; |
|
258 |
} |
|
259 |
|
|
260 |
long oldRecord = oldValue.record; |
|
261 |
|
|
262 |
if( oldRecord>record) |
|
263 |
{ |
|
264 |
MapValue value = new MapValue(record,0); |
|
265 |
mMap.put(key,value); |
|
266 |
return true; |
|
267 |
} |
|
268 |
|
|
269 |
return false; |
|
270 |
} |
|
271 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
272 |
|
|
273 |
public synchronized long getRecord(int object, int level) |
|
274 |
{ |
|
275 |
int key = mapKey(object,level); |
|
276 |
MapValue value = mMap.get(key); |
|
277 |
return value!=null ? value.record : NO_RECORD; |
|
278 |
} |
|
279 |
|
|
280 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
281 |
|
|
282 |
public synchronized boolean isSolved(int object, int level) |
|
244 | 283 |
{ |
245 |
return obj>=0 && obj<NUM_OBJECTS && level>=0 && level<MAX_LEVEL && mRecords[obj][level]<NO_RECORD; |
|
284 |
int key = mapKey(object,level); |
|
285 |
MapValue value = mMap.get(key); |
|
286 |
return value!=null && value.record<NO_RECORD; |
|
246 | 287 |
} |
247 | 288 |
|
248 | 289 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
289 | 330 |
|
290 | 331 |
public synchronized void savePreferences(SharedPreferences.Editor editor) |
291 | 332 |
{ |
333 |
int numObjects = RubikObjectList.getNumObjects(); |
|
292 | 334 |
StringBuilder builder = new StringBuilder(); |
293 |
String name; |
|
294 | 335 |
|
295 | 336 |
for(int level=0; level<MAX_LEVEL; level++) |
296 | 337 |
{ |
297 | 338 |
builder.setLength(0); |
298 | 339 |
|
299 |
for(int object=0; object<NUM_OBJECTS; object++)
|
|
340 |
for(int object=0; object<numObjects; object++)
|
|
300 | 341 |
{ |
301 |
name = ObjectType.getObject(object).name(); |
|
302 |
builder.append(name); |
|
303 |
builder.append("="); |
|
304 |
builder.append(mRecords[object][level]); |
|
305 |
builder.append(","); |
|
306 |
builder.append(mSubmitted[object][level]); |
|
307 |
builder.append(" "); |
|
342 |
int key = mapKey(object,level); |
|
343 |
RubikObject obj = RubikObjectList.getObject(object); |
|
344 |
MapValue value = mMap.get(key); |
|
345 |
|
|
346 |
if( obj!=null && value!=null && value.record<NO_RECORD ) |
|
347 |
{ |
|
348 |
builder.append(obj.getName()); |
|
349 |
builder.append("="); |
|
350 |
builder.append(value.record); |
|
351 |
builder.append(","); |
|
352 |
builder.append(value.submitted ? 1:0 ); |
|
353 |
builder.append(" "); |
|
354 |
} |
|
308 | 355 |
} |
309 | 356 |
|
310 | 357 |
editor.putString("scores_record"+level, builder.toString()); |
... | ... | |
326 | 373 |
int start, end, equals, comma, object, subm; |
327 | 374 |
long time; |
328 | 375 |
boolean thereWasError = false; |
376 |
int numObjects = RubikObjectList.getNumObjects(); |
|
329 | 377 |
|
330 | 378 |
for(int level=0; level<MAX_LEVEL; level++) |
331 | 379 |
{ |
... | ... | |
350 | 398 |
timeStr = subStr.substring(equals+1,comma); |
351 | 399 |
submStr = subStr.substring(comma+1); |
352 | 400 |
|
353 |
object = ObjectType.getOrdinal(nameStr);
|
|
401 |
object = RubikObjectList.getOrdinal(nameStr);
|
|
354 | 402 |
|
355 |
if( object>=0 && object< NUM_OBJECTS )
|
|
403 |
if( object>=0 && object<numObjects )
|
|
356 | 404 |
{ |
357 | 405 |
time = Long.parseLong(timeStr); |
358 | 406 |
subm = Integer.parseInt(submStr); |
359 | 407 |
|
360 | 408 |
if( subm>=0 && subm<=1 ) |
361 | 409 |
{ |
362 |
mRecords [object][level] = time; |
|
363 |
mSubmitted[object][level] = subm; |
|
410 |
MapValue value = new MapValue(time,subm); |
|
411 |
int key = mapKey(object,level); |
|
412 |
mMap.put(key,value); |
|
364 | 413 |
} |
365 | 414 |
else |
366 | 415 |
{ |
... | ... | |
405 | 454 |
crashlytics.recordException(ex); |
406 | 455 |
} |
407 | 456 |
} |
408 |
|
|
409 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
410 |
|
|
411 |
public synchronized boolean setRecord(int object, int level, long timeTaken) |
|
412 |
{ |
|
413 |
if( object>=0 && object<NUM_OBJECTS && level>=1 && level<=MAX_LEVEL && mRecords[object][level-1]>timeTaken ) |
|
414 |
{ |
|
415 |
mRecords [object][level-1] = timeTaken; |
|
416 |
mSubmitted[object][level-1] = 0; |
|
417 |
return true; |
|
418 |
} |
|
419 |
|
|
420 |
return false; |
|
421 |
} |
|
422 | 457 |
} |
Also available in: Unified diff
Progress replacing the enum ObjetType with the class RubikObjectList.