Revision cff92952
Added by Leszek Koltunski about 1 year ago
src/main/java/org/distorted/solvers/SolverSkewb.java | ||
---|---|---|
15 | 15 |
import org.distorted.objectlib.main.ObjectSignatures; |
16 | 16 |
import org.distorted.objectlib.main.TwistyObject; |
17 | 17 |
import org.distorted.objectlib.tablebases.ImplementedTablebasesList; |
18 |
import org.distorted.objectlib.tablebases.TablebaseHelpers; |
|
18 | 19 |
import org.distorted.objectlib.tablebases.TablebasesAbstract; |
19 | 20 |
|
20 | 21 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
42 | 43 |
private static final int ERROR_TWO_CENTERS = -17; |
43 | 44 |
private static final int ERROR_TWO_CORNERS = -18; |
44 | 45 |
|
46 |
private static final int ERROR_IMPOSSIBLE = -19; |
|
47 |
|
|
45 | 48 |
private TablebasesAbstract mSolver; |
46 |
private int[] mFaceColors; |
|
49 |
private final int[] mFaceColors;
|
|
47 | 50 |
|
48 | 51 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
49 | 52 |
|
50 | 53 |
public SolverSkewb(Resources res, TwistyObject object) |
51 | 54 |
{ |
52 | 55 |
super(res,object); |
56 |
mFaceColors = new int[6]; |
|
53 | 57 |
} |
54 | 58 |
|
55 | 59 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
56 | 60 |
|
57 | 61 |
private void getCorners(TwistyObject object, int[][] corners) |
58 | 62 |
{ |
63 |
for(int i=0; i<8; i++) |
|
64 |
for(int j=0; j<3; j++) |
|
65 |
corners[i][j] = object.getCubitFaceStickerIndex(i,j); |
|
66 |
} |
|
67 |
|
|
68 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
69 |
|
|
70 |
private void getCenters(TwistyObject object, int[] centers) |
|
71 |
{ |
|
72 |
int[] map = {12,13,10,11,8,9}; |
|
59 | 73 |
|
74 |
for(int i=0; i<6; i++) |
|
75 |
centers[i] = object.getCubitFaceStickerIndex(map[i],0) - 6; |
|
60 | 76 |
} |
61 | 77 |
|
62 | 78 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
63 | 79 |
|
64 |
private int checkAllCornersPresent(int[][] corners) |
|
80 |
private int commonCornerColor(int[] c1, int[] c2) |
|
81 |
{ |
|
82 |
int theSame = 0; |
|
83 |
int index = 0; |
|
84 |
|
|
85 |
for(int i=0; i<3; i++) |
|
86 |
for(int j=0; j<3; j++) |
|
87 |
if( c1[i]==c2[j] ) |
|
88 |
{ |
|
89 |
index = i; |
|
90 |
theSame++; |
|
91 |
} |
|
92 |
|
|
93 |
return theSame==1 ? c1[index] : ERROR_CORNERS_CANNOT; |
|
94 |
} |
|
95 |
|
|
96 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
97 |
|
|
98 |
private int computeFaceColors(int[][] corners, int[] output) |
|
65 | 99 |
{ |
100 |
final int[][] map = { {0,3},{5,6},{0,5},{6,3},{0,6},{3,5} }; |
|
101 |
|
|
102 |
for(int i=0; i<6; i++) |
|
103 |
{ |
|
104 |
int c1 = map[i][0]; |
|
105 |
int c2 = map[i][1]; |
|
106 |
output[i] = commonCornerColor(corners[c1],corners[c2]); |
|
107 |
if( output[i]<0 ) return ERROR_CORNERS_CANNOT; |
|
108 |
} |
|
109 |
|
|
66 | 110 |
return 0; |
67 | 111 |
} |
68 | 112 |
|
69 | 113 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
70 | 114 |
|
71 |
private int[] computeFaceColors(int[][] corners)
|
|
115 |
private boolean cornerIs(int[] corner, int c0, int c1, int c2)
|
|
72 | 116 |
{ |
73 |
return null; |
|
117 |
return ( (corner[0]==c0 && corner[1]==c1 && corner[2]==c2 ) || |
|
118 |
(corner[1]==c0 && corner[2]==c1 && corner[0]==c2 ) || |
|
119 |
(corner[2]==c0 && corner[0]==c1 && corner[1]==c2 ) ); |
|
74 | 120 |
} |
75 | 121 |
|
76 | 122 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
77 | 123 |
|
78 |
private void getCenters(TwistyObject object, int[] centers)
|
|
124 |
private int checkAllCornersPresent(int[][] corners)
|
|
79 | 125 |
{ |
126 |
boolean[] present = new boolean[8]; |
|
127 |
|
|
128 |
for(int i=0; i<8; i++) |
|
129 |
{ |
|
130 |
if( cornerIs(corners[i],4,2,0) ) present[0]=true; |
|
131 |
if( cornerIs(corners[i],2,5,0) ) present[1]=true; |
|
132 |
if( cornerIs(corners[i],3,4,0) ) present[2]=true; |
|
133 |
if( cornerIs(corners[i],5,3,0) ) present[3]=true; |
|
134 |
if( cornerIs(corners[i],1,2,4) ) present[4]=true; |
|
135 |
if( cornerIs(corners[i],5,2,1) ) present[5]=true; |
|
136 |
if( cornerIs(corners[i],4,3,1) ) present[6]=true; |
|
137 |
if( cornerIs(corners[i],1,3,5) ) present[7]=true; |
|
138 |
} |
|
139 |
|
|
140 |
if( !present[0] ) return ERROR_CORNER_024_MISSING; |
|
141 |
if( !present[1] ) return ERROR_CORNER_025_MISSING; |
|
142 |
if( !present[2] ) return ERROR_CORNER_034_MISSING; |
|
143 |
if( !present[3] ) return ERROR_CORNER_035_MISSING; |
|
144 |
if( !present[4] ) return ERROR_CORNER_124_MISSING; |
|
145 |
if( !present[5] ) return ERROR_CORNER_125_MISSING; |
|
146 |
if( !present[6] ) return ERROR_CORNER_134_MISSING; |
|
147 |
if( !present[7] ) return ERROR_CORNER_135_MISSING; |
|
80 | 148 |
|
149 |
return 0; |
|
81 | 150 |
} |
82 | 151 |
|
83 | 152 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
84 | 153 |
|
85 | 154 |
private int checkAllCentersPresent(int[] centers) |
86 | 155 |
{ |
156 |
boolean[] present = new boolean[6]; |
|
157 |
for(int i=0; i<6; i++) present[centers[i]]= true; |
|
158 |
|
|
159 |
if( !present[0] ) return ERROR_CENTER_4_MISSING; |
|
160 |
if( !present[1] ) return ERROR_CENTER_5_MISSING; |
|
161 |
if( !present[2] ) return ERROR_CENTER_2_MISSING; |
|
162 |
if( !present[3] ) return ERROR_CENTER_3_MISSING; |
|
163 |
if( !present[4] ) return ERROR_CENTER_0_MISSING; |
|
164 |
if( !present[5] ) return ERROR_CENTER_1_MISSING; |
|
165 |
|
|
166 |
return 0; |
|
167 |
} |
|
168 |
|
|
169 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
170 |
// free corners: 1,2,4,7 |
|
171 |
|
|
172 |
private int retCornerPermutation(int[] perm, int[][] corners) |
|
173 |
{ |
|
174 |
int[] map = {1,2,4,7}; |
|
175 |
|
|
176 |
perm[0] = 0; |
|
177 |
perm[1] = -1; |
|
178 |
perm[2] = -1; |
|
179 |
perm[3] = 3; |
|
180 |
perm[4] = -1; |
|
181 |
perm[5] = 5; |
|
182 |
perm[6] = 6; |
|
183 |
perm[7] = -1; |
|
184 |
|
|
185 |
for(int i=0; i<4; i++) |
|
186 |
{ |
|
187 |
int index = map[i]; |
|
188 |
int[] cor = corners[index]; |
|
189 |
|
|
190 |
if( cornerIs(cor,2,5,0) ) perm[1] = index; |
|
191 |
if( cornerIs(cor,3,4,0) ) perm[2] = index; |
|
192 |
if( cornerIs(cor,1,2,4) ) perm[4] = index; |
|
193 |
if( cornerIs(cor,1,3,5) ) perm[7] = index; |
|
194 |
} |
|
195 |
|
|
196 |
if( perm[1]==-1 ) return ERROR_CORNER_025_MISSING; |
|
197 |
if( perm[2]==-1 ) return ERROR_CORNER_034_MISSING; |
|
198 |
if( perm[4]==-1 ) return ERROR_CORNER_124_MISSING; |
|
199 |
if( perm[7]==-1 ) return ERROR_CORNER_135_MISSING; |
|
200 |
|
|
87 | 201 |
return 0; |
88 | 202 |
} |
89 | 203 |
|
204 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
205 |
|
|
206 |
private void fillCornerTwists(int[] output, int[][] corners, int[] perm) |
|
207 |
{ |
|
208 |
final int[] map = { 4,2,3,5,1,5,4,1 }; |
|
209 |
|
|
210 |
for(int i=0; i<8; i++) |
|
211 |
{ |
|
212 |
int color = mFaceColors[map[i]]; |
|
213 |
int[] c = corners[perm[i]]; |
|
214 |
|
|
215 |
if( c[0]==color ) output[i] = 0; |
|
216 |
else if( c[1]==color ) output[i] = 1; |
|
217 |
else output[i] = 2; |
|
218 |
} |
|
219 |
} |
|
220 |
|
|
221 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
222 |
|
|
223 |
private int computeCenterTwist(int p1, int p2) |
|
224 |
{ |
|
225 |
if( p1==1 ) |
|
226 |
{ |
|
227 |
switch(p2) |
|
228 |
{ |
|
229 |
case 2: return 2; |
|
230 |
case 4: return 1; |
|
231 |
case 7: return 0; |
|
232 |
} |
|
233 |
} |
|
234 |
if( p1==2 ) |
|
235 |
{ |
|
236 |
switch(p2) |
|
237 |
{ |
|
238 |
case 1: return 2; |
|
239 |
case 4: return 0; |
|
240 |
case 7: return 1; |
|
241 |
} |
|
242 |
} |
|
243 |
if( p1==4 ) |
|
244 |
{ |
|
245 |
switch(p2) |
|
246 |
{ |
|
247 |
case 1: return 1; |
|
248 |
case 2: return 0; |
|
249 |
case 7: return 2; |
|
250 |
} |
|
251 |
} |
|
252 |
if( p1==7 ) |
|
253 |
{ |
|
254 |
switch(p2) |
|
255 |
{ |
|
256 |
case 1: return 0; |
|
257 |
case 2: return 1; |
|
258 |
case 4: return 2; |
|
259 |
} |
|
260 |
} |
|
261 |
|
|
262 |
return ERROR_IMPOSSIBLE; |
|
263 |
} |
|
264 |
|
|
265 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
266 |
|
|
267 |
private int positionOfFirstCorner(int[] perm, int[] twist) |
|
268 |
{ |
|
269 |
int total_fixed_twist = twist[0]+twist[3]+twist[5]+twist[6]; |
|
270 |
|
|
271 |
int twist_42 = computeCenterTwist(perm[4],perm[2]); |
|
272 |
int twist_21 = computeCenterTwist(perm[2],perm[1]); |
|
273 |
|
|
274 |
if( twist_42<0 || twist_21<0 ) return ERROR_IMPOSSIBLE; |
|
275 |
|
|
276 |
|
|
277 |
android.util.Log.e("D", "twist42 "+twist_42+" twist21 "+twist_21+" total: "+total_fixed_twist); |
|
278 |
|
|
279 |
if( (twist_21-twist_42+1)%3 != 0 ) return ERROR_TWO_CORNERS; |
|
280 |
if( (total_fixed_twist-twist_42)%3 !=0 ) return ERROR_CORNER_TWISTED; |
|
281 |
|
|
282 |
switch(perm[1]) |
|
283 |
{ |
|
284 |
case 1: return 0; |
|
285 |
case 2: return 1; |
|
286 |
case 4: return 2; |
|
287 |
case 7: return 3; |
|
288 |
} |
|
289 |
|
|
290 |
return ERROR_IMPOSSIBLE; |
|
291 |
} |
|
292 |
|
|
90 | 293 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
91 | 294 |
|
92 | 295 |
public int tablebaseIndex(TwistyObject object) |
93 | 296 |
{ |
94 |
int[][] corners = new int[6][3]; |
|
95 |
int[] centers = new int[6]; |
|
96 |
int[] corner_twist= new int[6]; |
|
297 |
int[][] corners= new int[8][3]; |
|
298 |
int[] centers = new int[6]; |
|
299 |
int[] twist = new int[8]; |
|
300 |
int[] perm = new int[8]; |
|
97 | 301 |
|
98 | 302 |
getCorners(object,corners); |
99 | 303 |
|
100 |
int result1 = checkAllCornersPresent(corners);
|
|
304 |
int result1 = computeFaceColors(corners,mFaceColors);
|
|
101 | 305 |
if( result1<0 ) return result1; |
102 | 306 |
|
103 |
mFaceColors = computeFaceColors(corners); |
|
307 |
int result2 = checkAllCornersPresent(corners); |
|
308 |
if( result2<0 ) return result2; |
|
104 | 309 |
|
105 | 310 |
getCenters(object,centers); |
106 |
int result2 = checkAllCentersPresent(centers); |
|
107 |
if( result2<0 ) return result2; |
|
311 |
int result3 = checkAllCentersPresent(centers); |
|
312 |
if( result3<0 ) return result3; |
|
313 |
/* |
|
314 |
for(int i=0; i<8; i++) |
|
315 |
for(int j=0; j<3; j++) android.util.Log.e("D", "corner "+i+" face "+j+" : "+corners[i][j]); |
|
108 | 316 |
|
109 |
// TODO... |
|
317 |
for(int i=0; i<6; i++) android.util.Log.e("D", "center "+i+" : "+centers[i]); |
|
318 |
for(int i=0; i<6; i++) android.util.Log.e("D", "face "+i+" : "+mFaceColors[i]); |
|
319 |
*/ |
|
320 |
if( !TablebaseHelpers.permutationIsEven(centers) ) return ERROR_TWO_CENTERS; |
|
321 |
int center_perm_num = TablebaseHelpers.computeEvenPermutationNum(centers); |
|
110 | 322 |
|
111 |
return 0; |
|
323 |
int result4 = retCornerPermutation(perm,corners); |
|
324 |
if( result4<0 ) return result4; |
|
325 |
|
|
326 |
fillCornerTwists(twist,corners,perm); |
|
327 |
|
|
328 |
for(int i=0; i<8; i++) android.util.Log.e("D", "perm "+i+" : "+perm[i]); |
|
329 |
for(int i=0; i<8; i++) android.util.Log.e("D", "twist "+i+" : "+twist[i]); |
|
330 |
|
|
331 |
int totalTwist = 0; |
|
332 |
for(int i=0; i<8; i++) totalTwist += twist[i]; |
|
333 |
|
|
334 |
android.util.Log.e("D", "total twist "+totalTwist); |
|
335 |
|
|
336 |
if( (totalTwist%3)!=0 ) return ERROR_CORNER_TWISTED; |
|
337 |
|
|
338 |
int total = twist[0]+ 3*(twist[1]+ 3*(twist[2]+ 3*(twist[3]+ 3*(twist[4]+ 3*(twist[5]+ 3*twist[6]))))); |
|
339 |
|
|
340 |
int corner1 = positionOfFirstCorner(perm,twist); |
|
341 |
if( corner1<0 ) return ERROR_TWO_CORNERS; |
|
342 |
|
|
343 |
android.util.Log.e("D", "corner1: "+corner1+" center perm: "+center_perm_num+" twist: "+total); |
|
344 |
|
|
345 |
return corner1 + 4*(center_perm_num + 360*total); |
|
112 | 346 |
} |
113 | 347 |
|
114 | 348 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
Also available in: Unified diff
Progess with Skewb solver.