Project

General

Profile

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

magiccube / src / main / java / org / distorted / solvers / SolverIvyCube.java @ master

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.helpers.OperatingSystemInterface;
16
import org.distorted.objectlib.metadata.ListObjects;
17
import org.distorted.objectlib.main.TwistyObject;
18
import org.distorted.objectlib.tablebases.ImplementedTablebasesList;
19
import org.distorted.objectlib.tablebases.TablebaseHelpers;
20
import org.distorted.objectlib.tablebases.TablebasesAbstract;
21

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

    
24
public class SolverIvyCube extends SolverTablebase
25
{
26
  private static final int ERROR_CENTER_O_MISSING = -1;
27
  private static final int ERROR_CENTER_W_MISSING = -2;
28
  private static final int ERROR_CENTER_G_MISSING = -3;
29
  private static final int ERROR_CENTER_Y_MISSING = -4;
30
  private static final int ERROR_CENTER_B_MISSING = -5;
31
  private static final int ERROR_CENTER_R_MISSING = -6;
32
  private static final int ERROR_TWO_CENTERS_SWAP = -7;
33
  private static final int ERROR_CORNERS_CANNOT   = -8;
34

    
35
  TablebasesAbstract mSolver;
36

    
37
///////////////////////////////////////////////////////////////////////////////////////////////////
38

    
39
  private int checkAllCentersPresent(int[] centers)
40
    {
41
    int numCenters = centers.length;
42

    
43
    for(int color=0; color<numCenters; color++)
44
      {
45
      boolean error = true;
46
      int center;
47

    
48
      for(center=0; center<numCenters; center++)
49
        if( centers[center]==color )
50
          {
51
          error = false;
52
          break;
53
          }
54

    
55
      if( error )
56
        {
57
        switch(color)
58
          {
59
          case 0: return ERROR_CENTER_Y_MISSING;
60
          case 1: return ERROR_CENTER_W_MISSING;
61
          case 2: return ERROR_CENTER_B_MISSING;
62
          case 3: return ERROR_CENTER_G_MISSING;
63
          case 4: return ERROR_CENTER_R_MISSING;
64
          case 5: return ERROR_CENTER_O_MISSING;
65
          }
66
        }
67
      }
68

    
69
    return 0;
70
    }
71

    
72
///////////////////////////////////////////////////////////////////////////////////////////////////
73

    
74
  private boolean checkCommonColor(int[] buffer, int index, int[] c1, int[] c2)
75
    {
76
    if( c1[0]==c1[1] || c1[0]==c1[2] || c1[1]==c1[2] ) return false;
77
    if( c2[0]==c2[1] || c2[0]==c2[2] || c2[1]==c2[2] ) return false;
78

    
79
    if( c1[0]==c2[0] && c1[1]!=c2[1] && c1[1]!=c2[2] && c1[2]!=c2[1] && c1[2]!=c2[2] )
80
      {
81
      buffer[index] = c1[0];
82
      return true;
83
      }
84
    if( c1[0]==c2[1] && c1[1]!=c2[0] && c1[1]!=c2[2] && c1[2]!=c2[0] && c1[2]!=c2[2] )
85
      {
86
      buffer[index] = c1[0];
87
      return true;
88
      }
89
    if( c1[0]==c2[2] && c1[1]!=c2[0] && c1[1]!=c2[1] && c1[2]!=c2[0] && c1[2]!=c2[1] )
90
      {
91
      buffer[index] = c1[0];
92
      return true;
93
      }
94

    
95
    if( c1[1]==c2[0] && c1[0]!=c2[1] && c1[0]!=c2[2] && c1[2]!=c2[1] && c1[2]!=c2[2] )
96
      {
97
      buffer[index] = c1[1];
98
      return true;
99
      }
100
    if( c1[1]==c2[1] && c1[0]!=c2[0] && c1[0]!=c2[2] && c1[2]!=c2[0] && c1[2]!=c2[2] )
101
      {
102
      buffer[index] = c1[1];
103
      return true;
104
      }
105
    if( c1[1]==c2[2] && c1[0]!=c2[0] && c1[0]!=c2[1] && c1[2]!=c2[0] && c1[2]!=c2[1] )
106
      {
107
      buffer[index] = c1[1];
108
      return true;
109
      }
110

    
111
    if( c1[2]==c2[0] && c1[1]!=c2[1] && c1[1]!=c2[2] && c1[0]!=c2[1] && c1[0]!=c2[2] )
112
      {
113
      buffer[index] = c1[2];
114
      return true;
115
      }
116
    if( c1[2]==c2[1] && c1[1]!=c2[0] && c1[1]!=c2[2] && c1[0]!=c2[0] && c1[0]!=c2[2] )
117
      {
118
      buffer[index] = c1[2];
119
      return true;
120
      }
121
    if( c1[2]==c2[2] && c1[1]!=c2[0] && c1[1]!=c2[1] && c1[0]!=c2[0] && c1[0]!=c2[1] )
122
      {
123
      buffer[index] = c1[2];
124
      return true;
125
      }
126

    
127
    return false;
128
    }
129

    
130
///////////////////////////////////////////////////////////////////////////////////////////////////
131

    
132
  private int computeFaceColor(int[] buffer, int[][] corners)
133
    {
134
    boolean success0 = checkCommonColor(buffer,0,corners[0],corners[3]);
135
    if( !success0 ) return ERROR_CORNERS_CANNOT;
136
    boolean success1 = checkCommonColor(buffer,1,corners[1],corners[2]);
137
    if( !success1 ) return ERROR_CORNERS_CANNOT;
138
    boolean success2 = checkCommonColor(buffer,2,corners[0],corners[1]);
139
    if( !success2 ) return ERROR_CORNERS_CANNOT;
140
    boolean success3 = checkCommonColor(buffer,3,corners[2],corners[3]);
141
    if( !success3 ) return ERROR_CORNERS_CANNOT;
142
    boolean success4 = checkCommonColor(buffer,4,corners[0],corners[2]);
143
    if( !success4 ) return ERROR_CORNERS_CANNOT;
144
    boolean success5 = checkCommonColor(buffer,5,corners[1],corners[3]);
145
    if( !success5 ) return ERROR_CORNERS_CANNOT;
146

    
147
    return 0;
148
    }
149

    
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151

    
152
  private int computeCenterColors(int[] buffer, int[] faceColors, int[] centers)
153
    {
154
    int numCenters = faceColors.length;
155

    
156
    for(int color=0; color<numCenters; color++)
157
      for(int center=0; center<numCenters; center++)
158
        if( centers[center]==faceColors[color] )
159
          {
160
          buffer[center]=color;
161
          }
162

    
163
    return TablebaseHelpers.permutationIsEven(buffer) ? 0 : ERROR_TWO_CENTERS_SWAP;
164
    }
165
////////////////////////////////////////////////////////////////////////////////////////
166

    
167
  private int computeCornerTwist(int[] corner, int color)
168
    {
169
    if( corner[0]==color ) return 0;
170
    if( corner[1]==color ) return 1;
171
    return 2;
172
    }
173

    
174
///////////////////////////////////////////////////////////////////////////////////////////////////
175

    
176
  public SolverIvyCube(OperatingSystemInterface os, Resources res, TwistyObject object)
177
    {
178
    super(os,res,object);
179
    }
180

    
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182

    
183
  public int tablebaseIndex(TwistyObject object)
184
    {
185
    int[][] corners     = new int[4][3];
186
    int[] centers       = new int[6];
187
    int[] twist         = new int[4];
188
    int[] face_colors   = new int[6];
189
    int[] center_colors = new int[6];
190

    
191
    for(int i=0; i<4; i++)
192
      for(int j=0; j<3; j++)
193
        corners[i][j] = object.getCubitFaceStickerIndex(i,j);
194

    
195
    for(int i=0; i<6; i++)
196
      centers[i] = object.getCubitFaceStickerIndex(i+4,0) - 6;
197

    
198
    int result1 = checkAllCentersPresent(centers);
199
    if( result1<0 ) return result1;
200

    
201
    int result2 = computeFaceColor(face_colors,corners);
202
    if( result2<0 ) return result2;
203

    
204
    int result3 = computeCenterColors(center_colors, face_colors, centers);
205
    if( result3<0 ) return result3;
206

    
207
    twist[0] = computeCornerTwist(corners[0],face_colors[4]);
208
    twist[1] = computeCornerTwist(corners[1],face_colors[5]);
209
    twist[2] = computeCornerTwist(corners[2],face_colors[4]);
210
    twist[3] = computeCornerTwist(corners[3],face_colors[5]);
211

    
212
    int perm_num = TablebaseHelpers.computeEvenPermutationNum(center_colors);
213

    
214
    return perm_num + 360*(twist[0]+ 3*(twist[1]+ 3*(twist[2]+ 3*twist[3])));
215
    }
216

    
217
///////////////////////////////////////////////////////////////////////////////////////////////////
218

    
219
  public String error(int index, Resources res)
220
    {
221
    switch(index)
222
      {
223
      case ERROR_CENTER_W_MISSING  : String colorW = res.getString(R.string.color_white2);
224
                                     return res.getString(R.string.solver_generic_missing_center,colorW);
225
      case ERROR_CENTER_O_MISSING  : String colorO = res.getString(R.string.color_orange2);
226
                                     return res.getString(R.string.solver_generic_missing_center,colorO);
227
      case ERROR_CENTER_G_MISSING  : String colorG = res.getString(R.string.color_green2);
228
                                     return res.getString(R.string.solver_generic_missing_center,colorG);
229
      case ERROR_CENTER_Y_MISSING  : String colorY = res.getString(R.string.color_yellow2);
230
                                     return res.getString(R.string.solver_generic_missing_center,colorY);
231
      case ERROR_CENTER_B_MISSING  : String colorB = res.getString(R.string.color_blue2);
232
                                     return res.getString(R.string.solver_generic_missing_center,colorB);
233
      case ERROR_CENTER_R_MISSING  : String colorR = res.getString(R.string.color_red2);
234
                                     return res.getString(R.string.solver_generic_missing_center,colorR);
235
      case ERROR_TWO_CENTERS_SWAP  : return res.getString(R.string.solver_generic_two_centers);
236
      case ERROR_CORNERS_CANNOT    : return res.getString(R.string.solver_generic_corners_cannot);
237
      }
238

    
239
    return null;
240
    }
241

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

    
244
  public int[][] solution(int index, OperatingSystemInterface os)
245
    {
246
    if( mSolver==null )
247
      {
248
      mSolver = ImplementedTablebasesList.createPacked(os, ListObjects.IVY_2.name() );
249
      }
250

    
251
    return mSolver!=null ? mSolver.solution(index,null,os) : null;
252
    }
253
}  
254

    
(8-8/16)