Project

General

Profile

« Previous | Next » 

Revision 3eedf418

Added by Leszek Koltunski over 1 year ago

Ivy Solver: implementations of getIndex() and getQuats() remain.

View differences:

src/main/java/org/distorted/solvers/ImplementedSolversList.java
18 18
{
19 19
  CUBE3_KOCIEMBA (ObjectSignatures.CUBE_3, R.string.solver_cube3_title, R.string.solver_cube3_description, true),
20 20
  PYRAMINX_DUO   (ObjectSignatures.PDUO_2, R.string.solver_pduo2_title, R.string.solver_pduo2_description, false),
21
  PYRAMINX       (ObjectSignatures.PYRA_3, R.string.solver_pyra3_title, R.string.solver_pyra3_description, false),
22 21
  IVY            (ObjectSignatures.IVY_2 , R.string.solver_ivy_title, R.string.solver_ivy_description, false),
22
  PYRAMINX       (ObjectSignatures.PYRA_3, R.string.solver_pyra3_title, R.string.solver_pyra3_description, false),
23 23
  TOWER          (ObjectSignatures.CU_232, R.string.solver_cu232_title, R.string.solver_cu232_description, false),
24 24
  DIAMOND        (ObjectSignatures.DIAM_2, R.string.solver_diam2_title, R.string.solver_diam2_description, false),
25 25
  ;
src/main/java/org/distorted/solvers/SolverIvyCube.java
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.ObjectType;
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 SolverIvyCube extends SolverTablebase
23
{
24
  private static final int ERROR_CENTER_O_MISSING = -1;
25
  private static final int ERROR_CENTER_W_MISSING = -2;
26
  private static final int ERROR_CENTER_G_MISSING = -3;
27
  private static final int ERROR_CENTER_Y_MISSING = -4;
28
  private static final int ERROR_CENTER_B_MISSING = -5;
29
  private static final int ERROR_CENTER_R_MISSING = -6;
30
  private static final int ERROR_TWO_CENTERS_SWAP = -7;
31
  private static final int ERROR_CORNERS_CANNOT   = -8;
32

  
33
  TablebasesAbstract mSolver;
34

  
35
///////////////////////////////////////////////////////////////////////////////////////////////////
36

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

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

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

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

  
67
    return 0;
68
    }
69

  
70
///////////////////////////////////////////////////////////////////////////////////////////////////
71

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

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

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

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

  
125
    return false;
126
    }
127

  
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129

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

  
145
    return 0;
146
    }
147

  
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149

  
150
  private int swaps(int val, int[] buffer, int len)
151
    {
152
    int ret = 0;
153

  
154
    for(int i=0; i<len; i++)
155
      {
156
           if( buffer[i] >val ) ret++;
157
      else if( buffer[i]==val ) return ret;
158
      }
159

  
160
    return -1;
161
    }
162

  
163
///////////////////////////////////////////////////////////////////////////////////////////////////
164

  
165
  private boolean permutationIsEven(int[] buffer)
166
    {
167
    int len = buffer.length;
168
    int numOfSwaps = 0;
169
    for(int i=0; i<len; i++) numOfSwaps += swaps(i,buffer,len);
170
    return (numOfSwaps%2==0);
171
    }
172

  
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174

  
175
  private int computeCenterColors(int[] buffer, int[] faceColors, int[] centers)
176
    {
177
    int numCenters = faceColors.length;
178

  
179
    for(int color=0; color<numCenters; color++)
180
      for(int center=0; center<numCenters; center++)
181
        if( centers[center]==faceColors[color] )
182
          {
183
          buffer[center]=color;
184
          }
185

  
186
    return permutationIsEven(buffer) ? 0 : ERROR_TWO_CENTERS_SWAP;
187
    }
188
////////////////////////////////////////////////////////////////////////////////////////
189

  
190
  private int computeCornerTwist(int[] corner, int color)
191
    {
192
    if( corner[0]==color ) return 0;
193
    if( corner[1]==color ) return 1;
194
    return 2;
195
    }
196

  
197
///////////////////////////////////////////////////////////////////////////////////////////////////
198

  
199
  private int computeOrder(int[] permutation, int index)
200
    {
201
    int numOfSmaller = 0;
202
    int val = permutation[index];
203

  
204
    for(int i=0; i<index; i++)
205
      if( permutation[i]<val ) numOfSmaller++;
206

  
207
    return index-numOfSmaller;
208
    }
209

  
210
///////////////////////////////////////////////////////////////////////////////////////////////////
211

  
212
  private int computeEvenPermutationNum(int[] permutation)
213
    {
214
    int n0 = computeOrder(permutation,0);
215
    int n1 = computeOrder(permutation,1);
216
    int n2 = computeOrder(permutation,2);
217
    int n3 = computeOrder(permutation,3);
218

  
219
    return n0 + 6*(n1+ 5*(n2+4*n3));
220
    }
221

  
222
///////////////////////////////////////////////////////////////////////////////////////////////////
223

  
224
  public SolverIvyCube(Resources res, TwistyObject object)
225
    {
226
    super(res,object);
227
    }
228

  
229
///////////////////////////////////////////////////////////////////////////////////////////////////
230

  
231
  public int tablebaseIndex(TwistyObject object)
232
    {
233
    int[][] corners     = new int[4][3];
234
    int[] centers       = new int[6];
235
    int[] twist         = new int[4];
236
    int[] face_colors   = new int[6];
237
    int[] center_colors = new int[6];
238

  
239
    for(int i=0; i<4; i++)
240
      for(int j=0; j<3; j++)
241
        corners[i][j] = object.getCubitFaceStickerIndex(i,j);
242

  
243
    for(int i=0; i<6; i++)
244
      centers[i] = object.getCubitFaceStickerIndex(i+4,0) - 6;
245

  
246
/*
247
for(int i=0; i<4; i++)
248
  {
249
  android.util.Log.e("D", "corner "+i+" : "+corners[i][0]+" "+corners[i][1]+" "+corners[i][2]);
250
  }
251
for(int i=0; i<6; i++)
252
  {
253
  android.util.Log.e("D", "center "+i+" : "+centers[i]);
254
  }
255
*/
256
    int result1 = checkAllCentersPresent(centers);
257
    if( result1<0 ) return result1;
258

  
259
    int result2 = computeFaceColor(face_colors,corners);
260
    if( result2<0 ) return result2;
261

  
262
    int result3 = computeCenterColors(center_colors, face_colors, centers);
263
    if( result3<0 ) return result3;
264

  
265
    twist[0] = computeCornerTwist(corners[0],face_colors[4]);
266
    twist[1] = computeCornerTwist(corners[1],face_colors[5]);
267
    twist[2] = computeCornerTwist(corners[2],face_colors[4]);
268
    twist[3] = computeCornerTwist(corners[3],face_colors[5]);
269

  
270
    int perm_num = computeEvenPermutationNum(center_colors);
271

  
272
//  android.util.Log.e("D", "twist : "+twist[0]+" "+twist[1]+" "+twist[2]+" "+twist[3]);
273

  
274
    return perm_num + 360*(twist[0]+ 3*(twist[1]+ 3*(twist[2]+ 3*twist[3])));
275
    }
276

  
277
///////////////////////////////////////////////////////////////////////////////////////////////////
278

  
279
  public String error(int index, Resources res)
280
    {
281
    switch(index)
282
      {
283
      case ERROR_CENTER_W_MISSING  : String colorW = res.getString(R.string.color_white2);
284
                                     return res.getString(R.string.solver_generic_missing_center,colorW);
285
      case ERROR_CENTER_O_MISSING  : String colorO = res.getString(R.string.color_orange2);
286
                                     return res.getString(R.string.solver_generic_missing_center,colorO);
287
      case ERROR_CENTER_G_MISSING  : String colorG = res.getString(R.string.color_green2);
288
                                     return res.getString(R.string.solver_generic_missing_center,colorG);
289
      case ERROR_CENTER_Y_MISSING  : String colorY = res.getString(R.string.color_yellow2);
290
                                     return res.getString(R.string.solver_generic_missing_center,colorY);
291
      case ERROR_CENTER_B_MISSING  : String colorB = res.getString(R.string.color_blue2);
292
                                     return res.getString(R.string.solver_generic_missing_center,colorB);
293
      case ERROR_CENTER_R_MISSING  : String colorR = res.getString(R.string.color_red2);
294
                                     return res.getString(R.string.solver_generic_missing_center,colorR);
295
      case ERROR_TWO_CENTERS_SWAP  : return res.getString(R.string.solver_generic_two_centers);
296
      case ERROR_CORNERS_CANNOT    : return res.getString(R.string.solver_generic_corners_cannot);
297
      }
298

  
299
    return null;
300
    }
301

  
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303

  
304
  public int[][] solution(int index, Resources res)
305
    {
306
    if( mSolver==null )
307
      {
308
      mSolver = ImplementedTablebasesList.createPacked(res,ObjectType.IVY_2);
309
      }
310

  
311
    return mSolver!=null ? mSolver.solution(index) : null;
312
    }
313
}  
314

  
src/main/java/org/distorted/solvers/SolverMain.java
81 81
      SolverTablebase solver = new SolverPyraminxDuo(mRes,mObject);
82 82
      solver.solve(screen);
83 83
      }
84
    else if( mSignature==ObjectSignatures.IVY_2 )
85
      {
86
      SolverTablebase solver = new SolverIvyCube(mRes,mObject);
87
      solver.solve(screen);
88
      }
84 89
    else
85 90
      {
86 91
      screen.displayErrorDialog(mRes.getString(R.string.solver_generic_not_implemented));

Also available in: Unified diff