Project

General

Profile

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

magiccube / src / main / java / org / distorted / solvers / SolverDino6.java @ 03c3bcaa

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