Revision 94ce8e53
Added by Leszek Koltunski 1 day ago
src/main/java/org/distorted/dialogs/RubikDialogSolverView.java | ||
---|---|---|
9 | 9 |
|
10 | 10 |
package org.distorted.dialogs; |
11 | 11 |
|
12 |
import android.content.res.Resources; |
|
13 | 12 |
import android.util.TypedValue; |
14 | 13 |
import android.view.View; |
15 | 14 |
import android.widget.Button; |
... | ... | |
19 | 18 |
import org.distorted.main.R; |
20 | 19 |
import org.distorted.objectlib.helpers.OperatingSystemInterface; |
21 | 20 |
import org.distorted.objectlib.main.TwistyObject; |
22 |
import org.distorted.solvers.SolvingList; |
|
23 |
import org.distorted.solvers.SolvingThread; |
|
21 |
import org.distorted.objectlib.solvers.verifiers.SolverAbstract; |
|
22 |
import org.distorted.objectlib.solvers.verifiers.SolvingList; |
|
23 |
import org.distorted.solverui.ScreenList; |
|
24 |
import org.distorted.solverui.ScreenSolver; |
|
24 | 25 |
import org.distorted.solverui.SolverActivity; |
25 | 26 |
|
26 | 27 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
56 | 57 |
dialog.dismiss(); |
57 | 58 |
SolvingList list = SolvingList.getSolver(solverOrdinal); |
58 | 59 |
OperatingSystemInterface os = act.getInterface(); |
59 |
Resources res = act.getResources(); |
|
60 | 60 |
TwistyObject object = act.getObject(); |
61 |
SolvingThread solver = new SolvingThread( os,res,object,list ); |
|
62 |
solver.start(); |
|
61 |
SolverAbstract solver = list.create(os,object); |
|
62 |
ScreenSolver screen = (ScreenSolver)ScreenList.SVER.getScreenClass(); |
|
63 |
|
|
64 |
if( solver!=null ) |
|
65 |
{ |
|
66 |
int[] result = solver.validatePosition(object); |
|
67 |
if( result[0]>=0 ) solver.solve(screen,result); |
|
68 |
else screen.displayImpossibleDialog(result,solver.getFaceColors()); |
|
69 |
} |
|
70 |
else screen.displayErrorDialog(act.getString(R.string.solver_generic_not_implemented)); |
|
63 | 71 |
} |
64 | 72 |
}); |
65 | 73 |
|
src/main/java/org/distorted/dialogs/RubikDialogSolvers.java | ||
---|---|---|
23 | 23 |
import org.distorted.main.R; |
24 | 24 |
import org.distorted.objectlib.metadata.ListObjects; |
25 | 25 |
import org.distorted.solverui.SolverActivity; |
26 |
import org.distorted.solvers.SolvingList;
|
|
26 |
import org.distorted.objectlib.solvers.verifiers.SolvingList;
|
|
27 | 27 |
|
28 | 28 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
29 | 29 |
|
src/main/java/org/distorted/objects/RubikObject.java | ||
---|---|---|
27 | 27 |
import org.distorted.objectlib.metadata.ListObjects; |
28 | 28 |
import org.distorted.objectlib.metadata.Metadata; |
29 | 29 |
import org.distorted.objectlib.patterns.RubikPatternList; |
30 |
import org.distorted.solvers.SolvingList;
|
|
30 |
import org.distorted.objectlib.solvers.verifiers.SolvingList;
|
|
31 | 31 |
|
32 | 32 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
33 | 33 |
|
src/main/java/org/distorted/solvers/SolverAlgorithmic.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2024 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.solvers; |
|
11 |
|
|
12 |
import android.content.res.Resources; |
|
13 |
|
|
14 |
import org.distorted.objectlib.algsolvers.SolutionListener; |
|
15 |
import org.distorted.objectlib.algsolvers.SolvedObject; |
|
16 |
import org.distorted.objectlib.algsolvers.implemented.PhasedSolver3x3Beginner; |
|
17 |
import org.distorted.objectlib.algsolvers.implemented.PhasedSolverAbstract; |
|
18 |
import org.distorted.objectlib.helpers.OperatingSystemInterface; |
|
19 |
import org.distorted.objectlib.main.TwistyObject; |
|
20 |
import org.distorted.solverui.ScreenList; |
|
21 |
import org.distorted.solverui.ScreenPhasedSolution; |
|
22 |
import org.distorted.solverui.ScreenSolver; |
|
23 |
|
|
24 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
25 |
|
|
26 |
public abstract class SolverAlgorithmic implements SolvingInterface, SolutionListener |
|
27 |
{ |
|
28 |
private final SolvedObject mSolvedObject; |
|
29 |
private final PhasedSolverAbstract mSolver; |
|
30 |
private final OperatingSystemInterface mOS; |
|
31 |
private final Resources mRes; |
|
32 |
private final TwistyObject mObject; |
|
33 |
private long mTime; |
|
34 |
private ScreenSolver mScreen; |
|
35 |
|
|
36 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
37 |
// PUBLIC API |
|
38 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
39 |
|
|
40 |
public SolverAlgorithmic(OperatingSystemInterface os, Resources res, TwistyObject object) |
|
41 |
{ |
|
42 |
mOS = os; |
|
43 |
mRes = res; |
|
44 |
mObject = object; |
|
45 |
mSolver = new PhasedSolver3x3Beginner(); |
|
46 |
mSolvedObject = mSolver.getObject(); |
|
47 |
} |
|
48 |
|
|
49 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
50 |
|
|
51 |
abstract int[] validatePosition(TwistyObject object); |
|
52 |
abstract String getError(Resources res); |
|
53 |
|
|
54 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
55 |
|
|
56 |
public void solve(ScreenSolver screen) |
|
57 |
{ |
|
58 |
mScreen = screen; |
|
59 |
int[] quats = validatePosition(mObject); |
|
60 |
|
|
61 |
if( quats!=null ) |
|
62 |
{ |
|
63 |
int numPhases = mSolver.getNumPhases(); |
|
64 |
String[] names = new String[numPhases]; |
|
65 |
for(int p=0; p<numPhases; p++) names[p] = mSolver.getPhaseName(p); |
|
66 |
ScreenPhasedSolution solScreen = (ScreenPhasedSolution) ScreenList.PHAS.getScreenClass(); |
|
67 |
solScreen.updateNames(names); |
|
68 |
mTime = System.currentTimeMillis(); |
|
69 |
mSolver.solution(this,quats); |
|
70 |
} |
|
71 |
else |
|
72 |
{ |
|
73 |
String error = getError(mRes); |
|
74 |
screen.displayImpossibleDialog(error); |
|
75 |
} |
|
76 |
} |
|
77 |
|
|
78 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
79 |
|
|
80 |
public void receiveSolution(int[] solution, int phaseNumber) |
|
81 |
{ |
|
82 |
if( solution==null ) |
|
83 |
{ |
|
84 |
String message = "Phase "+phaseNumber+": FAIL"; |
|
85 |
System.out.println(message); |
|
86 |
} |
|
87 |
else |
|
88 |
{ |
|
89 |
int numMoves = solution[0]; |
|
90 |
int[][] moves = new int[numMoves][]; |
|
91 |
int index = 0; |
|
92 |
|
|
93 |
for(int m=1; m<=numMoves; m++) |
|
94 |
moves[index++] = mSolvedObject.findMove(solution[m]); |
|
95 |
|
|
96 |
int[][] subphases = mSolver.getSubPhases(phaseNumber); |
|
97 |
mScreen.setSolved(moves,phaseNumber,subphases); |
|
98 |
} |
|
99 |
|
|
100 |
long time = System.currentTimeMillis(); |
|
101 |
long diff = time - mTime; |
|
102 |
mTime = time; |
|
103 |
|
|
104 |
System.out.println("Phase "+phaseNumber+" solved in "+diff+"ms. Moves: "+(solution==null ? 0:solution[0])); |
|
105 |
} |
|
106 |
} |
|
107 |
|
src/main/java/org/distorted/solvers/SolverAlgorithmicCUBE3.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2024 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.solvers; |
|
11 |
|
|
12 |
import android.content.res.Resources; |
|
13 |
|
|
14 |
import org.distorted.objectlib.helpers.OperatingSystemInterface; |
|
15 |
import org.distorted.objectlib.main.TwistyObject; |
|
16 |
import org.distorted.solverui.SolverActivity; |
|
17 |
|
|
18 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
19 |
|
|
20 |
public class SolverAlgorithmicCUBE3 extends SolverAlgorithmic |
|
21 |
{ |
|
22 |
public SolverAlgorithmicCUBE3(OperatingSystemInterface os, Resources res, TwistyObject object) |
|
23 |
{ |
|
24 |
super(os,res,object); |
|
25 |
} |
|
26 |
|
|
27 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
28 |
|
|
29 |
int[] validatePosition(TwistyObject object) |
|
30 |
{ |
|
31 |
int numCubits = object.getNumCubits(); |
|
32 |
int[] ret = new int[numCubits]; // mockup |
|
33 |
return ret; |
|
34 |
} |
|
35 |
|
|
36 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
37 |
|
|
38 |
String getError(Resources res) |
|
39 |
{ |
|
40 |
return null; |
|
41 |
} |
|
42 |
} |
|
43 |
|
src/main/java/org/distorted/solvers/SolverKociembaCUBE3.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2023 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.solvers; |
|
11 |
|
|
12 |
import android.content.res.Resources; |
|
13 |
|
|
14 |
import org.distorted.main.R; |
|
15 |
import org.distorted.objectlib.helpers.OperatingSystemInterface; |
|
16 |
import org.distorted.solverui.ScreenSolver; |
|
17 |
import org.distorted.objectlib.main.TwistyObject; |
|
18 |
import org.distorted.objectlib.kociemba.SolverSearch; |
|
19 |
|
|
20 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
21 |
|
|
22 |
public class SolverKociembaCUBE3 implements SolvingInterface |
|
23 |
{ |
|
24 |
private final Resources mRes; |
|
25 |
private final OperatingSystemInterface mOS; |
|
26 |
private final TwistyObject mObject; |
|
27 |
private int mColorID; |
|
28 |
|
|
29 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
30 |
|
|
31 |
private int mapCubitToFace(int cubit, int face) |
|
32 |
{ |
|
33 |
if( cubit<8 ) |
|
34 |
{ |
|
35 |
switch(face) |
|
36 |
{ |
|
37 |
case 0: return 1; |
|
38 |
case 1: if( cubit==2 ) return 5; |
|
39 |
if( cubit==1 ) return 3; |
|
40 |
return 1; |
|
41 |
case 2: return cubit==7 ? 5 : 3; |
|
42 |
case 3: if( cubit==1 ) return 1; |
|
43 |
return cubit==4 ? 5 : 3; |
|
44 |
case 4: return cubit==7 ? 3 : 5; |
|
45 |
case 5: if( cubit==2 ) return 1; |
|
46 |
if( cubit==4 ) return 3; |
|
47 |
return 5; |
|
48 |
} |
|
49 |
} |
|
50 |
|
|
51 |
if( cubit>19 ) return 4; |
|
52 |
|
|
53 |
switch(face) |
|
54 |
{ |
|
55 |
case 0: return cubit==15 || cubit==18 ? 3 : 5; |
|
56 |
case 1: return cubit==13 || cubit==16 ? 3 : 5; |
|
57 |
case 2: return cubit==10 ? 5 : 3; |
|
58 |
case 3: return cubit== 8 ? 3 : 5; |
|
59 |
case 4: return cubit== 9 ? 3 : 5; |
|
60 |
case 5: return cubit== 8 ? 5 : 3; |
|
61 |
} |
|
62 |
|
|
63 |
return -1; |
|
64 |
} |
|
65 |
|
|
66 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
67 |
|
|
68 |
private int checkPosition(String position) |
|
69 |
{ |
|
70 |
int[] numColors = new int[6]; |
|
71 |
int len = position.length(); |
|
72 |
|
|
73 |
for(int i=0; i<len; i++) |
|
74 |
{ |
|
75 |
char ch = position.charAt(i); |
|
76 |
|
|
77 |
switch(ch) |
|
78 |
{ |
|
79 |
case 'R': numColors[0]++; break; |
|
80 |
case 'L': numColors[1]++; break; |
|
81 |
case 'U': numColors[2]++; break; |
|
82 |
case 'D': numColors[3]++; break; |
|
83 |
case 'F': numColors[4]++; break; |
|
84 |
case 'B': numColors[5]++; break; |
|
85 |
} |
|
86 |
} |
|
87 |
|
|
88 |
if( numColors[0]<9 ) { mColorID = R.string.color_yellow1; return numColors[0]; } |
|
89 |
if( numColors[1]<9 ) { mColorID = R.string.color_white1 ; return numColors[1]; } |
|
90 |
if( numColors[2]<9 ) { mColorID = R.string.color_blue1 ; return numColors[2]; } |
|
91 |
if( numColors[3]<9 ) { mColorID = R.string.color_green1 ; return numColors[3]; } |
|
92 |
if( numColors[4]<9 ) { mColorID = R.string.color_red1 ; return numColors[4]; } |
|
93 |
if( numColors[5]<9 ) { mColorID = R.string.color_orange1; return numColors[5]; } |
|
94 |
|
|
95 |
return -1; |
|
96 |
} |
|
97 |
|
|
98 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
99 |
// order: Up --> Right --> Front --> Down --> Left --> Back |
|
100 |
// (because the first implemented Solver - the two-phase Cube3 one - expects such order) |
|
101 |
// |
|
102 |
// Solved 3x3x3 Cube maps to "UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB" |
|
103 |
|
|
104 |
private String preparePosition() |
|
105 |
{ |
|
106 |
StringBuilder objectString = new StringBuilder(); |
|
107 |
|
|
108 |
final int R = 0; |
|
109 |
final int L = 1; |
|
110 |
final int U = 2; |
|
111 |
final int D = 3; |
|
112 |
final int F = 4; |
|
113 |
final int B = 5; |
|
114 |
|
|
115 |
// 'I' - interior, theoretically can happen |
|
116 |
final char[] FACE_NAMES = { 'R', 'L', 'U', 'D', 'F', 'B', 'I'}; |
|
117 |
|
|
118 |
final int[] U_INDEX = { 2,10, 6,17,22,19, 3,11, 7}; |
|
119 |
final int[] R_INDEX = { 7,19, 6,15,20,14, 5,18, 4}; |
|
120 |
final int[] F_INDEX = { 3,11, 7,13,24,15, 1, 9, 5}; |
|
121 |
final int[] D_INDEX = { 1, 9, 5,16,23,18, 0, 8, 4}; |
|
122 |
final int[] L_INDEX = { 2,17, 3,12,21,13, 0,16, 1}; |
|
123 |
final int[] B_INDEX = { 6,10, 2,14,25,12, 4, 8, 0}; |
|
124 |
|
|
125 |
for(int i=0; i<9; i++) |
|
126 |
{ |
|
127 |
int face = mapCubitToFace(U_INDEX[i],U); |
|
128 |
int color = mObject.getCubitFaceStickerIndex(U_INDEX[i], face); |
|
129 |
objectString.append(FACE_NAMES[color]); |
|
130 |
} |
|
131 |
for(int i=0; i<9; i++) |
|
132 |
{ |
|
133 |
int face = mapCubitToFace(R_INDEX[i],R); |
|
134 |
int color = mObject.getCubitFaceStickerIndex(R_INDEX[i], face); |
|
135 |
objectString.append(FACE_NAMES[color]); |
|
136 |
} |
|
137 |
for(int i=0; i<9; i++) |
|
138 |
{ |
|
139 |
int face = mapCubitToFace(F_INDEX[i],F); |
|
140 |
int color = mObject.getCubitFaceStickerIndex(F_INDEX[i], face); |
|
141 |
objectString.append(FACE_NAMES[color]); |
|
142 |
} |
|
143 |
for(int i=0; i<9; i++) |
|
144 |
{ |
|
145 |
int face = mapCubitToFace(D_INDEX[i],D); |
|
146 |
int color = mObject.getCubitFaceStickerIndex(D_INDEX[i], face); |
|
147 |
objectString.append(FACE_NAMES[color]); |
|
148 |
} |
|
149 |
for(int i=0; i<9; i++) |
|
150 |
{ |
|
151 |
int face = mapCubitToFace(L_INDEX[i],L); |
|
152 |
int color = mObject.getCubitFaceStickerIndex(L_INDEX[i], face); |
|
153 |
objectString.append(FACE_NAMES[color]); |
|
154 |
} |
|
155 |
for(int i=0; i<9; i++) |
|
156 |
{ |
|
157 |
int face = mapCubitToFace(B_INDEX[i],B); |
|
158 |
int color = mObject.getCubitFaceStickerIndex(B_INDEX[i], face); |
|
159 |
objectString.append(FACE_NAMES[color]); |
|
160 |
} |
|
161 |
|
|
162 |
return objectString.toString(); |
|
163 |
} |
|
164 |
|
|
165 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
166 |
// PUBLIC API |
|
167 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
168 |
|
|
169 |
public SolverKociembaCUBE3(OperatingSystemInterface os, Resources res, TwistyObject object) |
|
170 |
{ |
|
171 |
mRes = res; |
|
172 |
mOS = os; |
|
173 |
mObject= object; |
|
174 |
} |
|
175 |
|
|
176 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
177 |
|
|
178 |
public void solve(ScreenSolver solver) |
|
179 |
{ |
|
180 |
String result; |
|
181 |
|
|
182 |
SolverSearch.prepare(mOS); |
|
183 |
String objectPosition = preparePosition(); |
|
184 |
int check = checkPosition(objectPosition); |
|
185 |
|
|
186 |
if( check<0 ) |
|
187 |
{ |
|
188 |
result = SolverSearch.solution(objectPosition, 24, 20); |
|
189 |
|
|
190 |
if( result.contains("Error") ) |
|
191 |
{ |
|
192 |
switch( result.charAt(result.length()-1) ) |
|
193 |
{ |
|
194 |
case '1': result = mRes.getString(R.string.solver_cube3_error1); break; |
|
195 |
case '2': result = mRes.getString(R.string.solver_cube3_error2); break; |
|
196 |
case '3': result = mRes.getString(R.string.solver_generic_edge_twist); break; |
|
197 |
case '4': result = mRes.getString(R.string.solver_cube3_error4); break; |
|
198 |
case '5': result = mRes.getString(R.string.solver_generic_corner_twist); break; |
|
199 |
case '6': result = mRes.getString(R.string.solver_cube3_error6); break; |
|
200 |
case '7': result = mRes.getString(R.string.solver_cube3_error7); break; |
|
201 |
case '8': result = mRes.getString(R.string.solver_cube3_error8); break; |
|
202 |
case '9': result = mRes.getString(R.string.solver_cube3_error9); break; |
|
203 |
} |
|
204 |
|
|
205 |
solver.displayImpossibleDialog(result); |
|
206 |
} |
|
207 |
else |
|
208 |
{ |
|
209 |
solver.setSolved(result); |
|
210 |
} |
|
211 |
} |
|
212 |
else |
|
213 |
{ |
|
214 |
String color = mRes.getString(mColorID); |
|
215 |
result = mRes.getString(R.string.solver_cube3_error1,check,color); |
|
216 |
solver.displayImpossibleDialog(result); |
|
217 |
} |
|
218 |
} |
|
219 |
} |
|
220 |
|
src/main/java/org/distorted/solvers/SolverTablebase.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2023 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.solvers; |
|
11 |
|
|
12 |
import android.content.res.Resources; |
|
13 |
|
|
14 |
import org.distorted.main.R; |
|
15 |
import org.distorted.objectlib.helpers.OperatingSystemInterface; |
|
16 |
import org.distorted.objectlib.main.TwistyObject; |
|
17 |
import org.distorted.objectlib.tablebases.ImplementedTablebasesList; |
|
18 |
import org.distorted.objectlib.tablebases.TablebasesAbstract; |
|
19 |
import org.distorted.solverui.ScreenSolver; |
|
20 |
|
|
21 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
22 |
|
|
23 |
public abstract class SolverTablebase implements SolvingInterface |
|
24 |
{ |
|
25 |
private static final int[][] colorsHex = |
|
26 |
{ |
|
27 |
{R.string.color_yellow1,R.string.color_yellow2,R.string.color_yellow3,R.string.color_yellow4,R.string.color_yellow5,R.string.color_yellow6,R.string.color_yellow7 }, |
|
28 |
{R.string.color_white1 ,R.string.color_white2 ,R.string.color_white3 ,R.string.color_white4 ,R.string.color_white5 ,R.string.color_white6 ,R.string.color_white7 }, |
|
29 |
{R.string.color_blue1 ,R.string.color_blue2 ,R.string.color_blue3 ,R.string.color_blue4 ,R.string.color_blue5 ,R.string.color_blue6 ,R.string.color_blue7 }, |
|
30 |
{R.string.color_green1 ,R.string.color_green2 ,R.string.color_green3 ,R.string.color_green4 ,R.string.color_green5 ,R.string.color_green6 ,R.string.color_green7 }, |
|
31 |
{R.string.color_red1 ,R.string.color_red2 ,R.string.color_red3 ,R.string.color_red4 ,R.string.color_red5 ,R.string.color_red6 ,R.string.color_red7 }, |
|
32 |
{R.string.color_orange1,R.string.color_orange2,R.string.color_orange3,R.string.color_orange4,R.string.color_orange5,R.string.color_orange6,R.string.color_orange7 }, |
|
33 |
}; |
|
34 |
private static final int[][] colorsTet = |
|
35 |
{ |
|
36 |
{R.string.color_green1 ,R.string.color_green2 ,R.string.color_green3 ,R.string.color_green4 ,R.string.color_green5 ,R.string.color_green6 ,R.string.color_green7 }, |
|
37 |
{R.string.color_yellow1,R.string.color_yellow2,R.string.color_yellow3,R.string.color_yellow4,R.string.color_yellow5,R.string.color_yellow6,R.string.color_yellow7 }, |
|
38 |
{R.string.color_blue1 ,R.string.color_blue2 ,R.string.color_blue3 ,R.string.color_blue4 ,R.string.color_blue5 ,R.string.color_blue6 ,R.string.color_blue7 }, |
|
39 |
{R.string.color_red1 ,R.string.color_red2 ,R.string.color_red3 ,R.string.color_red4 ,R.string.color_red5 ,R.string.color_red6 ,R.string.color_red7 }, |
|
40 |
}; |
|
41 |
private static final int[][] colorsOct = |
|
42 |
{ |
|
43 |
{R.string.color_violet1,R.string.color_violet2,R.string.color_violet3,R.string.color_violet4,R.string.color_violet5,R.string.color_violet6,R.string.color_violet7 }, |
|
44 |
{R.string.color_grey1 ,R.string.color_grey2 ,R.string.color_grey3 ,R.string.color_grey4 ,R.string.color_grey5 ,R.string.color_grey6 ,R.string.color_grey7 }, |
|
45 |
{R.string.color_blue1 ,R.string.color_blue2 ,R.string.color_blue3 ,R.string.color_blue4 ,R.string.color_blue5 ,R.string.color_blue6 ,R.string.color_blue7 }, |
|
46 |
{R.string.color_red1 ,R.string.color_red2 ,R.string.color_red3 ,R.string.color_red4 ,R.string.color_red5 ,R.string.color_red6 ,R.string.color_red7 }, |
|
47 |
{R.string.color_orange1,R.string.color_orange2,R.string.color_orange3,R.string.color_orange4,R.string.color_orange5,R.string.color_orange6,R.string.color_orange7 }, |
|
48 |
{R.string.color_green1 ,R.string.color_green2 ,R.string.color_green3 ,R.string.color_green4 ,R.string.color_green5 ,R.string.color_green6 ,R.string.color_green7 }, |
|
49 |
{R.string.color_white1 ,R.string.color_white2 ,R.string.color_white3 ,R.string.color_white4 ,R.string.color_white5 ,R.string.color_white6 ,R.string.color_white7 }, |
|
50 |
{R.string.color_yellow1,R.string.color_yellow2,R.string.color_yellow3,R.string.color_yellow4,R.string.color_yellow5,R.string.color_yellow6,R.string.color_yellow7 }, |
|
51 |
}; |
|
52 |
|
|
53 |
private final OperatingSystemInterface mOS; |
|
54 |
private final Resources mRes; |
|
55 |
private final TwistyObject mObject; |
|
56 |
private TablebasesAbstract mSolver; |
|
57 |
|
|
58 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
59 |
|
|
60 |
public abstract int tablebaseIndex(TwistyObject object); |
|
61 |
public abstract String error(int index, Resources res); |
|
62 |
|
|
63 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
64 |
// PUBLIC API |
|
65 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
66 |
|
|
67 |
public SolverTablebase(OperatingSystemInterface os, Resources res, TwistyObject object) |
|
68 |
{ |
|
69 |
mOS = os; |
|
70 |
mRes = res; |
|
71 |
mObject= object; |
|
72 |
} |
|
73 |
|
|
74 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
75 |
|
|
76 |
int getHexColor(int color,int variant) { return colorsHex[color][variant]; } |
|
77 |
int getTetColor(int color,int variant) { return colorsTet[color][variant]; } |
|
78 |
int getOctColor(int color,int variant) { return colorsOct[color][variant]; } |
|
79 |
int[] getExtra() { return null; } |
|
80 |
|
|
81 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
82 |
|
|
83 |
public void solve(ScreenSolver screen) |
|
84 |
{ |
|
85 |
int index = tablebaseIndex(mObject); |
|
86 |
|
|
87 |
if( index>=0 ) |
|
88 |
{ |
|
89 |
if( mSolver==null ) |
|
90 |
{ |
|
91 |
mSolver = ImplementedTablebasesList.createPacked(mOS, mObject.getShortName() ); |
|
92 |
} |
|
93 |
|
|
94 |
mSolver.initialize(); |
|
95 |
int[][] moves = mSolver!=null ? mSolver.solution(index,getExtra(),mOS) : null; |
|
96 |
screen.setSolved(moves); |
|
97 |
} |
|
98 |
else |
|
99 |
{ |
|
100 |
String error = error(index,mRes); |
|
101 |
screen.displayImpossibleDialog(error); |
|
102 |
} |
|
103 |
} |
|
104 |
} |
|
105 |
|
src/main/java/org/distorted/solvers/SolverTablebaseCU232.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2023 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.solvers; |
|
11 |
|
|
12 |
import android.content.res.Resources; |
|
13 |
|
|
14 |
import org.distorted.main.R; |
|
15 |
import org.distorted.objectlib.helpers.OperatingSystemInterface; |
|
16 |
import org.distorted.objectlib.main.TwistyObject; |
|
17 |
import org.distorted.objectlib.tablebases.TablebaseHelpers; |
|
18 |
|
|
19 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
20 |
|
|
21 |
public class SolverTablebaseCU232 extends SolverTablebase |
|
22 |
{ |
|
23 |
private static final int ERROR_CORNER_MISSING = -1; |
|
24 |
private static final int ERROR_EDGE_MISSING = -2; |
|
25 |
private static final int ERROR_CORNERS_CANNOT = -3; |
|
26 |
private static final int ERROR_EDGE_TWISTED = -4; |
|
27 |
private static final int ERROR_CORNER_TWISTED = -5; |
|
28 |
|
|
29 |
private final int[] mFaceColors; |
|
30 |
private int mErrColor1, mErrColor2, mErrColor3; |
|
31 |
|
|
32 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
33 |
|
|
34 |
private int edgeIs(int[] edge, int i0, int i1) |
|
35 |
{ |
|
36 |
int c0 = mFaceColors[i0]; |
|
37 |
int c1 = mFaceColors[i1]; |
|
38 |
|
|
39 |
if( edge[0]==c0 && edge[1]==c1 ) return 0; |
|
40 |
if( edge[0]==c1 && edge[1]==c0 ) return 1; |
|
41 |
return 2; |
|
42 |
} |
|
43 |
|
|
44 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
45 |
|
|
46 |
private int retEdgePermutation(int[] output, int[][] edges) |
|
47 |
{ |
|
48 |
for(int i=0; i<4; i++) output[i] = -1; |
|
49 |
|
|
50 |
for(int i=0; i<4; i++) |
|
51 |
{ |
|
52 |
int edge0 = edgeIs(edges[i],1,5); |
|
53 |
if( edge0==0 ) output[0]=i; |
|
54 |
else if( edge0==1 ) return ERROR_EDGE_TWISTED; |
|
55 |
|
|
56 |
int edge1 = edgeIs(edges[i],1,4); |
|
57 |
if( edge1==0 ) output[1]=i; |
|
58 |
else if( edge1==1 ) return ERROR_EDGE_TWISTED; |
|
59 |
|
|
60 |
int edge2 = edgeIs(edges[i],0,5); |
|
61 |
if( edge2==0 ) output[2]=i; |
|
62 |
else if( edge2==1 ) return ERROR_EDGE_TWISTED; |
|
63 |
|
|
64 |
int edge3 = edgeIs(edges[i],0,4); |
|
65 |
if( edge3==0 ) output[3]=i; |
|
66 |
else if( edge3==1 ) return ERROR_EDGE_TWISTED; |
|
67 |
} |
|
68 |
|
|
69 |
if( output[0]==-1 ) { mErrColor1=1; mErrColor2=5; return ERROR_EDGE_MISSING; } |
|
70 |
if( output[1]==-1 ) { mErrColor1=1; mErrColor2=4; return ERROR_EDGE_MISSING; } |
|
71 |
if( output[2]==-1 ) { mErrColor1=0; mErrColor2=5; return ERROR_EDGE_MISSING; } |
|
72 |
if( output[3]==-1 ) { mErrColor1=0; mErrColor2=4; return ERROR_EDGE_MISSING; } |
|
73 |
|
|
74 |
return 0; |
|
75 |
} |
|
76 |
|
|
77 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
78 |
|
|
79 |
private int cornerIs(int[] corner, int i0, int i1, int i2) |
|
80 |
{ |
|
81 |
int c0 = mFaceColors[i0]; |
|
82 |
int c1 = mFaceColors[i1]; |
|
83 |
int c2 = mFaceColors[i2]; |
|
84 |
|
|
85 |
if( corner[0]==c0 && corner[1]==c1 && corner[2]==c2 ) return 0; |
|
86 |
|
|
87 |
if( corner[0]==c0 && corner[1]==c2 && corner[2]==c1 || |
|
88 |
corner[0]==c1 && corner[1]==c0 && corner[2]==c2 || |
|
89 |
corner[0]==c1 && corner[1]==c2 && corner[2]==c0 || |
|
90 |
corner[0]==c2 && corner[1]==c0 && corner[2]==c1 || |
|
91 |
corner[0]==c2 && corner[1]==c1 && corner[2]==c0 ) return 1; |
|
92 |
|
|
93 |
return 2; |
|
94 |
} |
|
95 |
|
|
96 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
97 |
|
|
98 |
private int retCornerPermutation(int[] output, int[][] corners) |
|
99 |
{ |
|
100 |
for(int i=0; i<8; i++) output[i] = -1; |
|
101 |
|
|
102 |
for(int i=0; i<8; i++) |
|
103 |
{ |
|
104 |
int corner7 = cornerIs(corners[i],2,4,0); |
|
105 |
if( corner7==0 ) output[7]=i; |
|
106 |
else if( corner7==1 ) return ERROR_CORNER_TWISTED; |
|
107 |
|
|
108 |
int corner6 = cornerIs(corners[i],2,0,5); |
|
109 |
if( corner6==0 ) output[6]=i; |
|
110 |
else if( corner6==1 ) return ERROR_CORNER_TWISTED; |
|
111 |
|
|
112 |
int corner5 = cornerIs(corners[i],3,0,4); |
|
113 |
if( corner5==0 ) output[5]=i; |
|
114 |
else if( corner5==1 ) return ERROR_CORNER_TWISTED; |
|
115 |
|
|
116 |
int corner4 = cornerIs(corners[i],3,5,0); |
|
117 |
if( corner4==0 ) output[4]=i; |
|
118 |
else if( corner4==1 ) return ERROR_CORNER_TWISTED; |
|
119 |
|
|
120 |
int corner3 = cornerIs(corners[i],2,1,4); |
|
121 |
if( corner3==0 ) output[3]=i; |
|
122 |
else if( corner3==1 ) return ERROR_CORNER_TWISTED; |
|
123 |
|
|
124 |
int corner2 = cornerIs(corners[i],2,5,1); |
|
125 |
if( corner2==0 ) output[2]=i; |
|
126 |
else if( corner2==1 ) return ERROR_CORNER_TWISTED; |
|
127 |
|
|
128 |
int corner1 = cornerIs(corners[i],3,4,1); |
|
129 |
if( corner1==0 ) output[1]=i; |
|
130 |
else if( corner1==1 ) return ERROR_CORNER_TWISTED; |
|
131 |
|
|
132 |
int corner0 = cornerIs(corners[i],3,1,5); |
|
133 |
if( corner0==0 ) output[0]=i; |
|
134 |
else if( corner0==1 ) return ERROR_CORNER_TWISTED; |
|
135 |
} |
|
136 |
|
|
137 |
if( output[0]==-1 ) { mErrColor1=1; mErrColor2=3; mErrColor3=5; return ERROR_CORNER_MISSING; } |
|
138 |
if( output[1]==-1 ) { mErrColor1=1; mErrColor2=3; mErrColor3=4; return ERROR_CORNER_MISSING; } |
|
139 |
if( output[2]==-1 ) { mErrColor1=1; mErrColor2=2; mErrColor3=5; return ERROR_CORNER_MISSING; } |
|
140 |
if( output[3]==-1 ) { mErrColor1=1; mErrColor2=3; mErrColor3=4; return ERROR_CORNER_MISSING; } |
|
141 |
if( output[4]==-1 ) { mErrColor1=0; mErrColor2=3; mErrColor3=5; return ERROR_CORNER_MISSING; } |
|
142 |
if( output[5]==-1 ) { mErrColor1=0; mErrColor2=3; mErrColor3=4; return ERROR_CORNER_MISSING; } |
|
143 |
if( output[6]==-1 ) { mErrColor1=0; mErrColor2=2; mErrColor3=5; return ERROR_CORNER_MISSING; } |
|
144 |
if( output[7]==-1 ) { mErrColor1=0; mErrColor2=2; mErrColor3=4; return ERROR_CORNER_MISSING; } |
|
145 |
|
|
146 |
return 0; |
|
147 |
} |
|
148 |
|
|
149 |
//////////////////////////////////////////////////////////////////////////////////////// |
|
150 |
|
|
151 |
private int computeFaceColors(int[][] corners, int[][] edges) |
|
152 |
{ |
|
153 |
mFaceColors[1] = edges[1][0]; |
|
154 |
mFaceColors[4] = edges[1][1]; |
|
155 |
|
|
156 |
if( edges[0][0]==mFaceColors[1] ) mFaceColors[5] = edges[0][1]; |
|
157 |
else if( edges[2][0]==mFaceColors[1] ) mFaceColors[5] = edges[2][1]; |
|
158 |
else if( edges[3][0]==mFaceColors[1] ) mFaceColors[5] = edges[3][1]; |
|
159 |
else return ERROR_EDGE_TWISTED; |
|
160 |
|
|
161 |
if( edges[0][1]==mFaceColors[4] ) mFaceColors[0] = edges[0][0]; |
|
162 |
else if( edges[2][1]==mFaceColors[4] ) mFaceColors[0] = edges[2][0]; |
|
163 |
else if( edges[3][1]==mFaceColors[4] ) mFaceColors[0] = edges[3][0]; |
|
164 |
else return ERROR_EDGE_TWISTED; |
|
165 |
|
|
166 |
boolean found2 = false; |
|
167 |
boolean found3 = false; |
|
168 |
|
|
169 |
for(int c=0; c<8; c++) |
|
170 |
{ |
|
171 |
if( !found3 && corners[c][1]==mFaceColors[4] && corners[c][2]==mFaceColors[1] ) |
|
172 |
{ |
|
173 |
found3=true; |
|
174 |
mFaceColors[3] = corners[c][0]; |
|
175 |
} |
|
176 |
if( !found2 && corners[c][1]==mFaceColors[1] && corners[c][2]==mFaceColors[4] ) |
|
177 |
{ |
|
178 |
found2=true; |
|
179 |
mFaceColors[2] = corners[c][0]; |
|
180 |
} |
|
181 |
} |
|
182 |
|
|
183 |
if( !found2 || !found3 ) return ERROR_CORNERS_CANNOT; |
|
184 |
|
|
185 |
for(int i=0; i<6; i++) |
|
186 |
for(int j=i+1; j<6; j++) |
|
187 |
if( mFaceColors[i]==mFaceColors[j] ) return ERROR_CORNERS_CANNOT; |
|
188 |
|
|
189 |
return 0; |
|
190 |
} |
|
191 |
|
|
192 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
193 |
|
|
194 |
private int[] correctEdgePerm(int[] perm) |
|
195 |
{ |
|
196 |
int[] ret = new int[3]; |
|
197 |
|
|
198 |
ret[0] = perm[0]; |
|
199 |
ret[1] = perm[2]; |
|
200 |
ret[2] = perm[3]; |
|
201 |
|
|
202 |
if( ret[0]>1 ) ret[0]--; |
|
203 |
if( ret[1]>1 ) ret[1]--; |
|
204 |
if( ret[2]>1 ) ret[2]--; |
|
205 |
|
|
206 |
return ret; |
|
207 |
} |
|
208 |
|
|
209 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
210 |
|
|
211 |
public SolverTablebaseCU232(OperatingSystemInterface os, Resources res, TwistyObject object) |
|
212 |
{ |
|
213 |
super(os,res,object); |
|
214 |
mFaceColors = new int[6]; |
|
215 |
} |
|
216 |
|
|
217 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
218 |
|
|
219 |
public int tablebaseIndex(TwistyObject object) |
|
220 |
{ |
|
221 |
int[][] corners= new int[8][3]; |
|
222 |
int[][] edges = new int[4][2]; |
|
223 |
|
|
224 |
corners[0][0] = object.getCubitFaceStickerIndex(0,3); |
|
225 |
corners[0][1] = object.getCubitFaceStickerIndex(0,1); |
|
226 |
corners[0][2] = object.getCubitFaceStickerIndex(0,5); |
|
227 |
|
|
228 |
corners[1][0] = object.getCubitFaceStickerIndex(1,1); |
|
229 |
corners[1][1] = object.getCubitFaceStickerIndex(1,5); |
|
230 |
corners[1][2] = object.getCubitFaceStickerIndex(1,3); |
|
231 |
|
|
232 |
corners[2][0] = object.getCubitFaceStickerIndex(2,3); |
|
233 |
corners[2][1] = object.getCubitFaceStickerIndex(2,1); |
|
234 |
corners[2][2] = object.getCubitFaceStickerIndex(2,5); |
|
235 |
|
|
236 |
corners[3][0] = object.getCubitFaceStickerIndex(3,3); |
|
237 |
corners[3][1] = object.getCubitFaceStickerIndex(3,1); |
|
238 |
corners[3][2] = object.getCubitFaceStickerIndex(3,5); |
|
239 |
|
|
240 |
corners[4][0] = object.getCubitFaceStickerIndex(4,5); |
|
241 |
corners[4][1] = object.getCubitFaceStickerIndex(4,3); |
|
242 |
corners[4][2] = object.getCubitFaceStickerIndex(4,1); |
|
243 |
|
|
244 |
corners[5][0] = object.getCubitFaceStickerIndex(5,3); |
|
245 |
corners[5][1] = object.getCubitFaceStickerIndex(5,1); |
|
246 |
corners[5][2] = object.getCubitFaceStickerIndex(5,5); |
|
247 |
|
|
248 |
corners[6][0] = object.getCubitFaceStickerIndex(6,3); |
|
249 |
corners[6][1] = object.getCubitFaceStickerIndex(6,1); |
|
250 |
corners[6][2] = object.getCubitFaceStickerIndex(6,5); |
|
251 |
|
|
252 |
corners[7][0] = object.getCubitFaceStickerIndex(7,5); |
|
253 |
corners[7][1] = object.getCubitFaceStickerIndex(7,3); |
|
254 |
corners[7][2] = object.getCubitFaceStickerIndex(7,1); |
|
255 |
|
|
256 |
edges[0][0] = object.getCubitFaceStickerIndex(8,5); |
|
257 |
edges[0][1] = object.getCubitFaceStickerIndex(8,3); |
|
258 |
edges[1][0] = object.getCubitFaceStickerIndex(9,3); |
|
259 |
edges[1][1] = object.getCubitFaceStickerIndex(9,5); |
|
260 |
edges[2][0] = object.getCubitFaceStickerIndex(10,5); |
|
261 |
edges[2][1] = object.getCubitFaceStickerIndex(10,3); |
|
262 |
edges[3][0] = object.getCubitFaceStickerIndex(11,3); |
|
263 |
edges[3][1] = object.getCubitFaceStickerIndex(11,5); |
|
264 |
|
|
265 |
int result0 = computeFaceColors(corners, edges); |
|
266 |
if( result0<0 ) return result0; |
|
267 |
|
|
268 |
int[] corner_perm = new int[8]; |
|
269 |
int result1 = retCornerPermutation(corner_perm,corners); |
|
270 |
if( result1<0 ) return result1; |
|
271 |
|
|
272 |
int[] edge_perm = new int[4]; |
|
273 |
int result2 = retEdgePermutation(edge_perm,edges); |
|
274 |
if( result2<0 ) return result2; |
|
275 |
|
|
276 |
int[] edge_perm2 = correctEdgePerm(edge_perm); // edge1 is fixed! |
|
277 |
|
|
278 |
int corner_perm_num = TablebaseHelpers.computePermutationNum(corner_perm); |
|
279 |
int edge_perm_num = TablebaseHelpers.computePermutationNum(edge_perm2); |
|
280 |
|
|
281 |
return edge_perm_num + 6*corner_perm_num; |
|
282 |
} |
|
283 |
|
|
284 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
285 |
|
|
286 |
private String edgeError(Resources res, int face0, int face1) |
|
287 |
{ |
|
288 |
int j0 = getHexColor(face0,3); |
|
289 |
int j1 = getHexColor(face1,6); |
|
290 |
|
|
291 |
String c0 = res.getString(j0); |
|
292 |
String c1 = res.getString(j1); |
|
293 |
|
|
294 |
return res.getString(R.string.solver_generic_missing_edge,c0,c1); |
|
295 |
} |
|
296 |
|
|
297 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
298 |
|
|
299 |
private String cornerError(Resources res, int face0, int face1, int face2) |
|
300 |
{ |
|
301 |
int j0 = getHexColor(face0,3); |
|
302 |
int j1 = getHexColor(face1,3); |
|
303 |
int j2 = getHexColor(face2,4); |
|
304 |
|
|
305 |
String c0 = res.getString(j0); |
|
306 |
String c1 = res.getString(j1); |
|
307 |
String c2 = res.getString(j2); |
|
308 |
|
|
309 |
return res.getString(R.string.solver_generic_missing_corner,c0,c1,c2); |
|
310 |
} |
|
311 |
|
|
312 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
313 |
|
|
314 |
public String error(int index, Resources res) |
|
315 |
{ |
|
316 |
switch(index) |
|
317 |
{ |
|
318 |
case ERROR_CORNER_MISSING: return cornerError(res,mErrColor1,mErrColor2,mErrColor3); |
|
319 |
case ERROR_EDGE_MISSING : return edgeError(res,mErrColor1,mErrColor2); |
|
320 |
case ERROR_CORNERS_CANNOT: return res.getString(R.string.solver_generic_corners_cannot); |
|
321 |
case ERROR_EDGE_TWISTED : return res.getString(R.string.solver_generic_edge_twist); |
|
322 |
case ERROR_CORNER_TWISTED: return res.getString(R.string.solver_generic_corner_twist); |
|
323 |
} |
|
324 |
|
|
325 |
return null; |
|
326 |
} |
|
327 |
} |
|
328 |
|
src/main/java/org/distorted/solvers/SolverTablebaseCU323.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2023 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.solvers; |
|
11 |
|
|
12 |
import android.content.res.Resources; |
|
13 |
|
|
14 |
import org.distorted.main.R; |
|
15 |
import org.distorted.objectlib.helpers.OperatingSystemInterface; |
|
16 |
import org.distorted.objectlib.main.TwistyObject; |
|
17 |
import org.distorted.objectlib.tablebases.TBCuboid323; |
|
18 |
import org.distorted.objectlib.tablebases.TablebaseHelpers; |
|
19 |
|
|
20 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
21 |
// a few cu_323 max (depth 18) indices: 1180633, 1180642, 1182044, 1190482, 128151851, 128190028 |
|
22 |
|
|
23 |
public class SolverTablebaseCU323 extends SolverTablebase |
|
24 |
{ |
|
25 |
private static final int ERROR_CORNER_MISSING = -1; |
|
26 |
private static final int ERROR_EDGE_MISSING = -2; |
|
27 |
private static final int ERROR_CORNERS_CANNOT = -3; |
|
28 |
private static final int ERROR_EDGE_TWISTED = -4; |
|
29 |
private static final int ERROR_CORNER_TWISTED = -5; |
|
30 |
|
|
31 |
private final int[] mFaceColors; |
|
32 |
private int mErrColor1, mErrColor2, mErrColor3; |
|
33 |
|
|
34 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
35 |
|
|
36 |
public SolverTablebaseCU323(OperatingSystemInterface os, Resources res, TwistyObject object) |
|
37 |
{ |
|
38 |
super(os,res,object); |
|
39 |
mFaceColors = new int[6]; |
|
40 |
} |
|
41 |
|
|
42 |
//////////////////////////////////////////////////////////////////////////////////////// |
|
43 |
|
|
44 |
private int findCorner(int[][] corners, int c1, int c2) |
|
45 |
{ |
|
46 |
for(int i=0; i<8; i++) |
|
47 |
{ |
|
48 |
int[] c = corners[i]; |
|
49 |
|
|
50 |
if( c[0]==c1 && c[1]==c2 ) return c[2]; |
|
51 |
if( c[1]==c1 && c[2]==c2 ) return c[0]; |
|
52 |
if( c[2]==c1 && c[0]==c2 ) return c[1]; |
|
53 |
} |
|
54 |
|
|
55 |
return ERROR_CORNERS_CANNOT; |
|
56 |
} |
|
57 |
|
|
58 |
//////////////////////////////////////////////////////////////////////////////////////// |
|
59 |
|
|
60 |
private int missingColor() |
|
61 |
{ |
|
62 |
boolean[] present = new boolean[6]; |
|
63 |
for(int i=0; i<5; i++) present[mFaceColors[i]] = true; |
|
64 |
|
|
65 |
int indexFalse = -1; |
|
66 |
|
|
67 |
for(int i=0; i<6; i++) |
|
68 |
if( !present[i] ) |
|
69 |
{ |
|
70 |
if( indexFalse<0 ) indexFalse=i; |
|
71 |
else return ERROR_CORNERS_CANNOT; |
|
72 |
} |
|
73 |
|
|
74 |
return indexFalse; |
|
75 |
} |
|
76 |
|
|
77 |
//////////////////////////////////////////////////////////////////////////////////////// |
|
78 |
|
|
79 |
private int edgePresent(int[][] edges, int f0, int f1) |
|
80 |
{ |
|
81 |
int c0 = mFaceColors[f0]; |
|
82 |
int c1 = mFaceColors[f1]; |
|
83 |
|
|
84 |
for(int i=0; i<8; i++ ) |
|
85 |
{ |
|
86 |
int[] edge = edges[i]; |
|
87 |
|
|
88 |
if( edge[0]==c0 && edge[1]==c1 ) return i; |
|
89 |
if( edge[0]==c1 && edge[1]==c0 ) |
|
90 |
{ |
|
91 |
mErrColor1 = c0; |
|
92 |
mErrColor2 = c1; |
|
93 |
return ERROR_EDGE_TWISTED; |
|
94 |
} |
|
95 |
} |
|
96 |
|
|
97 |
mErrColor1 = c0; |
|
98 |
mErrColor2 = c1; |
|
99 |
return ERROR_EDGE_MISSING; |
|
100 |
} |
|
101 |
|
|
102 |
//////////////////////////////////////////////////////////////////////////////////////// |
|
103 |
|
|
104 |
private int cornerPresent(int[][] corners, int f0, int f1, int f2) |
|
105 |
{ |
|
106 |
int c0 = mFaceColors[f0]; |
|
107 |
int c1 = mFaceColors[f1]; |
|
108 |
int c2 = mFaceColors[f2]; |
|
109 |
|
|
110 |
for(int i=0; i<8; i++) |
|
111 |
{ |
|
112 |
int[] corner = corners[i]; |
|
113 |
|
|
114 |
if( corner[0]==c0 && corner[1]==c1 && corner[2]==c2 ) return i; |
|
115 |
if( (corner[0]==c1 && corner[1]==c2 && corner[2]==c0 ) || |
|
116 |
(corner[0]==c2 && corner[1]==c0 && corner[2]==c1 ) ) |
|
117 |
{ |
|
118 |
mErrColor1 = c0; |
|
119 |
mErrColor2 = c1; |
|
120 |
mErrColor3 = c2; |
|
121 |
return ERROR_CORNER_TWISTED; |
|
122 |
} |
|
123 |
} |
|
124 |
|
|
125 |
mErrColor1 = c0; |
|
126 |
mErrColor2 = c1; |
|
127 |
mErrColor3 = c2; |
|
128 |
return ERROR_CORNER_MISSING; |
|
129 |
} |
|
130 |
|
|
131 |
//////////////////////////////////////////////////////////////////////////////////////// |
|
132 |
|
|
133 |
private int retEdgePermutation(int[] output, int[][] edges) |
|
134 |
{ |
|
135 |
int[][] e = { {5,3}, {4,3}, {5,2}, {4,2}, {1,3}, {1,2}, {0,3}, {0,2} }; |
|
136 |
|
|
137 |
for(int i=0; i<8; i++) |
|
138 |
{ |
|
139 |
int[] ee = e[i]; |
|
140 |
output[i] = edgePresent(edges,ee[0],ee[1]); |
|
141 |
if( output[i]<0 ) return output[i]; |
|
142 |
} |
|
143 |
|
|
144 |
return 0; |
|
145 |
} |
|
146 |
|
|
147 |
//////////////////////////////////////////////////////////////////////////////////////// |
|
148 |
|
|
149 |
private int retCornerPermutation(int[] output, int[][] corners) |
|
150 |
{ |
|
151 |
int[][] c = { {5,1,3}, {1,4,3}, {1,5,2}, {4,1,2}, {0,5,3}, {4,0,3}, {5,0,2}, {0,4,2} }; |
|
152 |
|
|
153 |
for(int i=0; i<8; i++) |
|
154 |
{ |
|
155 |
int[] cc = c[i]; |
|
156 |
output[i] = cornerPresent(corners,cc[0],cc[1],cc[2]); |
|
157 |
if( output[i]<0 ) return output[i]; |
|
158 |
} |
|
159 |
|
|
160 |
return 0; |
|
161 |
} |
|
162 |
|
|
163 |
//////////////////////////////////////////////////////////////////////////////////////// |
|
164 |
|
|
165 |
private int computeFaceColors(int[][] corners, int[][] edges, int[] centers) |
|
166 |
{ |
|
167 |
mFaceColors[4] = edges[1][0]; |
|
168 |
mFaceColors[3] = edges[1][1]; |
|
169 |
|
|
170 |
if( centers[0]!=mFaceColors[3] ) mFaceColors[2] = centers[0]; |
|
171 |
else if( centers[1]!=mFaceColors[3] ) mFaceColors[2] = centers[1]; |
|
172 |
else return ERROR_CORNERS_CANNOT; |
|
173 |
|
|
174 |
mFaceColors[0] = findCorner(corners,mFaceColors[4],mFaceColors[2]); |
|
175 |
if( mFaceColors[0]<0 ) return mFaceColors[0]; |
|
176 |
|
|
177 |
mFaceColors[1] = findCorner(corners,mFaceColors[2],mFaceColors[4]); |
|
178 |
if( mFaceColors[1]<0 ) return mFaceColors[1]; |
|
179 |
|
|
180 |
mFaceColors[5] = missingColor(); |
|
181 |
if( mFaceColors[5]<0 ) return mFaceColors[5]; |
|
182 |
|
|
183 |
return 0; |
|
184 |
} |
|
185 |
|
|
186 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
187 |
|
|
188 |
private void getCorners(TwistyObject object, int[][] corners) |
|
189 |
{ |
|
190 |
corners[0][0] = object.getCubitFaceStickerIndex(0,5); |
|
191 |
corners[0][1] = object.getCubitFaceStickerIndex(0,1); |
|
192 |
corners[0][2] = object.getCubitFaceStickerIndex(0,3); |
|
193 |
|
|
194 |
corners[1][0] = object.getCubitFaceStickerIndex(1,3); |
|
195 |
corners[1][1] = object.getCubitFaceStickerIndex(1,5); |
|
196 |
corners[1][2] = object.getCubitFaceStickerIndex(1,1); |
|
197 |
|
|
198 |
corners[2][0] = object.getCubitFaceStickerIndex(2,5); |
|
199 |
corners[2][1] = object.getCubitFaceStickerIndex(2,1); |
|
200 |
corners[2][2] = object.getCubitFaceStickerIndex(2,3); |
|
201 |
|
|
202 |
corners[3][0] = object.getCubitFaceStickerIndex(3,5); |
|
203 |
corners[3][1] = object.getCubitFaceStickerIndex(3,1); |
|
204 |
corners[3][2] = object.getCubitFaceStickerIndex(3,3); |
|
205 |
|
|
206 |
corners[4][0] = object.getCubitFaceStickerIndex(4,1); |
|
207 |
corners[4][1] = object.getCubitFaceStickerIndex(4,3); |
|
208 |
corners[4][2] = object.getCubitFaceStickerIndex(4,5); |
|
209 |
|
|
210 |
corners[5][0] = object.getCubitFaceStickerIndex(5,5); |
|
211 |
corners[5][1] = object.getCubitFaceStickerIndex(5,1); |
|
212 |
corners[5][2] = object.getCubitFaceStickerIndex(5,3); |
|
213 |
|
|
214 |
corners[6][0] = object.getCubitFaceStickerIndex(6,5); |
|
215 |
corners[6][1] = object.getCubitFaceStickerIndex(6,1); |
|
216 |
corners[6][2] = object.getCubitFaceStickerIndex(6,3); |
|
217 |
|
|
218 |
corners[7][0] = object.getCubitFaceStickerIndex(7,1); |
|
219 |
corners[7][1] = object.getCubitFaceStickerIndex(7,3); |
|
220 |
corners[7][2] = object.getCubitFaceStickerIndex(7,5); |
|
221 |
} |
|
222 |
|
|
223 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
224 |
|
|
225 |
private void getEdges(TwistyObject object, int[][] edges) |
|
226 |
{ |
|
227 |
edges[0][0] = object.getCubitFaceStickerIndex(8,5); |
|
228 |
edges[0][1] = object.getCubitFaceStickerIndex(8,3); |
|
229 |
edges[1][0] = object.getCubitFaceStickerIndex(9,3); |
|
230 |
edges[1][1] = object.getCubitFaceStickerIndex(9,5); |
|
231 |
edges[2][0] = object.getCubitFaceStickerIndex(10,3); |
|
232 |
edges[2][1] = object.getCubitFaceStickerIndex(10,5); |
|
233 |
edges[3][0] = object.getCubitFaceStickerIndex(11,5); |
|
234 |
edges[3][1] = object.getCubitFaceStickerIndex(11,3); |
|
235 |
edges[4][0] = object.getCubitFaceStickerIndex(12,3); |
|
236 |
edges[4][1] = object.getCubitFaceStickerIndex(12,5); |
|
237 |
edges[5][0] = object.getCubitFaceStickerIndex(13,5); |
|
238 |
edges[5][1] = object.getCubitFaceStickerIndex(13,3); |
|
239 |
edges[6][0] = object.getCubitFaceStickerIndex(14,3); |
|
240 |
edges[6][1] = object.getCubitFaceStickerIndex(14,5); |
|
241 |
edges[7][0] = object.getCubitFaceStickerIndex(15,5); |
|
242 |
edges[7][1] = object.getCubitFaceStickerIndex(15,3); |
|
243 |
} |
|
244 |
|
|
245 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
246 |
|
|
247 |
private void getCenters(TwistyObject object, int[] centers) |
|
248 |
{ |
|
249 |
centers[0] = object.getCubitFaceStickerIndex(16,4); |
|
250 |
centers[1] = object.getCubitFaceStickerIndex(17,4); |
|
251 |
} |
|
252 |
|
|
253 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
254 |
|
|
255 |
public int tablebaseIndex(TwistyObject object) |
|
256 |
{ |
|
257 |
int[][] corners= new int[8][3]; |
|
258 |
int[][] edges = new int[8][2]; |
|
259 |
int[] centers = new int[2]; |
|
260 |
|
|
261 |
getCorners(object,corners); |
|
262 |
getEdges(object,edges); |
|
263 |
getCenters(object,centers); |
|
264 |
|
|
265 |
//for(int i=0; i<8; i++) android.util.Log.e("D", "corner: "+i+" : "+corners[i][0]+" "+corners[i][1]+" "+corners[i][2]); |
|
266 |
//for(int i=0; i<8; i++) android.util.Log.e("D", "edge: "+i+" : "+edges[i][0]+" "+edges[i][1]); |
|
267 |
|
|
268 |
int result0 = computeFaceColors(corners, edges, centers); |
|
269 |
if( result0<0 ) return result0; |
|
270 |
|
|
271 |
int[] corner_perm = new int[8]; |
|
272 |
int result1 = retCornerPermutation(corner_perm,corners); |
|
273 |
if( result1<0 ) return result1; |
|
274 |
|
|
275 |
//android.util.Log.e("D", "upper: "+mUpper); |
|
276 |
//for(int i=0; i<6; i++) android.util.Log.e("D", "face color: "+mFaceColors[i]); |
|
277 |
|
|
278 |
int[] edge_perm8 = new int[8]; |
|
279 |
int result2 = retEdgePermutation(edge_perm8,edges); |
|
280 |
if( result2<0 ) return result2; |
|
281 |
|
|
282 |
int[] edge_perm7 = TBCuboid323.edgePermTo7(edge_perm8); |
|
283 |
/* |
|
284 |
TablebaseHelpers.displayTable(corner_perm, "CORNER PERM"); |
|
285 |
TablebaseHelpers.displayTable(edge_perm8, "EDGE PERM8"); |
|
286 |
TablebaseHelpers.displayTable(edge_perm7, "EDGE PERM7"); |
|
287 |
*/ |
|
288 |
int corner_perm_num = TablebaseHelpers.computePermutationNum(corner_perm); |
|
289 |
int edge_perm_num = TablebaseHelpers.computePermutationNum(edge_perm7); |
|
290 |
int centersInPlace = (centers[0]==mFaceColors[2]) ? 0 : 1; |
|
291 |
|
|
292 |
//android.util.Log.e("D", "corner_perm_num: "+corner_perm_num+" edge_perm_num: "+edge_perm_num+" inPlace: "+centersInPlace); |
|
293 |
//android.util.Log.e("D", "index="+(corner_perm_num + 40320*( centersInPlace + 2*edge_perm_num))); |
|
294 |
|
|
295 |
return corner_perm_num + 40320*( centersInPlace + 2*edge_perm_num); |
|
296 |
} |
|
297 |
|
|
298 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
299 |
|
|
300 |
private String edgeTwistedError(Resources res, int color0, int color1) |
|
301 |
{ |
|
302 |
int j0 = getHexColor(color0,3); |
|
303 |
int j1 = getHexColor(color1,6); |
|
304 |
|
|
305 |
String c0 = res.getString(j0); |
|
306 |
String c1 = res.getString(j1); |
|
307 |
|
|
308 |
return res.getString(R.string.solver_generic_twisted_edge,c0,c1); |
|
309 |
} |
|
310 |
|
|
311 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
312 |
|
|
313 |
private String cornerTwistedError(Resources res, int color0, int color1, int color2) |
|
314 |
{ |
|
315 |
int j0 = getHexColor(color0,3); |
|
316 |
int j1 = getHexColor(color1,3); |
|
317 |
int j2 = getHexColor(color2,5); |
|
318 |
|
|
319 |
String c0 = res.getString(j0); |
|
320 |
String c1 = res.getString(j1); |
|
321 |
String c2 = res.getString(j2); |
|
322 |
|
|
323 |
return res.getString(R.string.solver_generic_twisted_corner,c0,c1,c2); |
|
324 |
} |
|
325 |
|
|
326 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
327 |
|
|
328 |
private String edgeMissingError(Resources res, int color0, int color1) |
|
329 |
{ |
|
330 |
int j0 = getHexColor(color0,3); |
|
331 |
int j1 = getHexColor(color1,6); |
|
332 |
|
|
333 |
String c0 = res.getString(j0); |
|
334 |
String c1 = res.getString(j1); |
|
335 |
|
|
336 |
return res.getString(R.string.solver_generic_missing_edge,c0,c1); |
|
337 |
} |
|
338 |
|
|
339 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
340 |
|
|
341 |
private String cornerMissingError(Resources res, int color0, int color1, int color2) |
|
342 |
{ |
|
343 |
int j0 = getHexColor(color0,3); |
|
344 |
int j1 = getHexColor(color1,3); |
|
345 |
int j2 = getHexColor(color2,4); |
|
346 |
|
|
347 |
String c0 = res.getString(j0); |
|
348 |
String c1 = res.getString(j1); |
|
349 |
String c2 = res.getString(j2); |
|
350 |
|
|
351 |
return res.getString(R.string.solver_generic_missing_corner,c0,c1,c2); |
|
352 |
} |
|
353 |
|
|
354 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
355 |
|
|
356 |
public String error(int index, Resources res) |
|
357 |
{ |
|
358 |
switch(index) |
|
359 |
{ |
|
360 |
case ERROR_CORNER_MISSING : return cornerMissingError(res,mErrColor1,mErrColor2,mErrColor3); |
|
361 |
case ERROR_EDGE_MISSING : return edgeMissingError(res,mErrColor1,mErrColor2); |
|
362 |
case ERROR_CORNERS_CANNOT : return res.getString(R.string.solver_generic_corners_cannot); |
|
363 |
case ERROR_EDGE_TWISTED : return edgeTwistedError(res,mErrColor1,mErrColor2); |
|
364 |
case ERROR_CORNER_TWISTED : return cornerTwistedError(res,mErrColor1,mErrColor2,mErrColor3); |
|
365 |
} |
|
366 |
|
|
367 |
return null; |
|
368 |
} |
|
369 |
} |
|
370 |
|
src/main/java/org/distorted/solvers/SolverTablebaseCUBE2.java | ||
---|---|---|
1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2 |
// Copyright 2023 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.solvers; |
|
11 |
|
|
12 |
import android.content.res.Resources; |
|
13 |
|
|
14 |
import org.distorted.main.R; |
|
15 |
import org.distorted.objectlib.helpers.OperatingSystemInterface; |
|
16 |
import org.distorted.objectlib.main.TwistyObject; |
|
17 |
import org.distorted.objectlib.tablebases.TablebaseHelpers; |
|
18 |
import org.distorted.objectlib.tablebases.TBCube2; |
|
19 |
|
|
20 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
21 |
|
|
22 |
public class SolverTablebaseCUBE2 extends SolverTablebase |
|
23 |
{ |
|
24 |
private static final int ERROR_CORNER_MISSING = -1; |
|
25 |
private static final int ERROR_CORNERS_CANNOT = -2; |
|
26 |
private static final int ERROR_CORNER_TWISTED = -3; |
|
27 |
|
|
28 |
private final int[] mFaceColors; |
|
29 |
private int mErrColor1, mErrColor2, mErrColor3; |
|
30 |
|
|
31 |
//////////////////////////////////////////////////////////////////////////////////////// |
|
32 |
|
|
33 |
private void fillCornerTwists(int[] output, int[][] corners, int[] perm) |
|
34 |
{ |
|
35 |
for(int i=0; i<8; i++) |
|
36 |
{ |
|
37 |
int[] c = corners[perm[i]]; |
|
38 |
|
|
39 |
if( c[0]==mFaceColors[0] || c[0]==mFaceColors[1] ) output[i] = 0; |
|
40 |
else if( c[1]==mFaceColors[0] || c[1]==mFaceColors[1] ) output[i] = 1; |
|
41 |
else output[i] = 2; |
|
42 |
} |
|
43 |
} |
|
44 |
|
|
45 |
//////////////////////////////////////////////////////////////////////////////////////// |
|
46 |
|
|
47 |
private int cornerIndex(int[][] corners, int i1, int i2, int i3) |
|
48 |
{ |
|
49 |
int c1 = mFaceColors[i1]; |
|
50 |
int c2 = mFaceColors[i2]; |
|
51 |
int c3 = mFaceColors[i3]; |
|
52 |
|
|
53 |
for(int i=0; i<8; i++) |
|
54 |
{ |
|
55 |
int[] cor = corners[i]; |
|
56 |
|
|
57 |
if( (cor[0]==c1 && cor[1]==c2 && cor[2]==c3) || |
|
58 |
(cor[0]==c2 && cor[1]==c3 && cor[2]==c1) || |
|
59 |
(cor[0]==c3 && cor[1]==c1 && cor[2]==c2) ) return i; |
|
60 |
} |
|
61 |
|
|
62 |
return -1; |
|
63 |
} |
|
64 |
|
|
65 |
//////////////////////////////////////////////////////////////////////////////////////// |
|
66 |
|
|
67 |
private int retCornerPermutation(int[] output, int[][] corners) |
|
68 |
{ |
|
69 |
for(int i=0; i<8; i++) output[i] = -1; |
|
70 |
|
|
71 |
output[0] = cornerIndex(corners, 1,2,5); |
|
72 |
output[1] = cornerIndex(corners, 1,4,2); |
|
73 |
output[2] = cornerIndex(corners, 1,5,3); |
|
74 |
output[3] = cornerIndex(corners, 1,3,4); |
|
75 |
output[4] = cornerIndex(corners, 0,5,2); |
|
76 |
output[5] = cornerIndex(corners, 0,2,4); |
|
77 |
output[6] = cornerIndex(corners, 0,3,5); |
|
78 |
output[7] = cornerIndex(corners, 0,4,3); |
|
79 |
|
|
80 |
if( output[0]==-1 ) { mErrColor1=1; mErrColor2=2; mErrColor3=5; return ERROR_CORNER_MISSING; } |
|
81 |
if( output[1]==-1 ) { mErrColor1=1; mErrColor2=4; mErrColor3=2; return ERROR_CORNER_MISSING; } |
|
82 |
if( output[2]==-1 ) { mErrColor1=1; mErrColor2=5; mErrColor3=3; return ERROR_CORNER_MISSING; } |
|
83 |
if( output[3]==-1 ) { mErrColor1=1; mErrColor2=3; mErrColor3=4; return ERROR_CORNER_MISSING; } |
|
84 |
if( output[4]==-1 ) { mErrColor1=0; mErrColor2=5; mErrColor3=2; return ERROR_CORNER_MISSING; } |
|
85 |
if( output[5]==-1 ) { mErrColor1=0; mErrColor2=2; mErrColor3=4; return ERROR_CORNER_MISSING; } |
|
86 |
if( output[6]==-1 ) { mErrColor1=0; mErrColor2=3; mErrColor3=5; return ERROR_CORNER_MISSING; } |
|
87 |
if( output[7]==-1 ) { mErrColor1=0; mErrColor2=4; mErrColor3=3; return ERROR_CORNER_MISSING; } |
|
88 |
|
|
89 |
return 0; |
|
90 |
} |
|
91 |
|
|
92 |
//////////////////////////////////////////////////////////////////////////////////////// |
|
93 |
|
|
94 |
private int findColor(int[][] corners, int c1, int c2) |
|
95 |
{ |
|
96 |
for(int i=0; i<8; i++) |
|
97 |
{ |
|
98 |
int[] cor = corners[i]; |
|
99 |
|
|
100 |
if( cor[0]==c1 && cor[1]==c2 ) return cor[2]; |
|
101 |
if( cor[1]==c1 && cor[2]==c2 ) return cor[0]; |
|
102 |
if( cor[2]==c1 && cor[0]==c2 ) return cor[1]; |
|
103 |
} |
|
104 |
|
|
105 |
return -1; |
|
106 |
} |
|
107 |
|
|
108 |
//////////////////////////////////////////////////////////////////////////////////////// |
|
109 |
|
|
110 |
private int computeFaceColors(int[][] corners) |
|
111 |
{ |
|
112 |
mFaceColors[1] = corners[1][0]; |
|
113 |
mFaceColors[2] = corners[1][2]; |
|
114 |
mFaceColors[4] = corners[1][1]; |
|
115 |
|
|
116 |
mFaceColors[0] = findColor(corners,mFaceColors[2],mFaceColors[4]); |
|
117 |
mFaceColors[3] = findColor(corners,mFaceColors[4],mFaceColors[1]); |
|
118 |
mFaceColors[5] = findColor(corners,mFaceColors[1],mFaceColors[2]); |
|
119 |
|
|
120 |
for(int i=0; i<6; i++) |
|
121 |
{ |
|
122 |
int color = mFaceColors[i]; |
|
123 |
if( color<0 ) return ERROR_CORNERS_CANNOT; |
|
124 |
|
|
125 |
for(int j=i+1; j<6; j++) |
|
126 |
if( mFaceColors[j]==color ) return ERROR_CORNERS_CANNOT; |
|
127 |
} |
|
128 |
|
|
129 |
return 0; |
|
130 |
} |
|
131 |
|
|
132 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
133 |
|
|
134 |
public SolverTablebaseCUBE2(OperatingSystemInterface os, Resources res, TwistyObject object) |
|
135 |
{ |
|
136 |
super(os,res,object); |
|
137 |
mFaceColors = new int[6]; |
|
138 |
} |
|
139 |
|
|
140 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
141 |
|
|
142 |
private void getCorners(TwistyObject object, int[][] corners) |
|
143 |
{ |
|
144 |
corners[0][0] = object.getCubitFaceStickerIndex(0,1); |
|
145 |
corners[0][1] = object.getCubitFaceStickerIndex(0,3); |
|
146 |
corners[0][2] = object.getCubitFaceStickerIndex(0,5); |
|
147 |
|
|
148 |
corners[1][0] = object.getCubitFaceStickerIndex(1,3); |
|
149 |
corners[1][1] = object.getCubitFaceStickerIndex(1,5); |
|
150 |
corners[1][2] = object.getCubitFaceStickerIndex(1,1); |
|
151 |
|
|
152 |
corners[2][0] = object.getCubitFaceStickerIndex(2,5); |
|
153 |
corners[2][1] = object.getCubitFaceStickerIndex(2,1); |
|
154 |
corners[2][2] = object.getCubitFaceStickerIndex(2,3); |
|
155 |
|
|
156 |
corners[3][0] = object.getCubitFaceStickerIndex(3,1); |
|
157 |
corners[3][1] = object.getCubitFaceStickerIndex(3,3); |
|
158 |
corners[3][2] = object.getCubitFaceStickerIndex(3,5); |
|
159 |
|
|
160 |
corners[4][0] = object.getCubitFaceStickerIndex(4,1); |
|
161 |
corners[4][1] = object.getCubitFaceStickerIndex(4,3); |
|
162 |
corners[4][2] = object.getCubitFaceStickerIndex(4,5); |
|
163 |
|
|
164 |
corners[5][0] = object.getCubitFaceStickerIndex(5,1); |
|
165 |
corners[5][1] = object.getCubitFaceStickerIndex(5,3); |
|
166 |
corners[5][2] = object.getCubitFaceStickerIndex(5,5); |
|
167 |
|
|
168 |
corners[6][0] = object.getCubitFaceStickerIndex(6,1); |
|
169 |
corners[6][1] = object.getCubitFaceStickerIndex(6,3); |
|
170 |
corners[6][2] = object.getCubitFaceStickerIndex(6,5); |
|
171 |
|
|
172 |
corners[7][0] = object.getCubitFaceStickerIndex(7,1); |
|
173 |
corners[7][1] = object.getCubitFaceStickerIndex(7,3); |
|
174 |
corners[7][2] = object.getCubitFaceStickerIndex(7,5); |
|
175 |
} |
|
176 |
|
|
177 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
178 |
|
|
179 |
public int tablebaseIndex(TwistyObject object) |
|
180 |
{ |
|
181 |
int[][] corners= new int[8][3]; |
|
182 |
getCorners(object,corners); |
|
183 |
|
|
184 |
int result0 = computeFaceColors(corners); |
|
185 |
if( result0<0 ) return result0; |
|
186 |
|
|
187 |
int[] perm = new int[8]; |
|
188 |
int result1 = retCornerPermutation(perm,corners); |
|
189 |
if( result1<0 ) return result1; |
|
190 |
|
|
191 |
int[] perm7 = TBCube2.shrinkPerm(perm); |
|
192 |
int permNum = TablebaseHelpers.computePermutationNum(perm7); |
|
193 |
int[] twist = new int[8]; |
|
194 |
fillCornerTwists(twist,corners,perm); |
|
195 |
|
|
196 |
int totalTwist = 0; |
|
197 |
for(int i=0; i<8; i++) totalTwist += twist[i]; |
|
198 |
if( ((totalTwist)%3) != 0 ) return ERROR_CORNER_TWISTED; |
|
199 |
|
|
200 |
int twistNum = twist[0] + 3*(twist[2] + 3*(twist[3] + 3*(twist[4] + 3*(twist[5] + 3*twist[6])))); |
|
201 |
|
|
202 |
return twistNum + 729*permNum; |
|
203 |
} |
|
204 |
|
|
205 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
206 |
|
|
207 |
private String cornerError(Resources res, int face0, int face1, int face2) |
|
208 |
{ |
Also available in: Unified diff
Properly define and separate the interface between the App and the 'solver' part of the objectlib. Move the 'position verifiers' to the objectlib.