Project

General

Profile

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

magiccube / src / main / java / org / distorted / solvers / SolverDino6.java @ db4775f7

1 a505bce0 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
import org.distorted.main.R;
15
import org.distorted.objectlib.main.ObjectSignatures;
16
import org.distorted.objectlib.main.TwistyObject;
17
import org.distorted.objectlib.tablebases.ImplementedTablebasesList;
18 742401b4 Leszek Koltunski
import org.distorted.objectlib.tablebases.TBDino6;
19
import org.distorted.objectlib.tablebases.TablebaseHelpers;
20 a505bce0 Leszek Koltunski
import org.distorted.objectlib.tablebases.TablebasesAbstract;
21
22
///////////////////////////////////////////////////////////////////////////////////////////////////
23
24
public class SolverDino6 extends SolverTablebase
25
{
26 03c3bcaa Leszek Koltunski
  private static final int ERROR_EDGE_MISSING        = -1;
27
  private static final int ERROR_EDGE_CANNOT         = -2;
28
  private static final int ERROR_EDGE_TWISTED        = -3;
29
  private static final int ERROR_EDGE_MONOCHROMATIC  = -4;
30 92116505 Leszek Koltunski
  private static final int ERROR_EDGE_TWICE          = -5;
31 742401b4 Leszek Koltunski
  private static final int ERROR_TWO_EDGES           = -6;
32 03c3bcaa Leszek Koltunski
33
  int[][] EDGE_MAP = {
34
                      {4,2},{0,4},{4,3},{1,4},
35
                      {2,0},{3,0},{3,1},{2,1},
36
                      {5,2},{0,5},{5,3},{1,5}
37
                     };
38 a505bce0 Leszek Koltunski
39
  private TablebasesAbstract mSolver;
40 03c3bcaa Leszek Koltunski
  private final int[] mFaceColors;
41 a505bce0 Leszek Koltunski
  private int mErrorColor1, mErrorColor2;
42
43
///////////////////////////////////////////////////////////////////////////////////////////////////
44
45
  public SolverDino6(Resources res, TwistyObject object)
46
    {
47
    super(res,object);
48 03c3bcaa Leszek Koltunski
    mFaceColors = new int[6];
49
    }
50
51
///////////////////////////////////////////////////////////////////////////////////////////////////
52
53
  private void getEdges(TwistyObject object, int[][] edges)
54
    {
55
    for(int i=0; i<12; i++)
56
      {
57
      edges[i][0] = object.getCubitFaceStickerIndex(i,0);
58
      edges[i][1] = object.getCubitFaceStickerIndex(i,1);
59
      }
60
    }
61
62
///////////////////////////////////////////////////////////////////////////////////////////////////
63
64 083d854d Leszek Koltunski
  private int computeOpposite(int color, int[][] edges)
65 03c3bcaa Leszek Koltunski
    {
66 083d854d Leszek Koltunski
    int[] buffer = new int[6];
67
    for(int i=0; i<6; i++) buffer[i] = 0;
68 03c3bcaa Leszek Koltunski
69
    for(int i=0; i<12; i++)
70
      {
71 083d854d Leszek Koltunski
      int e0 = edges[i][0];
72
      int e1 = edges[i][1];
73
74
      if( e0==color && e1==color)
75
        {
76
        mErrorColor1 = color;
77
        return ERROR_EDGE_MONOCHROMATIC;
78
        }
79
80
      if( e0==color )
81
        {
82
        buffer[e1]++;
83
84
        if( buffer[e1]>1 )
85
          {
86
          mErrorColor1 = color;
87
          mErrorColor2 = e1;
88
          return ERROR_EDGE_TWICE;
89
          }
90
        }
91
92
      if( e1==color )
93
        {
94
        buffer[e0]++;
95
96
        if( buffer[e0]>1 )
97
          {
98
          mErrorColor1 = color;
99
          mErrorColor2 = e0;
100
          return ERROR_EDGE_TWICE;
101
          }
102
        }
103 03c3bcaa Leszek Koltunski
      }
104
105
    int total = 0;
106
107
    for(int i=0; i<6; i++)
108 083d854d Leszek Koltunski
      if( buffer[i]==1 )
109 03c3bcaa Leszek Koltunski
        {
110
        if( i!=color) total++;
111
        else
112
          {
113
          mErrorColor1 = i;
114
          return ERROR_EDGE_MONOCHROMATIC;
115
          }
116
        }
117
118
    if( total==4 )
119
      for(int i=0; i<6; i++)
120 083d854d Leszek Koltunski
        if( buffer[i]==0 && i!=color ) return i;
121 03c3bcaa Leszek Koltunski
122
    return ERROR_EDGE_CANNOT;
123
    }
124
125
///////////////////////////////////////////////////////////////////////////////////////////////////
126
127
  private int fillUpRemainingFaceColors(boolean[] buffer)
128
    {
129
    for(int i=0; i<6; i++)
130
      {
131
      buffer[i] = false;
132
      }
133
    for(int i=0; i<6; i++)
134
      {
135
      int color = mFaceColors[i];
136
      if( color>=0 ) buffer[color] = true;
137
      }
138
139
    int total = 0;
140
    for(int i=0; i<6; i++)
141
      if( buffer[i] ) total++;
142
143
    if( total==4 )
144
      {
145
      for(int i=0; i<6; i++)
146
        if( !buffer[i] )
147
          {
148
          buffer[i]=true;
149
          mFaceColors[0] = i;
150
          break;
151
          }
152
      for(int i=0; i<6; i++)
153
        if( !buffer[i] )
154
          {
155
          buffer[i]=true;
156
          mFaceColors[1] = i;
157
          break;
158
          }
159
160
      return 0;
161
      }
162
163
    return ERROR_EDGE_CANNOT;
164
    }
165
166
///////////////////////////////////////////////////////////////////////////////////////////////////
167
168
  private int figureOutFaceColors(int[][] edges)
169
    {
170
    boolean[] present = new boolean[6];
171
172
    for(int i=0; i<6; i++) mFaceColors[i] = -1;
173
174
    for(int i=0; i<12; i++)
175
      {
176
      int[] edge = edges[i];
177
      int c0 = edge[0];
178
      int c1 = edge[1];
179
180
      if( c0>=0 && c0<6 ) present[c0] = true;
181
      if( c1>=0 && c1<6 ) present[c1] = true;
182
      }
183
184
    for(int i=0; i<6; i++)
185
      if( !present[i] )
186
        {
187
        mErrorColor1 = i;
188 083d854d Leszek Koltunski
        mErrorColor2 = (i<4 ? i+2 : i-2 );
189 03c3bcaa Leszek Koltunski
        return ERROR_EDGE_MISSING;
190
        }
191
192
    if( edges[0][0]==edges[0][1] ) return ERROR_EDGE_CANNOT;
193
194
    mFaceColors[4] = edges[0][0];
195
    mFaceColors[2] = edges[0][1];
196 083d854d Leszek Koltunski
    mFaceColors[5] = computeOpposite(mFaceColors[4], edges);
197 92116505 Leszek Koltunski
    if( mFaceColors[5]<0 ) return mFaceColors[5];
198 03c3bcaa Leszek Koltunski
199 083d854d Leszek Koltunski
    mFaceColors[3] = computeOpposite(mFaceColors[2], edges);
200 92116505 Leszek Koltunski
    if( mFaceColors[3]<0 ) return mFaceColors[3];
201 03c3bcaa Leszek Koltunski
202
    int success = fillUpRemainingFaceColors(present);
203
    if( success<0 ) return success;
204
205
    return 0;
206
    }
207
208
///////////////////////////////////////////////////////////////////////////////////////////////////
209
210
  private boolean notPresent(int face0, int face1, int[][] edges)
211
    {
212
    int c0=mFaceColors[face0];
213
    int c1=mFaceColors[face1];
214
215
    for(int i=0; i<12; i++)
216
      {
217
      int[] edge = edges[i];
218
      if( edge[0]==c0 && edge[1]==c1 ) return false;
219
      if( edge[0]==c1 && edge[1]==c0 ) return false;
220
      }
221
    return true;
222
    }
223
224
///////////////////////////////////////////////////////////////////////////////////////////////////
225
226
  public int checkAllPresent(int[][] edges)
227
    {
228
    for(int i=0; i<12; i++)
229
      {
230
      int[] map = EDGE_MAP[i];
231
      int m1 = map[0];
232
      int m2 = map[1];
233
234
      if( notPresent(m1,m2,edges) )
235
        {
236
        mErrorColor1 = mFaceColors[m1];
237
        mErrorColor2 = mFaceColors[m2];
238
        return ERROR_EDGE_MISSING;
239
        }
240
      }
241
242
    return 0;
243
    }
244
245
///////////////////////////////////////////////////////////////////////////////////////////////////
246
247
  private boolean wrongTwist(int face0, int face1, int[][] edges)
248
    {
249
    int c0=mFaceColors[face0];
250
    int c1=mFaceColors[face1];
251
252
    for(int i=0; i<12; i++)
253
      {
254
      int[] edge = edges[i];
255
      if( edge[1]==c0 && edge[0]==c1 ) return true;
256
      }
257
    return false;
258
    }
259
260
///////////////////////////////////////////////////////////////////////////////////////////////////
261
262
  public int checkTwist(int[][] edges)
263
    {
264
    for(int i=0; i<12; i++)
265
      {
266
      int[] map = EDGE_MAP[i];
267
      int m1 = map[0];
268
      int m2 = map[1];
269
270
      if( wrongTwist(m1,m2,edges) )
271
        {
272
        mErrorColor1 = mFaceColors[m1];
273
        mErrorColor2 = mFaceColors[m2];
274
        return ERROR_EDGE_TWISTED;
275
        }
276
      }
277
278
    return 0;
279 a505bce0 Leszek Koltunski
    }
280
281 742401b4 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
282
283
  private int getPerm(int face0, int face1, int[][] edges)
284
    {
285
    int c0=mFaceColors[face0];
286
    int c1=mFaceColors[face1];
287
288
    for(int i=0; i<12; i++)
289
      {
290
      int[] edge = edges[i];
291
      if( edge[0]==c0 && edge[1]==c1 ) return i;
292
      }
293
294
    return -1;
295
    }
296
297
///////////////////////////////////////////////////////////////////////////////////////////////////
298
299
  private int computePermutation(int[][] edges, int[] perm)
300
    {
301
    for(int i=0; i<12; i++)
302
      {
303
      int[] map = EDGE_MAP[i];
304
      int m1 = map[0];
305
      int m2 = map[1];
306
      perm[i] = getPerm(m1,m2,edges);
307
      }
308
309
    return 0;
310
    }
311
312 a505bce0 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
313
314
  public int tablebaseIndex(TwistyObject object)
315
    {
316
    int[][] edges = new int[12][2];
317 03c3bcaa Leszek Koltunski
    getEdges(object,edges);
318
319
    int result1 = figureOutFaceColors(edges);
320
    if( result1<0 ) return result1;
321
322
    int result2 = checkAllPresent(edges);
323
    if( result2<0 ) return result2;
324
325
    int result3 = checkTwist(edges);
326
    if( result3<0 ) return result3;
327
328 742401b4 Leszek Koltunski
    int[] perm = new int[12];
329
    int result4 = computePermutation(edges,perm);
330
    if( result4<0 ) return result4;
331
332
    if( !TablebaseHelpers.permutationIsEven(perm) ) return ERROR_TWO_EDGES;
333
334
    return TBDino6.getIndexFromPerm(perm);
335 a505bce0 Leszek Koltunski
    }
336
337
///////////////////////////////////////////////////////////////////////////////////////////////////
338
339
  private int getColorIndex3(int color)
340
    {
341
    switch(color)
342
      {
343
      case 0: return R.string.color_yellow3;
344
      case 1: return R.string.color_white3;
345
      case 2: return R.string.color_blue3;
346
      case 3: return R.string.color_green3;
347
      case 4: return R.string.color_red3;
348
      case 5: return R.string.color_orange3;
349
      }
350
351
    return -1;
352
    }
353
354
///////////////////////////////////////////////////////////////////////////////////////////////////
355
356
  private int getColorIndex6(int color)
357
    {
358
    switch(color)
359
      {
360
      case 0: return R.string.color_yellow6;
361
      case 1: return R.string.color_white6;
362
      case 2: return R.string.color_blue6;
363
      case 3: return R.string.color_green6;
364
      case 4: return R.string.color_red6;
365
      case 5: return R.string.color_orange6;
366
      }
367
368
    return -1;
369
    }
370
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372
373
  private String edgeMissingError(Resources res, int color0, int color1)
374
    {
375
    int j0 = getColorIndex3(color0);
376
    int j1 = getColorIndex6(color1);
377
378
    String c0 = res.getString(j0);
379
    String c1 = res.getString(j1);
380
381
    return res.getString(R.string.solver_generic_missing_edge,c0,c1);
382
    }
383
384
///////////////////////////////////////////////////////////////////////////////////////////////////
385
386
  private String edgeTwistedError(Resources res, int color0, int color1)
387
    {
388
    int j0 = getColorIndex3(color0);
389
    int j1 = getColorIndex6(color1);
390
391
    String c0 = res.getString(j0);
392
    String c1 = res.getString(j1);
393
394
    return res.getString(R.string.solver_generic_twisted_edge,c0,c1);
395
    }
396
397 03c3bcaa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
398
399
  private String edgeMonoError(Resources res, int color)
400
    {
401
    int j0 = getColorIndex3(color);
402
    int j1 = getColorIndex6(color);
403
    String c0 = res.getString(j0);
404
    String c1 = res.getString(j1);
405
406
    return res.getString(R.string.solver_generic_edge_mono,c0,c1);
407
    }
408
409 92116505 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
410
411
  private String edgeTwiceError(Resources res, int color0, int color1)
412
    {
413
    int j0 = getColorIndex3(color0);
414
    int j1 = getColorIndex6(color1);
415
    String c0 = res.getString(j0);
416
    String c1 = res.getString(j1);
417
418
    return res.getString(R.string.solver_generic_edge_twice,c0,c1);
419
    }
420
421 a505bce0 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
422
423
  public String error(int index, Resources res)
424
    {
425
    switch(index)
426
      {
427 03c3bcaa Leszek Koltunski
      case ERROR_EDGE_MISSING      : return edgeMissingError(res,mErrorColor1,mErrorColor2);
428
      case ERROR_EDGE_TWISTED      : return edgeTwistedError(res,mErrorColor1,mErrorColor2);
429
      case ERROR_EDGE_MONOCHROMATIC: return edgeMonoError(res,mErrorColor1);
430 92116505 Leszek Koltunski
      case ERROR_EDGE_TWICE        : return edgeTwiceError(res,mErrorColor1,mErrorColor2);
431 03c3bcaa Leszek Koltunski
      case ERROR_EDGE_CANNOT       : return res.getString(R.string.solver_generic_edges_cannot);
432 742401b4 Leszek Koltunski
      case ERROR_TWO_EDGES         : return res.getString(R.string.solver_generic_two_edges);
433 a505bce0 Leszek Koltunski
      }
434
435
    return null;
436
    }
437
438
///////////////////////////////////////////////////////////////////////////////////////////////////
439
440
  public int[][] solution(int index, Resources res)
441
    {
442
    if( mSolver==null )
443
      {
444 db4775f7 Leszek Koltunski
      mSolver = ImplementedTablebasesList.createPacked(res,ObjectSignatures.DINO_3);
445 a505bce0 Leszek Koltunski
      }
446
447
    return mSolver!=null ? mSolver.solution(index,null) : null;
448
    }
449
}