Project

General

Profile

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

magiccube / src / main / java / org / distorted / solvers / SolverTablebaseDIAM2.java @ 7464b393

1 9a39aabf Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 478a4c45 Leszek Koltunski
import org.distorted.main.R;
15 da57afae Leszek Koltunski
import org.distorted.objectlib.helpers.OperatingSystemInterface;
16 9a39aabf Leszek Koltunski
import org.distorted.objectlib.main.TwistyObject;
17 62c08ea7 Leszek Koltunski
import org.distorted.objectlib.tablebases.TablebaseHelpers;
18 9a39aabf Leszek Koltunski
19
///////////////////////////////////////////////////////////////////////////////////////////////////
20
21 1d1f9ccf leszek
public class SolverTablebaseDIAM2 extends SolverTablebase
22 9a39aabf Leszek Koltunski
{
23
  private static final int ERROR_CORNER_FR_MISSING = -1;
24
  private static final int ERROR_CORNER_BR_MISSING = -2;
25
  private static final int ERROR_CORNER_BL_MISSING = -3;
26
  private static final int ERROR_CORNER_FL_MISSING = -4;
27
  private static final int ERROR_CORNER_TO_MISSING = -5;
28
  private static final int ERROR_CORNER_BO_MISSING = -6;
29
30
  private static final int ERROR_CENTER_0_MISSING = -7;
31
  private static final int ERROR_CENTER_1_MISSING = -8;
32
  private static final int ERROR_CENTER_2_MISSING = -9;
33
  private static final int ERROR_CENTER_3_MISSING = -10;
34
  private static final int ERROR_CENTER_4_MISSING = -11;
35
  private static final int ERROR_CENTER_5_MISSING = -12;
36
  private static final int ERROR_CENTER_6_MISSING = -13;
37
  private static final int ERROR_CENTER_7_MISSING = -14;
38
39
  private static final int ERROR_TWO_CORNERS      = -15;
40
  private static final int ERROR_TWO_CENTERS      = -16;
41 11e67fa5 Leszek Koltunski
  private static final int ERROR_CORNER_TWIST_90  = -17;
42
  private static final int ERROR_CORNER_TWIST_180 = -18;
43
  private static final int ERROR_CORNERS_CANNOT   = -19;
44 9a39aabf Leszek Koltunski
45 478a4c45 Leszek Koltunski
  private final int[] mFaceColors;
46
47
  private static final int[] FREE_CENTERS = {0,2,5,7};
48 9a39aabf Leszek Koltunski
49
///////////////////////////////////////////////////////////////////////////////////////////////////
50
51 1d1f9ccf leszek
  public SolverTablebaseDIAM2(OperatingSystemInterface os, Resources res, TwistyObject object)
52 9a39aabf Leszek Koltunski
    {
53 da57afae Leszek Koltunski
    super(os,res,object);
54 478a4c45 Leszek Koltunski
    mFaceColors = new int[8];
55
    }
56
57
///////////////////////////////////////////////////////////////////////////////////////////////////
58
59
  private int retCorner(int[][] corners, int c1, int c2)
60
    {
61
    for(int i=0; i<6; i++)
62
      {
63
      int[] cor = corners[i];
64
      int twist = retCornerTwist(cor,c1,c2);
65
      if( twist>=0 ) return i;
66
      }
67
68
    return -1;
69
    }
70
71
///////////////////////////////////////////////////////////////////////////////////////////////////
72
73
  private int[] getCornersPermutation(int[][] corners)
74
    {
75
    int[] perm = new int[6];
76
77
    perm[0] = retCorner(corners,mFaceColors[1],mFaceColors[4]);
78
    perm[1] = retCorner(corners,mFaceColors[1],mFaceColors[6]);
79
    perm[2] = retCorner(corners,mFaceColors[3],mFaceColors[6]);
80
    perm[3] = retCorner(corners,mFaceColors[3],mFaceColors[4]);
81
    perm[4] = retCorner(corners,mFaceColors[1],mFaceColors[3]);
82
    perm[5] = retCorner(corners,mFaceColors[4],mFaceColors[6]);
83
84
    return perm;
85 9a39aabf Leszek Koltunski
    }
86
87 754f7231 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
88
89
  private int computeCornerTwist(int[] corner, int color )
90
    {
91
    if( corner[3]==color ) return 0;
92
    if( corner[2]==color ) return 1;
93
    if( corner[1]==color ) return 2;
94
    if( corner[0]==color ) return 3;
95
96
    return -1;
97
    }
98
99 62c08ea7 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
100
101 478a4c45 Leszek Koltunski
  private int[] getCornersTwist(int[] corners_perm, int[][] corners)
102 62c08ea7 Leszek Koltunski
    {
103 478a4c45 Leszek Koltunski
    int[] twist = new int[6];
104
105 754f7231 Leszek Koltunski
    twist[0] = computeCornerTwist( corners[corners_perm[0]], mFaceColors[1] );
106
    twist[1] = computeCornerTwist( corners[corners_perm[1]], mFaceColors[1] );
107
    twist[2] = computeCornerTwist( corners[corners_perm[2]], mFaceColors[3] );
108
    twist[3] = computeCornerTwist( corners[corners_perm[3]], mFaceColors[3] );
109
    twist[4] = computeCornerTwist( corners[corners_perm[4]], mFaceColors[1] );
110
    twist[5] = computeCornerTwist( corners[corners_perm[5]], mFaceColors[4] );
111 62c08ea7 Leszek Koltunski
112 478a4c45 Leszek Koltunski
    return twist;
113 62c08ea7 Leszek Koltunski
    }
114
115
///////////////////////////////////////////////////////////////////////////////////////////////////
116
117 478a4c45 Leszek Koltunski
  private int retCenter(int color, int[] centers)
118 62c08ea7 Leszek Koltunski
    {
119 478a4c45 Leszek Koltunski
    for(int i=0; i<4; i++ )
120
      if( centers[FREE_CENTERS[i]]==color ) return i;
121 62c08ea7 Leszek Koltunski
122 478a4c45 Leszek Koltunski
    return -1;
123 62c08ea7 Leszek Koltunski
    }
124
125
///////////////////////////////////////////////////////////////////////////////////////////////////
126
127 478a4c45 Leszek Koltunski
  private int[] getFreeCentersPermutation(int[] centers)
128 62c08ea7 Leszek Koltunski
    {
129 478a4c45 Leszek Koltunski
    int[] perm = new int[4];
130
131
    for(int i=0; i<4; i++ )
132
      perm[i] = retCenter(mFaceColors[FREE_CENTERS[i]],centers);
133 62c08ea7 Leszek Koltunski
134 478a4c45 Leszek Koltunski
    return perm;
135 62c08ea7 Leszek Koltunski
    }
136
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138
139
  private int getTotalTwist(int[] twist)
140
    {
141
    int total = 0;
142 11e67fa5 Leszek Koltunski
    boolean even = true;
143 62c08ea7 Leszek Koltunski
144
    for(int i=0; i<6; i++)
145
      {
146
      int t= twist[i];
147 11e67fa5 Leszek Koltunski
148
      if( t==1 || t==3 ) return ERROR_CORNER_TWIST_90;
149
      if( t==2 )
150
        {
151
        if( i<5 )
152
          {
153
          total+=(1<<i);
154
          even = !even;
155
          }
156
        else if( even ) return ERROR_CORNER_TWIST_180;
157
        }
158 62c08ea7 Leszek Koltunski
      }
159
160
    return total;
161
    }
162
163 478a4c45 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
164
165
  private int retCornerTwist(int[] corner, int c1, int c2)
166
    {
167
    if( corner[0]==c1 && corner[2]==c2 ) return 1;
168
    if( corner[1]==c1 && corner[3]==c2 ) return 2;
169
    if( corner[2]==c1 && corner[0]==c2 ) return 3;
170
    if( corner[3]==c1 && corner[1]==c2 ) return 0;
171
172
    return -1;
173
    }
174
175 62c08ea7 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
176
177
  private int figureOutColor(int[][] corners, int c1, int c2)
178
    {
179
    for(int i=0; i<6; i++)
180
      {
181
      int[] cor = corners[i];
182 478a4c45 Leszek Koltunski
      int twist = retCornerTwist(cor,c1,c2);
183
      if( twist>=0 ) return cor[twist];
184 62c08ea7 Leszek Koltunski
      }
185
186
    return -1;
187
    }
188
189
///////////////////////////////////////////////////////////////////////////////////////////////////
190
// We only move the UR, UR, DR & DB faces --> those centers are fixed and determine the colors of
191
// the faces.
192
193
  private int figureOutFaceColors(int[] output, int[] centers, int[][] corners)
194
    {
195
    output[1] = centers[1];
196
    output[3] = centers[3];
197
    output[4] = centers[4];
198
    output[6] = centers[6];
199
200
    int color01 = figureOutColor(corners,output[4],output[1]);
201
    if( color01<0 ) return ERROR_CORNER_FR_MISSING;
202
    int color02 = figureOutColor(corners,output[3],output[4]);
203
    if( color02<0 ) return ERROR_CORNER_FL_MISSING;
204
    int color03 = figureOutColor(corners,output[1],output[3]);
205
    if( color03<0 ) return ERROR_CORNER_TO_MISSING;
206
    if( color01!=color02 || color01!=color03 ) return ERROR_CORNERS_CANNOT;
207
    output[0] = color01;
208
209
    int color21 = figureOutColor(corners,output[1],output[6]);
210
    if( color21<0 ) return ERROR_CORNER_BR_MISSING;
211
    int color22 = figureOutColor(corners,output[6],output[3]);
212
    if( color22<0 ) return ERROR_CORNER_BL_MISSING;
213
    int color23 = figureOutColor(corners,output[3],output[1]);
214
    if( color23<0 ) return ERROR_CORNER_TO_MISSING;
215
    if( color21!=color22 || color21!=color23 ) return ERROR_CORNERS_CANNOT;
216
    output[2] = color21;
217
218
    int color51 = figureOutColor(corners,output[1],output[4]);
219
    if( color51<0 ) return ERROR_CORNER_FR_MISSING;
220
    int color52 = figureOutColor(corners,output[6],output[1]);
221
    if( color52<0 ) return ERROR_CORNER_BR_MISSING;
222
    int color53 = figureOutColor(corners,output[4],output[6]);
223
    if( color53<0 ) return ERROR_CORNER_BO_MISSING;
224
    if( color51!=color52 || color51!=color53 ) return ERROR_CORNERS_CANNOT;
225
    output[5] = color51;
226
227
    int color71 = figureOutColor(corners,output[3],output[6]);
228
    if( color71<0 ) return ERROR_CORNER_BL_MISSING;
229
    int color72 = figureOutColor(corners,output[4],output[3]);
230
    if( color72<0 ) return ERROR_CORNER_FL_MISSING;
231
    int color73 = figureOutColor(corners,output[6],output[4]);
232
    if( color73<0 ) return ERROR_CORNER_BO_MISSING;
233
    if( color71!=color72 || color71!=color73 ) return ERROR_CORNERS_CANNOT;
234
    output[7] = color71;
235
236
    return 0;
237
    }
238
239
///////////////////////////////////////////////////////////////////////////////////////////////////
240
241 478a4c45 Leszek Koltunski
  private int checkAllColorsDifferent()
242 62c08ea7 Leszek Koltunski
    {
243
    for(int i=0; i<8; i++)
244
      {
245
      boolean present = false;
246
247
      for(int j=0; j<8; j++)
248 478a4c45 Leszek Koltunski
        if( mFaceColors[j]==i )
249 62c08ea7 Leszek Koltunski
          {
250
          present=true;
251
          break;
252
          }
253
254
      if( !present ) return ERROR_CORNERS_CANNOT;
255
      }
256
257
    return 0;
258
    }
259
260 379ba26d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
261
262
  private int checkAllCentersPresent(int[] centers)
263
    {
264 62c08ea7 Leszek Koltunski
    for(int i=0; i<8; i++)
265
      {
266
      boolean present = false;
267
268
      for(int j=0; j<8; j++)
269
        if( centers[j]==i )
270
          {
271
          present=true;
272
          break;
273
          }
274
275
      if( !present )
276
        {
277
        switch(i)
278
          {
279
          case 0: return ERROR_CENTER_0_MISSING;
280
          case 1: return ERROR_CENTER_1_MISSING;
281
          case 2: return ERROR_CENTER_2_MISSING;
282
          case 3: return ERROR_CENTER_3_MISSING;
283
          case 4: return ERROR_CENTER_4_MISSING;
284
          case 5: return ERROR_CENTER_5_MISSING;
285
          case 6: return ERROR_CENTER_6_MISSING;
286
          case 7: return ERROR_CENTER_7_MISSING;
287
          }
288
        }
289
      }
290
291 379ba26d Leszek Koltunski
    return 0;
292
    }
293
294
///////////////////////////////////////////////////////////////////////////////////////////////////
295
296
  private void getCorners(TwistyObject object, int[][] corners)
297
    {
298 030f1bf4 Leszek Koltunski
    corners[0][0] = object.getCubitFaceStickerIndex( 0,5); // FR
299
    corners[0][1] = object.getCubitFaceStickerIndex( 0,4);
300
    corners[0][2] = object.getCubitFaceStickerIndex( 0,0);
301
    corners[0][3] = object.getCubitFaceStickerIndex( 0,1);
302
303
    corners[1][0] = object.getCubitFaceStickerIndex( 1,2); // BR
304
    corners[1][1] = object.getCubitFaceStickerIndex( 1,6);
305
    corners[1][2] = object.getCubitFaceStickerIndex( 1,5);
306
    corners[1][3] = object.getCubitFaceStickerIndex( 1,1);
307
308
    corners[2][0] = object.getCubitFaceStickerIndex( 2,7); // BL
309
    corners[2][1] = object.getCubitFaceStickerIndex( 2,6);
310
    corners[2][2] = object.getCubitFaceStickerIndex( 2,2);
311
    corners[2][3] = object.getCubitFaceStickerIndex( 2,3);
312
313
    corners[3][0] = object.getCubitFaceStickerIndex( 3,0); // FL
314
    corners[3][1] = object.getCubitFaceStickerIndex( 3,4);
315
    corners[3][2] = object.getCubitFaceStickerIndex( 3,7);
316
    corners[3][3] = object.getCubitFaceStickerIndex( 3,3);
317 379ba26d Leszek Koltunski
318
    corners[4][0] = object.getCubitFaceStickerIndex( 4,0); // U
319
    corners[4][1] = object.getCubitFaceStickerIndex( 4,3);
320
    corners[4][2] = object.getCubitFaceStickerIndex( 4,2);
321
    corners[4][3] = object.getCubitFaceStickerIndex( 4,1);
322
323 030f1bf4 Leszek Koltunski
    corners[5][0] = object.getCubitFaceStickerIndex( 5,5); // D
324
    corners[5][1] = object.getCubitFaceStickerIndex( 5,6);
325
    corners[5][2] = object.getCubitFaceStickerIndex( 5,7);
326
    corners[5][3] = object.getCubitFaceStickerIndex( 5,4);
327 379ba26d Leszek Koltunski
    }
328
329
///////////////////////////////////////////////////////////////////////////////////////////////////
330
331
  private void getCenters(TwistyObject object, int[] centers)
332
    {
333 62c08ea7 Leszek Koltunski
    centers[0] = object.getCubitFaceStickerIndex( 9,0); // UF
334
    centers[1] = object.getCubitFaceStickerIndex( 6,0); // UR
335
    centers[2] = object.getCubitFaceStickerIndex( 7,0); // UB
336
    centers[3] = object.getCubitFaceStickerIndex( 8,0); // UL
337
    centers[4] = object.getCubitFaceStickerIndex(13,0); // DF
338
    centers[5] = object.getCubitFaceStickerIndex(10,1); // DR
339
    centers[6] = object.getCubitFaceStickerIndex(11,0); // DB
340
    centers[7] = object.getCubitFaceStickerIndex(12,0); // DL
341 379ba26d Leszek Koltunski
    }
342
343 9a39aabf Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
344
345
  public int tablebaseIndex(TwistyObject object)
346
    {
347 379ba26d Leszek Koltunski
    int[][] corners = new int[6][4];
348
    int[] centers = new int[8];
349
350
    getCorners(object,corners);
351
    getCenters(object,centers);
352
353
    int result1 = checkAllCentersPresent(centers);
354
    if( result1<0 ) return result1;
355
356 478a4c45 Leszek Koltunski
    int result2 = figureOutFaceColors(mFaceColors,centers,corners);
357 62c08ea7 Leszek Koltunski
    if( result2<0 ) return result2;
358
359 478a4c45 Leszek Koltunski
    int result3 = checkAllColorsDifferent();
360 62c08ea7 Leszek Koltunski
    if( result3<0 ) return result3;
361
362 478a4c45 Leszek Koltunski
    int[] corners_perm = getCornersPermutation(corners);
363 62c08ea7 Leszek Koltunski
    boolean even1 = TablebaseHelpers.permutationIsEven(corners_perm);
364
    if( !even1 ) return ERROR_TWO_CORNERS;
365
366 478a4c45 Leszek Koltunski
    int[] free_centers_perm = getFreeCentersPermutation(centers);
367 62c08ea7 Leszek Koltunski
    boolean even2 = TablebaseHelpers.permutationIsEven(free_centers_perm);
368
    if( !even2 ) return ERROR_TWO_CENTERS;
369
370 478a4c45 Leszek Koltunski
    int[] corners_twist = getCornersTwist(corners_perm, corners);
371 9fd4c04a Leszek Koltunski
/*
372 030f1bf4 Leszek Koltunski
android.util.Log.e("D", "faces: "+mFaceColors[0]+" "+mFaceColors[1]+" "+mFaceColors[2]+" "
373
+mFaceColors[3]+" "+mFaceColors[4]+" "+mFaceColors[5]+" "+mFaceColors[6]+" "+mFaceColors[7]);
374
375
android.util.Log.e("D", "corn perm: "+corners_perm[0]+" "+corners_perm[1]+" "+corners_perm[2]+" "
376
+corners_perm[3]+" "+corners_perm[4]+" "+corners_perm[5]);
377
378
android.util.Log.e("D", "corn twist: "+corners_twist[0]+" "+corners_twist[1]+" "+corners_twist[2]+" "
379
+corners_twist[3]+" "+corners_twist[4]+" "+corners_twist[5]);
380 9fd4c04a Leszek Koltunski
*/
381 62c08ea7 Leszek Koltunski
    int totalTwist = getTotalTwist(corners_twist);
382 11e67fa5 Leszek Koltunski
    if( totalTwist<0 ) return totalTwist;
383 62c08ea7 Leszek Koltunski
384
    int corners_perm_num = TablebaseHelpers.computeEvenPermutationNum(corners_perm);
385
    int centers_perm_num = TablebaseHelpers.computeEvenPermutationNum(free_centers_perm);
386
387 ca5260c2 Leszek Koltunski
    return centers_perm_num + 12*(totalTwist + 32*corners_perm_num);
388 9a39aabf Leszek Koltunski
    }
389
390 478a4c45 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
391
392
  private int getColorIndex4(int face)
393
    {
394
    switch(mFaceColors[face])
395
      {
396
      case 0: return R.string.color_violet4;
397
      case 1: return R.string.color_grey4;
398
      case 2: return R.string.color_blue4;
399
      case 3: return R.string.color_red4;
400
      case 4: return R.string.color_orange4;
401
      case 5: return R.string.color_green4;
402
      case 6: return R.string.color_white4;
403
      case 7: return R.string.color_yellow4;
404
      }
405
406
    return -1;
407
    }
408
409
///////////////////////////////////////////////////////////////////////////////////////////////////
410
411
  private int getColorIndex3(int face)
412
    {
413
    switch(mFaceColors[face])
414
      {
415
      case 0: return R.string.color_violet3;
416
      case 1: return R.string.color_grey3;
417
      case 2: return R.string.color_blue3;
418
      case 3: return R.string.color_red3;
419
      case 4: return R.string.color_orange3;
420
      case 5: return R.string.color_green3;
421
      case 6: return R.string.color_white3;
422
      case 7: return R.string.color_yellow3;
423
      }
424
425
    return -1;
426
    }
427
428
///////////////////////////////////////////////////////////////////////////////////////////////////
429
430
  private int getColorIndex2(int face)
431
    {
432 030f1bf4 Leszek Koltunski
    switch(face)
433 478a4c45 Leszek Koltunski
      {
434
      case 0: return R.string.color_violet2;
435
      case 1: return R.string.color_grey2;
436
      case 2: return R.string.color_blue2;
437
      case 3: return R.string.color_red2;
438
      case 4: return R.string.color_orange2;
439
      case 5: return R.string.color_green2;
440
      case 6: return R.string.color_white2;
441
      case 7: return R.string.color_yellow2;
442
      }
443
444
    return -1;
445
    }
446
447
///////////////////////////////////////////////////////////////////////////////////////////////////
448
449
  private String centerError(Resources res, int face)
450
    {
451
    String color = res.getString(getColorIndex2(face));
452
    return res.getString(R.string.solver_generic_missing_center,color);
453
    }
454
455
///////////////////////////////////////////////////////////////////////////////////////////////////
456
457
  private String cornerError(Resources res, int f1, int f2)
458
    {
459
    String c1 = res.getString(getColorIndex3(f1));
460
    String c2 = res.getString(getColorIndex4(f2));
461
    return res.getString(R.string.solver_generic_missing_corner2,c1,c2);
462
    }
463
464 9a39aabf Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
465
466
  public String error(int index, Resources res)
467
    {
468
    switch(index)
469
      {
470 478a4c45 Leszek Koltunski
      case ERROR_CORNER_FR_MISSING: return cornerError(res,1,4);
471
      case ERROR_CORNER_BR_MISSING: return cornerError(res,1,6);
472
      case ERROR_CORNER_BL_MISSING: return cornerError(res,3,6);
473
      case ERROR_CORNER_FL_MISSING: return cornerError(res,3,4);
474
      case ERROR_CORNER_TO_MISSING: return cornerError(res,1,3);
475
      case ERROR_CORNER_BO_MISSING: return cornerError(res,4,6);
476
477
      case ERROR_CENTER_0_MISSING : return centerError(res,0);
478
      case ERROR_CENTER_1_MISSING : return centerError(res,1);
479
      case ERROR_CENTER_2_MISSING : return centerError(res,2);
480
      case ERROR_CENTER_3_MISSING : return centerError(res,3);
481
      case ERROR_CENTER_4_MISSING : return centerError(res,4);
482
      case ERROR_CENTER_5_MISSING : return centerError(res,5);
483
      case ERROR_CENTER_6_MISSING : return centerError(res,6);
484
      case ERROR_CENTER_7_MISSING : return centerError(res,7);
485
486
      case ERROR_TWO_CORNERS      : return res.getString(R.string.solver_generic_two_corners);
487
      case ERROR_TWO_CENTERS      : return res.getString(R.string.solver_generic_two_centers);
488 11e67fa5 Leszek Koltunski
      case ERROR_CORNER_TWIST_90  : return res.getString(R.string.solver_generic_corner_twist) + " (90)";
489
      case ERROR_CORNER_TWIST_180 : return res.getString(R.string.solver_generic_corner_twist) + " (180)";
490 478a4c45 Leszek Koltunski
      case ERROR_CORNERS_CANNOT   : return res.getString(R.string.solver_generic_corners_cannot);
491 9a39aabf Leszek Koltunski
      }
492
493
    return null;
494
    }
495
}