Project

General

Profile

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

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

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.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
  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
  private static final int ERROR_EDGE_TWICE          = -5;
29

    
30
  int[][] EDGE_MAP = {
31
                      {4,2},{0,4},{4,3},{1,4},
32
                      {2,0},{3,0},{3,1},{2,1},
33
                      {5,2},{0,5},{5,3},{1,5}
34
                     };
35

    
36
  private TablebasesAbstract mSolver;
37
  private final int[] mFaceColors;
38
  private int mErrorColor1, mErrorColor2;
39

    
40
///////////////////////////////////////////////////////////////////////////////////////////////////
41

    
42
  public SolverDino6(Resources res, TwistyObject object)
43
    {
44
    super(res,object);
45
    mFaceColors = new int[6];
46
    }
47

    
48
///////////////////////////////////////////////////////////////////////////////////////////////////
49

    
50
  private void getEdges(TwistyObject object, int[][] edges)
51
    {
52
    for(int i=0; i<12; i++)
53
      {
54
      edges[i][0] = object.getCubitFaceStickerIndex(i,0);
55
      edges[i][1] = object.getCubitFaceStickerIndex(i,1);
56
      }
57
    }
58

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

    
61
  private int computeOpposite(int color, int[][] edges, boolean[] buffer)
62
    {
63
    for(int i=0; i<6; i++) buffer[i] = false;
64

    
65
    for(int i=0; i<12; i++)
66
      {
67
      int[] edge = edges[i];
68
      if( edge[0]==color ) buffer[edge[1]]=true;
69
      if( edge[1]==color ) buffer[edge[0]]=true;
70
      }
71

    
72
    int total = 0;
73

    
74
    for(int i=0; i<6; i++)
75
      if( buffer[i] )
76
        {
77
        if( i!=color) total++;
78
        else
79
          {
80
          mErrorColor1 = i;
81
          return ERROR_EDGE_MONOCHROMATIC;
82
          }
83
        }
84

    
85
    if( total==4 )
86
      for(int i=0; i<6; i++)
87
        if( !buffer[i] && i!=color ) return i;
88

    
89
    return ERROR_EDGE_CANNOT;
90
    }
91

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

    
94
  private int fillUpRemainingFaceColors(boolean[] buffer)
95
    {
96
    for(int i=0; i<6; i++)
97
      {
98
      buffer[i] = false;
99
      }
100
    for(int i=0; i<6; i++)
101
      {
102
      int color = mFaceColors[i];
103
      if( color>=0 ) buffer[color] = true;
104
      }
105

    
106
    int total = 0;
107
    for(int i=0; i<6; i++)
108
      if( buffer[i] ) total++;
109

    
110
    if( total==4 )
111
      {
112
      for(int i=0; i<6; i++)
113
        if( !buffer[i] )
114
          {
115
          buffer[i]=true;
116
          mFaceColors[0] = i;
117
          break;
118
          }
119
      for(int i=0; i<6; i++)
120
        if( !buffer[i] )
121
          {
122
          buffer[i]=true;
123
          mFaceColors[1] = i;
124
          break;
125
          }
126

    
127
      return 0;
128
      }
129

    
130
    return ERROR_EDGE_CANNOT;
131
    }
132

    
133
///////////////////////////////////////////////////////////////////////////////////////////////////
134

    
135
  private int figureOutFaceColors(int[][] edges)
136
    {
137
    boolean[] present = new boolean[6];
138

    
139
    for(int i=0; i<6; i++) mFaceColors[i] = -1;
140

    
141
    for(int i=0; i<12; i++)
142
      {
143
      int[] edge = edges[i];
144
      int c0 = edge[0];
145
      int c1 = edge[1];
146

    
147
      if( c0>=0 && c0<6 ) present[c0] = true;
148
      if( c1>=0 && c1<6 ) present[c1] = true;
149
      }
150

    
151
    for(int i=0; i<6; i++)
152
      if( !present[i] )
153
        {
154
        mErrorColor1 = i;
155
        mErrorColor2 = (i<5 ? i+1 : 4 );
156
        return ERROR_EDGE_MISSING;
157
        }
158

    
159
    if( edges[0][0]==edges[0][1] ) return ERROR_EDGE_CANNOT;
160

    
161
    mFaceColors[4] = edges[0][0];
162
    mFaceColors[2] = edges[0][1];
163
    mFaceColors[5] = computeOpposite(mFaceColors[4], edges, present);
164
    if( mFaceColors[5]<0 ) return mFaceColors[5];
165

    
166
    mFaceColors[3] = computeOpposite(mFaceColors[2], edges, present);
167
    if( mFaceColors[3]<0 ) return mFaceColors[3];
168

    
169
    int success = fillUpRemainingFaceColors(present);
170
    if( success<0 ) return success;
171

    
172
    return 0;
173
    }
174

    
175
///////////////////////////////////////////////////////////////////////////////////////////////////
176

    
177
  private boolean notPresent(int face0, int face1, int[][] edges)
178
    {
179
    int c0=mFaceColors[face0];
180
    int c1=mFaceColors[face1];
181

    
182
    for(int i=0; i<12; i++)
183
      {
184
      int[] edge = edges[i];
185
      if( edge[0]==c0 && edge[1]==c1 ) return false;
186
      if( edge[0]==c1 && edge[1]==c0 ) return false;
187
      }
188
    return true;
189
    }
190

    
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192

    
193
  public int checkAllPresent(int[][] edges)
194
    {
195
    for(int i=0; i<12; i++)
196
      {
197
      int[] map = EDGE_MAP[i];
198
      int m1 = map[0];
199
      int m2 = map[1];
200

    
201
      if( notPresent(m1,m2,edges) )
202
        {
203
        mErrorColor1 = mFaceColors[m1];
204
        mErrorColor2 = mFaceColors[m2];
205
        return ERROR_EDGE_MISSING;
206
        }
207
      }
208

    
209
    return 0;
210
    }
211

    
212
///////////////////////////////////////////////////////////////////////////////////////////////////
213

    
214
  private boolean wrongTwist(int face0, int face1, int[][] edges)
215
    {
216
    int c0=mFaceColors[face0];
217
    int c1=mFaceColors[face1];
218

    
219
    for(int i=0; i<12; i++)
220
      {
221
      int[] edge = edges[i];
222
      if( edge[1]==c0 && edge[0]==c1 ) return true;
223
      }
224
    return false;
225
    }
226

    
227
///////////////////////////////////////////////////////////////////////////////////////////////////
228

    
229
  public int checkTwist(int[][] edges)
230
    {
231
    for(int i=0; i<12; i++)
232
      {
233
      int[] map = EDGE_MAP[i];
234
      int m1 = map[0];
235
      int m2 = map[1];
236

    
237
      if( wrongTwist(m1,m2,edges) )
238
        {
239
        mErrorColor1 = mFaceColors[m1];
240
        mErrorColor2 = mFaceColors[m2];
241
        return ERROR_EDGE_TWISTED;
242
        }
243
      }
244

    
245
    return 0;
246
    }
247

    
248
///////////////////////////////////////////////////////////////////////////////////////////////////
249

    
250
  public int tablebaseIndex(TwistyObject object)
251
    {
252
    int[][] edges = new int[12][2];
253
    getEdges(object,edges);
254

    
255
    int result1 = figureOutFaceColors(edges);
256
    if( result1<0 ) return result1;
257

    
258
for(int i=0; i<6; i++)
259
  {
260
  android.util.Log.e("D", "face "+i+" : "+mFaceColors[i]);
261
  }
262

    
263
    int result2 = checkAllPresent(edges);
264
    if( result2<0 ) return result2;
265

    
266
    int result3 = checkTwist(edges);
267
    if( result3<0 ) return result3;
268

    
269
    return 0;
270
    }
271

    
272
///////////////////////////////////////////////////////////////////////////////////////////////////
273

    
274
  private int getColorIndex3(int color)
275
    {
276
    switch(color)
277
      {
278
      case 0: return R.string.color_yellow3;
279
      case 1: return R.string.color_white3;
280
      case 2: return R.string.color_blue3;
281
      case 3: return R.string.color_green3;
282
      case 4: return R.string.color_red3;
283
      case 5: return R.string.color_orange3;
284
      }
285

    
286
    return -1;
287
    }
288

    
289
///////////////////////////////////////////////////////////////////////////////////////////////////
290

    
291
  private int getColorIndex6(int color)
292
    {
293
    switch(color)
294
      {
295
      case 0: return R.string.color_yellow6;
296
      case 1: return R.string.color_white6;
297
      case 2: return R.string.color_blue6;
298
      case 3: return R.string.color_green6;
299
      case 4: return R.string.color_red6;
300
      case 5: return R.string.color_orange6;
301
      }
302

    
303
    return -1;
304
    }
305

    
306
///////////////////////////////////////////////////////////////////////////////////////////////////
307

    
308
  private String edgeMissingError(Resources res, int color0, int color1)
309
    {
310
    int j0 = getColorIndex3(color0);
311
    int j1 = getColorIndex6(color1);
312

    
313
    String c0 = res.getString(j0);
314
    String c1 = res.getString(j1);
315

    
316
    return res.getString(R.string.solver_generic_missing_edge,c0,c1);
317
    }
318

    
319
///////////////////////////////////////////////////////////////////////////////////////////////////
320

    
321
  private String edgeTwistedError(Resources res, int color0, int color1)
322
    {
323
    int j0 = getColorIndex3(color0);
324
    int j1 = getColorIndex6(color1);
325

    
326
    String c0 = res.getString(j0);
327
    String c1 = res.getString(j1);
328

    
329
    return res.getString(R.string.solver_generic_twisted_edge,c0,c1);
330
    }
331

    
332
///////////////////////////////////////////////////////////////////////////////////////////////////
333

    
334
  private String edgeMonoError(Resources res, int color)
335
    {
336
    int j0 = getColorIndex3(color);
337
    int j1 = getColorIndex6(color);
338
    String c0 = res.getString(j0);
339
    String c1 = res.getString(j1);
340

    
341
    return res.getString(R.string.solver_generic_edge_mono,c0,c1);
342
    }
343

    
344
///////////////////////////////////////////////////////////////////////////////////////////////////
345

    
346
  private String edgeTwiceError(Resources res, int color0, int color1)
347
    {
348
    int j0 = getColorIndex3(color0);
349
    int j1 = getColorIndex6(color1);
350
    String c0 = res.getString(j0);
351
    String c1 = res.getString(j1);
352

    
353
    return res.getString(R.string.solver_generic_edge_twice,c0,c1);
354
    }
355

    
356
///////////////////////////////////////////////////////////////////////////////////////////////////
357

    
358
  public String error(int index, Resources res)
359
    {
360
    switch(index)
361
      {
362
      case ERROR_EDGE_MISSING      : return edgeMissingError(res,mErrorColor1,mErrorColor2);
363
      case ERROR_EDGE_TWISTED      : return edgeTwistedError(res,mErrorColor1,mErrorColor2);
364
      case ERROR_EDGE_MONOCHROMATIC: return edgeMonoError(res,mErrorColor1);
365
      case ERROR_EDGE_TWICE        : return edgeTwiceError(res,mErrorColor1,mErrorColor2);
366
      case ERROR_EDGE_CANNOT       : return res.getString(R.string.solver_generic_edges_cannot);
367
      }
368

    
369
    return null;
370
    }
371

    
372
///////////////////////////////////////////////////////////////////////////////////////////////////
373

    
374
  public int[][] solution(int index, Resources res)
375
    {
376
    if( mSolver==null )
377
      {
378
      mSolver = ImplementedTablebasesList.createUnpacked(ObjectSignatures.DINO_3);
379

    
380
      if( mSolver!=null )
381
        {
382
        mSolver.createTablebase(-1);
383
        }
384
      }
385

    
386
    return mSolver!=null ? mSolver.solution(index,null) : null;
387
    }
388
}  
389

    
(5-5/13)