Project

General

Profile

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

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

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

    
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

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

    
39
///////////////////////////////////////////////////////////////////////////////////////////////////
40

    
41
  public SolverDino6(Resources res, TwistyObject object)
42
    {
43
    super(res,object);
44
    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
    }
248

    
249
///////////////////////////////////////////////////////////////////////////////////////////////////
250

    
251
  public int tablebaseIndex(TwistyObject object)
252
    {
253
    int[][] edges = new int[12][2];
254
    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
    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
///////////////////////////////////////////////////////////////////////////////////////////////////
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
///////////////////////////////////////////////////////////////////////////////////////////////////
346

    
347
  public String error(int index, Resources res)
348
    {
349
    switch(index)
350
      {
351
      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
      }
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
}  
377

    
(5-5/13)