Project

General

Profile

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

magiccube / src / main / java / org / distorted / solvers / SolverCuboid232.java @ master

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.metadata.ListObjects;
17
import org.distorted.objectlib.main.TwistyObject;
18
import org.distorted.objectlib.tablebases.ImplementedTablebasesList;
19
import org.distorted.objectlib.tablebases.TablebaseHelpers;
20
import org.distorted.objectlib.tablebases.TablebasesAbstract;
21

    
22
///////////////////////////////////////////////////////////////////////////////////////////////////
23

    
24
public class SolverCuboid232 extends SolverTablebase
25
{
26
  private static final int ERROR_CORNER_135_MISSING = -1;
27
  private static final int ERROR_CORNER_134_MISSING = -2;
28
  private static final int ERROR_CORNER_125_MISSING = -3;
29
  private static final int ERROR_CORNER_124_MISSING = -4;
30
  private static final int ERROR_CORNER_035_MISSING = -5;
31
  private static final int ERROR_CORNER_034_MISSING = -6;
32
  private static final int ERROR_CORNER_025_MISSING = -7;
33
  private static final int ERROR_CORNER_024_MISSING = -8;
34

    
35
  private static final int ERROR_EDGE_15_MISSING = -9;
36
  private static final int ERROR_EDGE_14_MISSING = -10;
37
  private static final int ERROR_EDGE_05_MISSING = -11;
38
  private static final int ERROR_EDGE_04_MISSING = -12;
39

    
40
  private static final int ERROR_CORNERS_CANNOT  = -13;
41
  private static final int ERROR_EDGE_TWISTED    = -14;
42
  private static final int ERROR_CORNER_TWISTED  = -15;
43

    
44
  TablebasesAbstract mSolver;
45
  private final int[] mFaceColors;
46

    
47
///////////////////////////////////////////////////////////////////////////////////////////////////
48

    
49
  private int edgeIs(int[] edge, int i0, int i1)
50
    {
51
    int c0 = mFaceColors[i0];
52
    int c1 = mFaceColors[i1];
53

    
54
    if( edge[0]==c0 && edge[1]==c1 ) return 0;
55
    if( edge[0]==c1 && edge[1]==c0 ) return 1;
56
    return 2;
57
    }
58

    
59
///////////////////////////////////////////////////////////////////////////////////////////////////
60

    
61
  private int retEdgePermutation(int[] output, int[][] edges)
62
    {
63
    for(int i=0; i<4; i++) output[i] = -1;
64

    
65
    for(int i=0; i<4; i++)
66
      {
67
      int edge0 = edgeIs(edges[i],1,5);
68
           if( edge0==0 ) output[0]=i;
69
      else if( edge0==1 ) return ERROR_EDGE_TWISTED;
70

    
71
      int edge1 = edgeIs(edges[i],1,4);
72
           if( edge1==0 ) output[1]=i;
73
      else if( edge1==1 ) return ERROR_EDGE_TWISTED;
74

    
75
      int edge2 = edgeIs(edges[i],0,5);
76
           if( edge2==0 ) output[2]=i;
77
      else if( edge2==1 ) return ERROR_EDGE_TWISTED;
78

    
79
      int edge3 = edgeIs(edges[i],0,4);
80
           if( edge3==0 ) output[3]=i;
81
      else if( edge3==1 ) return ERROR_EDGE_TWISTED;
82
      }
83

    
84
    if( output[0]==-1 ) return ERROR_EDGE_15_MISSING;
85
    if( output[1]==-1 ) return ERROR_EDGE_14_MISSING;
86
    if( output[2]==-1 ) return ERROR_EDGE_05_MISSING;
87
    if( output[3]==-1 ) return ERROR_EDGE_04_MISSING;
88

    
89
    return 0;
90
    }
91

    
92
///////////////////////////////////////////////////////////////////////////////////////////////////
93

    
94
  private int cornerIs(int[] corner, int i0, int i1, int i2)
95
    {
96
    int c0 = mFaceColors[i0];
97
    int c1 = mFaceColors[i1];
98
    int c2 = mFaceColors[i2];
99

    
100
    if( corner[0]==c0 && corner[1]==c1 && corner[2]==c2 ) return 0;
101

    
102
    if( corner[0]==c0 && corner[1]==c2 && corner[2]==c1 ||
103
        corner[0]==c1 && corner[1]==c0 && corner[2]==c2 ||
104
        corner[0]==c1 && corner[1]==c2 && corner[2]==c0 ||
105
        corner[0]==c2 && corner[1]==c0 && corner[2]==c1 ||
106
        corner[0]==c2 && corner[1]==c1 && corner[2]==c0  ) return 1;
107

    
108
    return 2;
109
    }
110

    
111
///////////////////////////////////////////////////////////////////////////////////////////////////
112

    
113
  private int retCornerPermutation(int[] output, int[][] corners)
114
    {
115
    for(int i=0; i<8; i++) output[i] = -1;
116

    
117
    for(int i=0; i<8; i++)
118
      {
119
      int corner7 = cornerIs(corners[i],2,4,0);
120
           if( corner7==0 ) output[7]=i;
121
      else if( corner7==1 ) return ERROR_CORNER_TWISTED;
122

    
123
      int corner6 = cornerIs(corners[i],2,0,5);
124
           if( corner6==0 ) output[6]=i;
125
      else if( corner6==1 ) return ERROR_CORNER_TWISTED;
126

    
127
      int corner5 = cornerIs(corners[i],3,0,4);
128
           if( corner5==0 ) output[5]=i;
129
      else if( corner5==1 ) return ERROR_CORNER_TWISTED;
130

    
131
      int corner4 = cornerIs(corners[i],3,5,0);
132
           if( corner4==0 ) output[4]=i;
133
      else if( corner4==1 ) return ERROR_CORNER_TWISTED;
134

    
135
      int corner3 = cornerIs(corners[i],2,1,4);
136
           if( corner3==0 ) output[3]=i;
137
      else if( corner3==1 ) return ERROR_CORNER_TWISTED;
138

    
139
      int corner2 = cornerIs(corners[i],2,5,1);
140
           if( corner2==0 ) output[2]=i;
141
      else if( corner2==1 ) return ERROR_CORNER_TWISTED;
142

    
143
      int corner1 = cornerIs(corners[i],3,4,1);
144
           if( corner1==0 ) output[1]=i;
145
      else if( corner1==1 ) return ERROR_CORNER_TWISTED;
146

    
147
      int corner0 = cornerIs(corners[i],3,1,5);
148
           if( corner0==0 ) output[0]=i;
149
      else if( corner0==1 ) return ERROR_CORNER_TWISTED;
150
      }
151

    
152
    if( output[0]==-1 ) return ERROR_CORNER_135_MISSING;
153
    if( output[1]==-1 ) return ERROR_CORNER_134_MISSING;
154
    if( output[2]==-1 ) return ERROR_CORNER_125_MISSING;
155
    if( output[3]==-1 ) return ERROR_CORNER_124_MISSING;
156
    if( output[4]==-1 ) return ERROR_CORNER_035_MISSING;
157
    if( output[5]==-1 ) return ERROR_CORNER_034_MISSING;
158
    if( output[6]==-1 ) return ERROR_CORNER_025_MISSING;
159
    if( output[7]==-1 ) return ERROR_CORNER_024_MISSING;
160

    
161
    return 0;
162
    }
163

    
164
////////////////////////////////////////////////////////////////////////////////////////
165

    
166
  private int computeFaceColors(int[][] corners, int[][] edges)
167
    {
168
    mFaceColors[1] = edges[1][0];
169
    mFaceColors[4] = edges[1][1];
170

    
171
         if( edges[0][0]==mFaceColors[1] ) mFaceColors[5] = edges[0][1];
172
    else if( edges[2][0]==mFaceColors[1] ) mFaceColors[5] = edges[2][1];
173
    else if( edges[3][0]==mFaceColors[1] ) mFaceColors[5] = edges[3][1];
174
    else return ERROR_EDGE_TWISTED;
175

    
176
         if( edges[0][1]==mFaceColors[4] ) mFaceColors[0] = edges[0][0];
177
    else if( edges[2][1]==mFaceColors[4] ) mFaceColors[0] = edges[2][0];
178
    else if( edges[3][1]==mFaceColors[4] ) mFaceColors[0] = edges[3][0];
179
    else return ERROR_EDGE_TWISTED;
180

    
181
    boolean found2 = false;
182
    boolean found3 = false;
183

    
184
    for(int c=0; c<8; c++)
185
      {
186
      if( !found3 && corners[c][1]==mFaceColors[4] && corners[c][2]==mFaceColors[1] )
187
        {
188
        found3=true;
189
        mFaceColors[3] = corners[c][0];
190
        }
191
      if( !found2 && corners[c][1]==mFaceColors[1] && corners[c][2]==mFaceColors[4] )
192
        {
193
        found2=true;
194
        mFaceColors[2] = corners[c][0];
195
        }
196
      }
197

    
198
    if( !found2 || !found3 ) return ERROR_CORNERS_CANNOT;
199

    
200
    for(int i=0; i<6; i++)
201
      for(int j=i+1; j<6; j++)
202
        if( mFaceColors[i]==mFaceColors[j] ) return ERROR_CORNERS_CANNOT;
203

    
204
    return 0;
205
    }
206

    
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208

    
209
  private int[] correctEdgePerm(int[] perm)
210
    {
211
    int[] ret = new int[3];
212

    
213
    ret[0] = perm[0];
214
    ret[1] = perm[2];
215
    ret[2] = perm[3];
216

    
217
    if( ret[0]>1 ) ret[0]--;
218
    if( ret[1]>1 ) ret[1]--;
219
    if( ret[2]>1 ) ret[2]--;
220

    
221
    return ret;
222
    }
223

    
224
///////////////////////////////////////////////////////////////////////////////////////////////////
225

    
226
  public SolverCuboid232(OperatingSystemInterface os, Resources res, TwistyObject object)
227
    {
228
    super(os,res,object);
229
    mFaceColors = new int[6];
230
    }
231

    
232
///////////////////////////////////////////////////////////////////////////////////////////////////
233

    
234
  public int tablebaseIndex(TwistyObject object)
235
    {
236
    int[][] corners= new int[8][3];
237
    int[][] edges  = new int[4][2];
238

    
239
    corners[0][0] = object.getCubitFaceStickerIndex(0,3);
240
    corners[0][1] = object.getCubitFaceStickerIndex(0,1);
241
    corners[0][2] = object.getCubitFaceStickerIndex(0,5);
242

    
243
    corners[1][0] = object.getCubitFaceStickerIndex(1,1);
244
    corners[1][1] = object.getCubitFaceStickerIndex(1,5);
245
    corners[1][2] = object.getCubitFaceStickerIndex(1,3);
246

    
247
    corners[2][0] = object.getCubitFaceStickerIndex(2,3);
248
    corners[2][1] = object.getCubitFaceStickerIndex(2,1);
249
    corners[2][2] = object.getCubitFaceStickerIndex(2,5);
250

    
251
    corners[3][0] = object.getCubitFaceStickerIndex(3,3);
252
    corners[3][1] = object.getCubitFaceStickerIndex(3,1);
253
    corners[3][2] = object.getCubitFaceStickerIndex(3,5);
254

    
255
    corners[4][0] = object.getCubitFaceStickerIndex(4,5);
256
    corners[4][1] = object.getCubitFaceStickerIndex(4,3);
257
    corners[4][2] = object.getCubitFaceStickerIndex(4,1);
258

    
259
    corners[5][0] = object.getCubitFaceStickerIndex(5,3);
260
    corners[5][1] = object.getCubitFaceStickerIndex(5,1);
261
    corners[5][2] = object.getCubitFaceStickerIndex(5,5);
262

    
263
    corners[6][0] = object.getCubitFaceStickerIndex(6,3);
264
    corners[6][1] = object.getCubitFaceStickerIndex(6,1);
265
    corners[6][2] = object.getCubitFaceStickerIndex(6,5);
266

    
267
    corners[7][0] = object.getCubitFaceStickerIndex(7,5);
268
    corners[7][1] = object.getCubitFaceStickerIndex(7,3);
269
    corners[7][2] = object.getCubitFaceStickerIndex(7,1);
270

    
271
    edges[0][0] = object.getCubitFaceStickerIndex(8,5);
272
    edges[0][1] = object.getCubitFaceStickerIndex(8,3);
273
    edges[1][0] = object.getCubitFaceStickerIndex(9,3);
274
    edges[1][1] = object.getCubitFaceStickerIndex(9,5);
275
    edges[2][0] = object.getCubitFaceStickerIndex(10,5);
276
    edges[2][1] = object.getCubitFaceStickerIndex(10,3);
277
    edges[3][0] = object.getCubitFaceStickerIndex(11,3);
278
    edges[3][1] = object.getCubitFaceStickerIndex(11,5);
279

    
280
    int result0 = computeFaceColors(corners, edges);
281
    if( result0<0 ) return result0;
282

    
283
    int[] corner_perm = new int[8];
284
    int result1 = retCornerPermutation(corner_perm,corners);
285
    if( result1<0 ) return result1;
286

    
287
    int[] edge_perm = new int[4];
288
    int result2 = retEdgePermutation(edge_perm,edges);
289
    if( result2<0 ) return result2;
290

    
291
    int[] edge_perm2 = correctEdgePerm(edge_perm); // edge1 is fixed!
292

    
293
    int corner_perm_num = TablebaseHelpers.computePermutationNum(corner_perm);
294
    int edge_perm_num = TablebaseHelpers.computePermutationNum(edge_perm2);
295

    
296
    return edge_perm_num + 6*corner_perm_num;
297
    }
298

    
299
///////////////////////////////////////////////////////////////////////////////////////////////////
300

    
301
  private int getColorIndex4(int face)
302
    {
303
    switch(mFaceColors[face])
304
      {
305
      case 0: return R.string.color_yellow4;
306
      case 1: return R.string.color_white4;
307
      case 2: return R.string.color_blue4;
308
      case 3: return R.string.color_green4;
309
      case 4: return R.string.color_red4;
310
      case 5: return R.string.color_orange4;
311
      }
312

    
313
    return -1;
314
    }
315

    
316
///////////////////////////////////////////////////////////////////////////////////////////////////
317

    
318
  private int getColorIndex3(int face)
319
    {
320
    switch(mFaceColors[face])
321
      {
322
      case 0: return R.string.color_yellow3;
323
      case 1: return R.string.color_white3;
324
      case 2: return R.string.color_blue3;
325
      case 3: return R.string.color_green3;
326
      case 4: return R.string.color_red3;
327
      case 5: return R.string.color_orange3;
328
      }
329

    
330
    return -1;
331
    }
332

    
333
///////////////////////////////////////////////////////////////////////////////////////////////////
334

    
335
  private int getColorIndex6(int face)
336
    {
337
    switch(mFaceColors[face])
338
      {
339
      case 0: return R.string.color_yellow6;
340
      case 1: return R.string.color_white6;
341
      case 2: return R.string.color_blue6;
342
      case 3: return R.string.color_green6;
343
      case 4: return R.string.color_red6;
344
      case 5: return R.string.color_orange6;
345
      }
346

    
347
    return -1;
348
    }
349

    
350
///////////////////////////////////////////////////////////////////////////////////////////////////
351

    
352
  private String edgeError(Resources res, int face0, int face1)
353
    {
354
    int j0 = getColorIndex3(face0);
355
    int j1 = getColorIndex6(face1);
356

    
357
    String c0 = res.getString(j0);
358
    String c1 = res.getString(j1);
359

    
360
    return res.getString(R.string.solver_generic_missing_edge,c0,c1);
361
    }
362

    
363
///////////////////////////////////////////////////////////////////////////////////////////////////
364

    
365
  private String cornerError(Resources res, int face0, int face1, int face2)
366
    {
367
    int j0 = getColorIndex3(face0);
368
    int j1 = getColorIndex3(face1);
369
    int j2 = getColorIndex4(face2);
370

    
371
    String c0 = res.getString(j0);
372
    String c1 = res.getString(j1);
373
    String c2 = res.getString(j2);
374

    
375
    return res.getString(R.string.solver_generic_missing_corner,c0,c1,c2);
376
    }
377

    
378
///////////////////////////////////////////////////////////////////////////////////////////////////
379

    
380
  public String error(int index, Resources res)
381
    {
382
    switch(index)
383
      {
384
      case ERROR_CORNER_135_MISSING: return cornerError(res,1,3,5);
385
      case ERROR_CORNER_134_MISSING: return cornerError(res,1,3,4);
386
      case ERROR_CORNER_125_MISSING: return cornerError(res,1,2,5);
387
      case ERROR_CORNER_124_MISSING: return cornerError(res,1,2,4);
388
      case ERROR_CORNER_035_MISSING: return cornerError(res,0,3,5);
389
      case ERROR_CORNER_034_MISSING: return cornerError(res,0,3,4);
390
      case ERROR_CORNER_025_MISSING: return cornerError(res,0,2,5);
391
      case ERROR_CORNER_024_MISSING: return cornerError(res,0,2,4);
392

    
393
      case ERROR_EDGE_15_MISSING   : return edgeError(res,1,5);
394
      case ERROR_EDGE_14_MISSING   : return edgeError(res,1,4);
395
      case ERROR_EDGE_05_MISSING   : return edgeError(res,0,5);
396
      case ERROR_EDGE_04_MISSING   : return edgeError(res,0,4);
397

    
398
      case ERROR_CORNERS_CANNOT    : return res.getString(R.string.solver_generic_corners_cannot);
399
      case ERROR_EDGE_TWISTED      : return res.getString(R.string.solver_generic_edge_twist);
400
      case ERROR_CORNER_TWISTED    : return res.getString(R.string.solver_generic_corner_twist);
401
      }
402

    
403
    return null;
404
    }
405

    
406
///////////////////////////////////////////////////////////////////////////////////////////////////
407

    
408
  public int[][] solution(int index, OperatingSystemInterface os)
409
    {
410
    if( mSolver==null )
411
      {
412
      mSolver = ImplementedTablebasesList.createPacked(os, ListObjects.CU_232.name() );
413
      }
414

    
415
    return mSolver!=null ? mSolver.solution(index,null,os) : null;
416
    }
417
}  
418

    
(4-4/16)