Project

General

Profile

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

magiccube / src / main / java / org / distorted / solvers / SolverCube2.java @ 682f73d2

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.TablebaseHelpers;
19
import org.distorted.objectlib.tablebases.TablebasesAbstract;
20
import org.distorted.objectlib.tablebases.TablebasesCube2;
21

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

    
24
public class SolverCube2 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
  private static final int ERROR_CORNERS_CANNOT     = -9;
35
  private static final int ERROR_CORNER_TWISTED     = -10;
36

    
37
  TablebasesAbstract mSolver;
38
  private final int[] mFaceColors;
39

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

    
42
  private void fillCornerTwists(int[] output, int[][] corners, int[] perm)
43
    {
44
    for(int i=0; i<8; i++)
45
      {
46
      int[] c = corners[perm[i]];
47

    
48
           if( c[0]==mFaceColors[0] || c[0]==mFaceColors[1] ) output[i] = 0;
49
      else if( c[1]==mFaceColors[0] || c[1]==mFaceColors[1] ) output[i] = 1;
50
      else                                                    output[i] = 2;
51
      }
52
    }
53

    
54
////////////////////////////////////////////////////////////////////////////////////////
55

    
56
  private int cornerIndex(int[][] corners, int i1, int i2, int i3)
57
    {
58
    int c1 = mFaceColors[i1];
59
    int c2 = mFaceColors[i2];
60
    int c3 = mFaceColors[i3];
61

    
62
    for(int i=0; i<8; i++)
63
      {
64
      int[] cor = corners[i];
65

    
66
      if( (cor[0]==c1 && cor[1]==c2 && cor[2]==c3) ||
67
          (cor[0]==c2 && cor[1]==c3 && cor[2]==c1) ||
68
          (cor[0]==c3 && cor[1]==c1 && cor[2]==c2)  ) return i;
69
      }
70

    
71
    return -1;
72
    }
73

    
74
////////////////////////////////////////////////////////////////////////////////////////
75

    
76
  private int retCornerPermutation(int[] output, int[][] corners)
77
    {
78
    for(int i=0; i<8; i++) output[i] = -1;
79

    
80
    output[0] = cornerIndex(corners, 1,2,5);
81
    output[1] = cornerIndex(corners, 1,4,2);
82
    output[2] = cornerIndex(corners, 1,5,3);
83
    output[3] = cornerIndex(corners, 1,3,4);
84
    output[4] = cornerIndex(corners, 0,5,2);
85
    output[5] = cornerIndex(corners, 0,2,4);
86
    output[6] = cornerIndex(corners, 0,3,5);
87
    output[7] = cornerIndex(corners, 0,4,3);
88

    
89
    if( output[0]==-1 ) return ERROR_CORNER_125_MISSING;
90
    if( output[1]==-1 ) return ERROR_CORNER_124_MISSING;
91
    if( output[2]==-1 ) return ERROR_CORNER_135_MISSING;
92
    if( output[3]==-1 ) return ERROR_CORNER_134_MISSING;
93
    if( output[4]==-1 ) return ERROR_CORNER_025_MISSING;
94
    if( output[5]==-1 ) return ERROR_CORNER_024_MISSING;
95
    if( output[6]==-1 ) return ERROR_CORNER_035_MISSING;
96
    if( output[7]==-1 ) return ERROR_CORNER_034_MISSING;
97

    
98
    return 0;
99
    }
100

    
101
////////////////////////////////////////////////////////////////////////////////////////
102

    
103
  private int findColor(int[][] corners, int c1, int c2)
104
    {
105
    for(int i=0; i<8; i++)
106
      {
107
      int[] cor = corners[i];
108

    
109
      if( cor[0]==c1 && cor[1]==c2 ) return cor[2];
110
      if( cor[1]==c1 && cor[2]==c2 ) return cor[0];
111
      if( cor[2]==c1 && cor[0]==c2 ) return cor[1];
112
      }
113

    
114
    return -1;
115
    }
116

    
117
////////////////////////////////////////////////////////////////////////////////////////
118

    
119
  private int computeFaceColors(int[][] corners)
120
    {
121
    mFaceColors[1] = corners[1][0];
122
    mFaceColors[2] = corners[1][2];
123
    mFaceColors[4] = corners[1][1];
124

    
125
    mFaceColors[0] = findColor(corners,mFaceColors[2],mFaceColors[4]);
126
    mFaceColors[3] = findColor(corners,mFaceColors[4],mFaceColors[1]);
127
    mFaceColors[5] = findColor(corners,mFaceColors[1],mFaceColors[2]);
128

    
129
    for(int i=0; i<6; i++)
130
      {
131
      int color = mFaceColors[i];
132
      if( color<0 ) return ERROR_CORNERS_CANNOT;
133

    
134
      for(int j=i+1; j<6; j++)
135
        if( mFaceColors[j]==color ) return ERROR_CORNERS_CANNOT;
136
      }
137

    
138
    return 0;
139
    }
140

    
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142

    
143
  public SolverCube2(Resources res, TwistyObject object)
144
    {
145
    super(res,object);
146
    mFaceColors = new int[6];
147
    }
148

    
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150

    
151
  public int tablebaseIndex(TwistyObject object)
152
    {
153
    int[][] corners= new int[8][3];
154

    
155
    corners[0][0] = object.getCubitFaceStickerIndex(0,1);
156
    corners[0][1] = object.getCubitFaceStickerIndex(0,3);
157
    corners[0][2] = object.getCubitFaceStickerIndex(0,5);
158

    
159
    corners[1][0] = object.getCubitFaceStickerIndex(1,3);
160
    corners[1][1] = object.getCubitFaceStickerIndex(1,5);
161
    corners[1][2] = object.getCubitFaceStickerIndex(1,1);
162

    
163
    corners[2][0] = object.getCubitFaceStickerIndex(2,5);
164
    corners[2][1] = object.getCubitFaceStickerIndex(2,1);
165
    corners[2][2] = object.getCubitFaceStickerIndex(2,3);
166

    
167
    corners[3][0] = object.getCubitFaceStickerIndex(3,1);
168
    corners[3][1] = object.getCubitFaceStickerIndex(3,3);
169
    corners[3][2] = object.getCubitFaceStickerIndex(3,5);
170

    
171
    corners[4][0] = object.getCubitFaceStickerIndex(4,1);
172
    corners[4][1] = object.getCubitFaceStickerIndex(4,3);
173
    corners[4][2] = object.getCubitFaceStickerIndex(4,5);
174

    
175
    corners[5][0] = object.getCubitFaceStickerIndex(5,1);
176
    corners[5][1] = object.getCubitFaceStickerIndex(5,3);
177
    corners[5][2] = object.getCubitFaceStickerIndex(5,5);
178

    
179
    corners[6][0] = object.getCubitFaceStickerIndex(6,1);
180
    corners[6][1] = object.getCubitFaceStickerIndex(6,3);
181
    corners[6][2] = object.getCubitFaceStickerIndex(6,5);
182

    
183
    corners[7][0] = object.getCubitFaceStickerIndex(7,1);
184
    corners[7][1] = object.getCubitFaceStickerIndex(7,3);
185
    corners[7][2] = object.getCubitFaceStickerIndex(7,5);
186

    
187
    int result0 = computeFaceColors(corners);
188
    if( result0<0 ) return result0;
189

    
190
    int[] perm = new int[8];
191
    int result1 = retCornerPermutation(perm,corners);
192
    if( result1<0 ) return result1;
193

    
194
    int[] perm7 = TablebasesCube2.shrinkPerm(perm);
195
    int permNum = TablebaseHelpers.computePermutationNum(perm7);
196
    int[] twist = new int[8];
197
    fillCornerTwists(twist,corners,perm);
198

    
199
    int totalTwist = 0;
200
    for(int i=0; i<8; i++) totalTwist += twist[i];
201
    if( ((totalTwist)%3) != 0 ) return ERROR_CORNER_TWISTED;
202

    
203
    int twistNum = twist[0] + 3*(twist[2] + 3*(twist[3] + 3*(twist[4] + 3*(twist[5] + 3*twist[6]))));
204

    
205
    return twistNum + 729*permNum;
206
    }
207

    
208
///////////////////////////////////////////////////////////////////////////////////////////////////
209

    
210
  private int getColorIndex4(int face)
211
    {
212
    switch(mFaceColors[face])
213
      {
214
      case 0: return R.string.color_yellow4;
215
      case 1: return R.string.color_white4;
216
      case 2: return R.string.color_blue4;
217
      case 3: return R.string.color_green4;
218
      case 4: return R.string.color_red4;
219
      case 5: return R.string.color_orange4;
220
      }
221

    
222
    return -1;
223
    }
224

    
225
///////////////////////////////////////////////////////////////////////////////////////////////////
226

    
227
  private int getColorIndex3(int face)
228
    {
229
    switch(mFaceColors[face])
230
      {
231
      case 0: return R.string.color_yellow3;
232
      case 1: return R.string.color_white3;
233
      case 2: return R.string.color_blue3;
234
      case 3: return R.string.color_green3;
235
      case 4: return R.string.color_red3;
236
      case 5: return R.string.color_orange3;
237
      }
238

    
239
    return -1;
240
    }
241

    
242
///////////////////////////////////////////////////////////////////////////////////////////////////
243

    
244
  private String cornerError(Resources res, int face0, int face1, int face2)
245
    {
246
    int j0 = getColorIndex3(face0);
247
    int j1 = getColorIndex3(face1);
248
    int j2 = getColorIndex4(face2);
249

    
250
    String c0 = res.getString(j0);
251
    String c1 = res.getString(j1);
252
    String c2 = res.getString(j2);
253

    
254
    return res.getString(R.string.solver_generic_missing_corner,c0,c1,c2);
255
    }
256

    
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258

    
259
  public String error(int index, Resources res)
260
    {
261
    switch(index)
262
      {
263
      case ERROR_CORNER_135_MISSING: return cornerError(res,1,3,5);
264
      case ERROR_CORNER_134_MISSING: return cornerError(res,1,3,4);
265
      case ERROR_CORNER_125_MISSING: return cornerError(res,1,2,5);
266
      case ERROR_CORNER_124_MISSING: return cornerError(res,1,2,4);
267
      case ERROR_CORNER_035_MISSING: return cornerError(res,0,3,5);
268
      case ERROR_CORNER_034_MISSING: return cornerError(res,0,3,4);
269
      case ERROR_CORNER_025_MISSING: return cornerError(res,0,2,5);
270
      case ERROR_CORNER_024_MISSING: return cornerError(res,0,2,4);
271
      case ERROR_CORNERS_CANNOT    : return res.getString(R.string.solver_generic_corners_cannot);
272
      case ERROR_CORNER_TWISTED    : return res.getString(R.string.solver_generic_corner_twist);
273
      }
274

    
275
    return null;
276
    }
277

    
278
///////////////////////////////////////////////////////////////////////////////////////////////////
279

    
280
  public int[][] solution(int index, Resources res)
281
    {
282
    if( mSolver==null )
283
      {
284
      mSolver = ImplementedTablebasesList.createUnpacked(ObjectSignatures.CUBE_2);
285

    
286
      if( mSolver!=null )
287
        {
288
        int level = 5;
289
        mSolver.createTablebase(level);
290
        mSolver.testPruning(level);
291
        }
292
      }
293

    
294
    return mSolver!=null ? mSolver.solution(index,null) : null;
295
    }
296
}  
297

    
(2-2/10)