Revision e2448de9
Added by Leszek Koltunski about 9 hours ago
| src/main/java/org/distorted/helpers/RubikRememberedSolves.java | ||
|---|---|---|
| 1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 2 |
// Copyright 2025 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.helpers; |
|
| 11 |
|
|
| 12 |
import org.distorted.library.type.Static4D; |
|
| 13 |
import org.distorted.main.MainObjectPopup; |
|
| 14 |
import org.json.JSONArray; |
|
| 15 |
import org.json.JSONException; |
|
| 16 |
import org.json.JSONObject; |
|
| 17 |
|
|
| 18 |
import java.io.BufferedReader; |
|
| 19 |
import java.io.IOException; |
|
| 20 |
import java.io.InputStream; |
|
| 21 |
import java.io.InputStreamReader; |
|
| 22 |
import java.nio.charset.StandardCharsets; |
|
| 23 |
|
|
| 24 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 25 |
|
|
| 26 |
public class RubikRememberedSolves |
|
| 27 |
{
|
|
| 28 |
private static final int MAXSOLVES = 8; |
|
| 29 |
private static RubikRememberedSolves mThis; |
|
| 30 |
|
|
| 31 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 32 |
|
|
| 33 |
private RubikRememberedSolves() |
|
| 34 |
{
|
|
| 35 |
|
|
| 36 |
} |
|
| 37 |
|
|
| 38 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 39 |
// PUBLIC API |
|
| 40 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 41 |
|
|
| 42 |
public static RubikRememberedSolves getInstance() |
|
| 43 |
{
|
|
| 44 |
if( mThis==null ) mThis = new RubikRememberedSolves(); |
|
| 45 |
return mThis; |
|
| 46 |
} |
|
| 47 |
|
|
| 48 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 49 |
|
|
| 50 |
private JSONObject createData(long time, Static4D rot, int[] quats) throws JSONException |
|
| 51 |
{
|
|
| 52 |
JSONObject data = new JSONObject(); |
|
| 53 |
data.put("time",time);
|
|
| 54 |
data.put("rot0", rot.get0() );
|
|
| 55 |
data.put("rot1", rot.get1() );
|
|
| 56 |
data.put("rot2", rot.get2() );
|
|
| 57 |
data.put("rot3", rot.get3() );
|
|
| 58 |
JSONArray qs = new JSONArray(); |
|
| 59 |
for(int q:quats) qs.put(q); |
|
| 60 |
data.put("quats", qs);
|
|
| 61 |
|
|
| 62 |
return data; |
|
| 63 |
} |
|
| 64 |
|
|
| 65 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 66 |
|
|
| 67 |
public String addInfo(InputStream stream, int level, long time, Static4D rot, int[] quats) |
|
| 68 |
{
|
|
| 69 |
/* |
|
| 70 |
StringBuilder quatStr = new StringBuilder(); |
|
| 71 |
|
|
| 72 |
for(int c : quats) |
|
| 73 |
{
|
|
| 74 |
quatStr.append(c); |
|
| 75 |
quatStr.append(" ");
|
|
| 76 |
} |
|
| 77 |
|
|
| 78 |
android.util.Log.e("D", "level: "+level+"\n"+
|
|
| 79 |
"time: "+time+"\n"+ |
|
| 80 |
"rotQuat: " +rot.get0()+" "+rot.get1()+" "+rot.get2()+" "+rot.get3()+"\n"+ |
|
| 81 |
"quats: "+quatStr ); |
|
| 82 |
*/ |
|
| 83 |
if( stream!=null ) |
|
| 84 |
{
|
|
| 85 |
try |
|
| 86 |
{
|
|
| 87 |
BufferedReader br = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8)); |
|
| 88 |
StringBuilder contents = new StringBuilder(); |
|
| 89 |
String tmp; |
|
| 90 |
|
|
| 91 |
while( (tmp = br.readLine()) != null) contents.append(tmp); |
|
| 92 |
br.close(); |
|
| 93 |
stream.close(); |
|
| 94 |
|
|
| 95 |
JSONArray levels = new JSONArray(contents.toString()); |
|
| 96 |
JSONArray lvl = levels.getJSONArray(level); |
|
| 97 |
JSONObject data = createData(time,rot,quats); |
|
| 98 |
if( lvl.length()>MAXSOLVES ) lvl.remove(0); |
|
| 99 |
lvl.put(data); |
|
| 100 |
|
|
| 101 |
return levels.toString(); |
|
| 102 |
} |
|
| 103 |
catch(IOException iex) { android.util.Log.e("D", "addInfo: failed to read file"); }
|
|
| 104 |
catch(JSONException jex) { android.util.Log.e("D", "addInfo: failed to parse file"); }
|
|
| 105 |
} |
|
| 106 |
else |
|
| 107 |
{
|
|
| 108 |
JSONArray levels = new JSONArray(); |
|
| 109 |
|
|
| 110 |
try |
|
| 111 |
{
|
|
| 112 |
for(int l=0; l< MainObjectPopup.LEVELS_SHOWN+1; l++) |
|
| 113 |
{
|
|
| 114 |
JSONArray save = new JSONArray(); |
|
| 115 |
|
|
| 116 |
if( l==level ) |
|
| 117 |
{
|
|
| 118 |
JSONObject data = createData(time,rot,quats); |
|
| 119 |
save.put(data); |
|
| 120 |
} |
|
| 121 |
levels.put(save); |
|
| 122 |
} |
|
| 123 |
} |
|
| 124 |
catch(JSONException jex) { android.util.Log.e("D", "addInfo: failed to parse file"); }
|
|
| 125 |
|
|
| 126 |
return levels.toString(); |
|
| 127 |
} |
|
| 128 |
|
|
| 129 |
return null; |
|
| 130 |
} |
|
| 131 |
} |
|
| src/main/java/org/distorted/main/MainActivity.java | ||
|---|---|---|
| 47 | 47 |
import org.distorted.play.PlayActivity; |
| 48 | 48 |
import org.distorted.solvers.SolverActivity; |
| 49 | 49 |
import org.distorted.tutorials.TutorialActivity; |
| 50 |
import org.json.JSONArray; |
|
| 50 | 51 |
|
| 51 | 52 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 52 | 53 |
|
| ... | ... | |
| 347 | 348 |
intent.putExtra("scrambles", scrambles);
|
| 348 | 349 |
intent.putExtra("local", local );
|
| 349 | 350 |
intent.putExtra("ordinal", ordinal );
|
| 351 |
|
|
| 350 | 352 |
startActivity(intent); |
| 351 | 353 |
} |
| 352 | 354 |
|
| ... | ... | |
| 442 | 444 |
|
| 443 | 445 |
public void errorUpdate() |
| 444 | 446 |
{
|
| 445 |
android.util.Log.e("D", "NewRubikActivity: Error receiving downloaded objects update");
|
|
| 447 |
android.util.Log.e("D", "RubikActivity: Error receiving downloaded objects update");
|
|
| 446 | 448 |
} |
| 447 | 449 |
} |
| src/main/java/org/distorted/main/MainObjectPopup.java | ||
|---|---|---|
| 24 | 24 |
import android.widget.PopupWindow; |
| 25 | 25 |
import android.widget.TextView; |
| 26 | 26 |
|
| 27 |
import org.distorted.helpers.RubikRememberedSolves; |
|
| 27 | 28 |
import org.distorted.helpers.RubikScores; |
| 28 | 29 |
import org.distorted.objects.RubikObject; |
| 29 | 30 |
import org.distorted.objects.RubikObjectList; |
| 31 |
import org.json.JSONArray; |
|
| 32 |
import org.json.JSONException; |
|
| 30 | 33 |
|
| 31 | 34 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 32 | 35 |
|
| ... | ... | |
| 42 | 45 |
private final PopupWindow mPopup; |
| 43 | 46 |
private final int mMenuTextSize; |
| 44 | 47 |
private final int mObjectOrdinal; |
| 48 |
private JSONArray mRememberedSolves = null; |
|
| 45 | 49 |
|
| 46 | 50 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 47 | 51 |
|
| ... | ... | |
| 68 | 72 |
int levelHeight = (int)(width*BUTTON_HEIGHT); |
| 69 | 73 |
|
| 70 | 74 |
RubikObject object = RubikObjectList.getObject(ordinal); |
| 75 |
String objname = object!=null ? object.getLowerName() : "null"; |
|
| 76 |
|
|
| 77 |
Thread thread = new Thread() |
|
| 78 |
{
|
|
| 79 |
public void run() |
|
| 80 |
{
|
|
| 81 |
RubikRememberedSolves solves = RubikRememberedSolves.getInstance(); |
|
| 82 |
mRememberedSolves = solves.readFile(objname); |
|
| 83 |
} |
|
| 84 |
}; |
|
| 85 |
|
|
| 86 |
thread.start(); |
|
| 71 | 87 |
|
| 72 | 88 |
///////// SOLVER ////////////////////////////////////////////////// |
| 73 | 89 |
Button b1 = layout.findViewById(R.id.objectSolver); |
| ... | ... | |
| 248 | 264 |
mPopup.dismiss(); |
| 249 | 265 |
if( ll<0 ) scores.setRecord(mObjectOrdinal,ll,0); // remember we've entered the 'Free' |
| 250 | 266 |
// so that the button turns green |
| 267 |
|
|
| 268 |
JSONArray json = null; |
|
| 269 |
int numSolves = 0; |
|
| 270 |
|
|
| 271 |
if( mRememberedSolves!=null ) |
|
| 272 |
{
|
|
| 273 |
try |
|
| 274 |
{
|
|
| 275 |
json = mRememberedSolves.getJSONArray(ll); |
|
| 276 |
numSolves = json.length(); |
|
| 277 |
} |
|
| 278 |
catch(JSONException jex) |
|
| 279 |
{
|
|
| 280 |
android.util.Log.e("D", "execption trying to parse file: "+jex.getMessage() );
|
|
| 281 |
} |
|
| 282 |
} |
|
| 283 |
|
|
| 284 |
if( numSolves>0 ) act |
|
| 251 | 285 |
act.switchToPlay(object,mObjectOrdinal,scrambles,ll); |
| 252 | 286 |
} |
| 253 | 287 |
}); |
| src/main/java/org/distorted/play/PlayActivity.java | ||
|---|---|---|
| 9 | 9 |
|
| 10 | 10 |
package org.distorted.play; |
| 11 | 11 |
|
| 12 |
import java.io.BufferedWriter; |
|
| 13 |
import java.io.FileOutputStream; |
|
| 14 |
import java.io.IOException; |
|
| 12 | 15 |
import java.io.InputStream; |
| 16 |
import java.io.OutputStreamWriter; |
|
| 17 |
import java.nio.charset.StandardCharsets; |
|
| 13 | 18 |
|
| 14 | 19 |
import android.content.SharedPreferences; |
| 15 | 20 |
import android.os.Build; |
| ... | ... | |
| 24 | 29 |
|
| 25 | 30 |
import org.distorted.dialogs.DialogScores; |
| 26 | 31 |
import org.distorted.helpers.BaseActivity; |
| 32 |
import org.distorted.helpers.RubikRememberedSolves; |
|
| 27 | 33 |
import org.distorted.library.main.DistortedLibrary; |
| 28 | 34 |
import org.distorted.library.type.Static4D; |
| 29 | 35 |
import org.distorted.objectlib.main.InitAssets; |
| ... | ... | |
| 133 | 139 |
protected void onResume() |
| 134 | 140 |
{
|
| 135 | 141 |
super.onResume(); |
| 142 |
|
|
| 136 | 143 |
DistortedLibrary.onResume(ACTIVITY_NUMBER); |
| 137 | 144 |
PlayView view = findViewById(R.id.playView); |
| 138 | 145 |
ObjectControl control = view.getObjectControl(); |
| ... | ... | |
| 297 | 304 |
return mObjectOrdinal; |
| 298 | 305 |
} |
| 299 | 306 |
|
| 307 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 308 |
|
|
| 309 |
private void rememberSolveThread(String name, int level, long time, Static4D rot, int[] quats) |
|
| 310 |
{
|
|
| 311 |
String filename = name+"_solves.json"; |
|
| 312 |
RubikFiles files = RubikFiles.getInstance(); |
|
| 313 |
InputStream file = files.openFile(this, filename); |
|
| 314 |
RubikRememberedSolves solves = RubikRememberedSolves.getInstance(); |
|
| 315 |
String contents = solves.addInfo(file,level,time,rot,quats); |
|
| 316 |
|
|
| 317 |
try |
|
| 318 |
{
|
|
| 319 |
FileOutputStream fos = new FileOutputStream(filename); |
|
| 320 |
OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8); |
|
| 321 |
BufferedWriter bw = new BufferedWriter(osw); |
|
| 322 |
bw.write(contents); |
|
| 323 |
bw.flush(); |
|
| 324 |
} |
|
| 325 |
catch(IOException ex) |
|
| 326 |
{
|
|
| 327 |
android.util.Log.e("D", "failed to save file "+filename);
|
|
| 328 |
} |
|
| 329 |
} |
|
| 330 |
|
|
| 300 | 331 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 301 | 332 |
|
| 302 | 333 |
public void rememberSolve() |
| ... | ... | |
| 312 | 343 |
for(int c=0; c<numCubits; c++) quats[c] = object.getCubitQuatIndex(c); |
| 313 | 344 |
Static4D rotQuat = control.getQuat(); |
| 314 | 345 |
|
| 315 |
StringBuilder quatStr = new StringBuilder(); |
|
| 316 |
for(int c=0; c<numCubits; c++) |
|
| 346 |
Thread thread = new Thread() |
|
| 317 | 347 |
{
|
| 318 |
quatStr.append(quats[c]); |
|
| 319 |
quatStr.append(" ");
|
|
| 320 |
} |
|
| 348 |
public void run() |
|
| 349 |
{
|
|
| 350 |
rememberSolveThread(name,level,time,rotQuat,quats); |
|
| 351 |
} |
|
| 352 |
}; |
|
| 321 | 353 |
|
| 322 |
android.util.Log.e("D", "object: "+name+"\n"+
|
|
| 323 |
"level: "+level+"\n"+ |
|
| 324 |
"time: "+time+"\n"+ |
|
| 325 |
"rotQuat: " +rotQuat.get0()+" "+rotQuat.get1()+" "+rotQuat.get2()+" "+rotQuat.get3()+"\n"+ |
|
| 326 |
"quats: "+quatStr ); |
|
| 354 |
thread.start(); |
|
| 327 | 355 |
} |
| 328 | 356 |
|
| 329 | 357 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
Also available in: Unified diff
progress with saving solves