Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / tablebases / TBCuboid323.java @ 398f2870

1 68b59ec3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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.objectlib.tablebases;
11
12
import org.distorted.library.type.Static3D;
13 feceac2f Leszek Koltunski
import org.distorted.objectlib.R;
14 68b59ec3 Leszek Koltunski
import org.distorted.objectlib.helpers.OperatingSystemInterface;
15
16
///////////////////////////////////////////////////////////////////////////////////////////////////
17
18 45dc5cd7 Leszek Koltunski
public class TBCuboid323 extends TablebasesPruning
19 68b59ec3 Leszek Koltunski
{
20 6ab0bce9 Leszek Koltunski
  private static final int[][] CORNER_MAP = new int[][]
21
      {
22
          {0,4,7,1,2,3,5,6},
23
          {2,0,1,6,3,4,7,5},
24
          {7,1,0,4,5,6,2,3},
25
          {1,6,2,0,7,5,3,4},
26
          {4,3,5,7,0,2,6,1},
27
          {3,2,6,5,4,0,1,7},
28
          {5,7,4,3,6,1,0,2},
29
          {6,5,3,2,1,7,4,0}
30
      };
31
  private static final int[][] EDGE_MAP = new int[][]
32
      {
33
          {0,3,5,1,4,7,2,6},
34
          {3,0,1,5,2,6,4,7},
35
          {5,1,0,3,7,4,6,2},
36
          {1,5,3,0,6,2,7,4},
37
          {2,4,7,6,0,1,3,5},
38
          {7,6,2,4,1,0,5,3},
39
          {4,2,6,7,3,5,0,1},
40
          {6,7,4,2,5,3,1,0}
41
      };
42
43 f5eeab30 Leszek Koltunski
  private static boolean mFixedEdgeIsDown;
44 45dc5cd7 Leszek Koltunski
  private int[][] mAngles;
45 6ab0bce9 Leszek Koltunski
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47
48 d0eb4ae9 Leszek Koltunski
  public static void initialize()
49 6ab0bce9 Leszek Koltunski
    {
50 d0eb4ae9 Leszek Koltunski
    mFixedEdgeIsDown = true;
51 6ab0bce9 Leszek Koltunski
    }
52
53
///////////////////////////////////////////////////////////////////////////////////////////////////
54 c64217f7 Leszek Koltunski
// We must have perm[1]==1 or perm[1]==3, depending on if inPlace==true;
55
// remove this extraneous perm member.
56 6ab0bce9 Leszek Koltunski
57 08451d7f Leszek Koltunski
  public static int[] edgePermTo7(int[] perm)
58 6ab0bce9 Leszek Koltunski
    {
59
    int[] ret = new int[7];
60
61 08451d7f Leszek Koltunski
    ret[0] = perm[0];
62
    ret[1] = perm[2];
63
    ret[2] = perm[3];
64
    ret[3] = perm[4];
65
    ret[4] = perm[5];
66
    ret[5] = perm[6];
67
    ret[6] = perm[7];
68
69
    int val = perm[1];
70 6ab0bce9 Leszek Koltunski
71
    for(int i=0; i<7; i++)
72
      if( ret[i]>val ) ret[i]--;
73
74
    return ret;
75
    }
76
77
///////////////////////////////////////////////////////////////////////////////////////////////////
78 c64217f7 Leszek Koltunski
// reverse the above
79 6ab0bce9 Leszek Koltunski
80
  private static int[] edgePermTo8(int[] perm, boolean inPlace)
81
    {
82
    int[] ret = new int[8];
83 08451d7f Leszek Koltunski
    int val = inPlace ? 1:3;
84 6ab0bce9 Leszek Koltunski
85 08451d7f Leszek Koltunski
    ret[0] = perm[0]; if( ret[0]>=val ) ret[0]++;
86
    ret[1] = val;
87
    ret[2] = perm[1]; if( ret[2]>=val ) ret[2]++;
88
    ret[3] = perm[2]; if( ret[3]>=val ) ret[3]++;
89
    ret[4] = perm[3]; if( ret[4]>=val ) ret[4]++;
90
    ret[5] = perm[4]; if( ret[5]>=val ) ret[5]++;
91
    ret[6] = perm[5]; if( ret[6]>=val ) ret[6]++;
92
    ret[7] = perm[6]; if( ret[7]>=val ) ret[7]++;
93 6ab0bce9 Leszek Koltunski
94
    return ret;
95
    }
96
97
///////////////////////////////////////////////////////////////////////////////////////////////////
98
99 68b59ec3 Leszek Koltunski
  public TBCuboid323()
100
    {
101
    super();
102
    }
103
104
///////////////////////////////////////////////////////////////////////////////////////////////////
105
106
  public TBCuboid323(OperatingSystemInterface os)
107
    {
108 c64217f7 Leszek Koltunski
    super(os,new int[] {R.raw.cu_323_pruning6,R.raw.cu_323_pruning7}, new int[] {R.raw.cu_323_pruning17,R.raw.cu_323_pruning18});
109 68b59ec3 Leszek Koltunski
    }
110
111
///////////////////////////////////////////////////////////////////////////////////////////////////
112
113
  int[][] getBasicAngles()
114
    {
115 45dc5cd7 Leszek Koltunski
    if( mAngles==null )
116
      {
117
      int[] tmp2 = {2,2,2};
118
      int[] tmp4 = {4,4};
119 d2216784 Leszek Koltunski
      mAngles = new int[][] { tmp2,tmp4,tmp2 };
120 45dc5cd7 Leszek Koltunski
      }
121
122
    return mAngles;
123 68b59ec3 Leszek Koltunski
    }
124
125
///////////////////////////////////////////////////////////////////////////////////////////////////
126
127
  Static3D[] getRotationAxis()
128
    {
129
    return new Static3D[]
130
         {
131
           new Static3D(1,0,0),
132
           new Static3D(0,1,0),
133
           new Static3D(0,0,1)
134
         };
135
    }
136
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138
139
  float[][] getPosition()
140
    {
141
    return new float[][]
142
      {
143
        { -1.0f, -0.5f, -1.0f },
144
        { -1.0f, -0.5f,  1.0f },
145
        { -1.0f,  0.5f, -1.0f },
146
        { -1.0f,  0.5f,  1.0f },
147
        {  1.0f, -0.5f, -1.0f },
148
        {  1.0f, -0.5f,  1.0f },
149
        {  1.0f,  0.5f, -1.0f },
150
        {  1.0f,  0.5f,  1.0f },
151
152
        {  0.0f, -0.5f, -1.0f },
153
        {  0.0f, -0.5f,  1.0f },
154
        {  0.0f,  0.5f, -1.0f },
155
        {  0.0f,  0.5f,  1.0f },
156
        { -1.0f, -0.5f,  0.0f },
157
        { -1.0f,  0.5f,  0.0f },
158
        {  1.0f, -0.5f,  0.0f },
159
        {  1.0f,  0.5f,  0.0f },
160
161
        {  0.0f,  0.5f,  0.0f },
162
        {  0.0f, -0.5f,  0.0f },
163
      };
164
    }
165
166
///////////////////////////////////////////////////////////////////////////////////////////////////
167
168
  float[][] getCuts()
169
    {
170
    return new float[][] { {-0.5f,0.5f}, {0.0f}, {-0.5f,0.5f} };
171
    }
172
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174
175
  boolean[][] getRotatable()
176
    {
177
    return new boolean[][] { {true,false,true},{true,false},{true,false,true} };
178
    }
179
180
///////////////////////////////////////////////////////////////////////////////////////////////////
181
// specifically for the tablebase
182 45dc5cd7 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
183 d0eb4ae9 Leszek Koltunski
// edge1 (i.e. the edge which is initially in the lower front) needs to stay in front.
184 45dc5cd7 Leszek Koltunski
185
  @Override
186
  int[] newMove(int axis, int layer, int angle)
187
    {
188 f5eeab30 Leszek Koltunski
    if( axis==2 && layer==2 ) mFixedEdgeIsDown = !mFixedEdgeIsDown;
189 d0eb4ae9 Leszek Koltunski
    if( axis==1 )
190
      {
191 398f2870 Leszek Koltunski
      if( angle==3 ) angle=-1;
192
193 d0eb4ae9 Leszek Koltunski
      if( layer==0 &&  mFixedEdgeIsDown ) return new int[] { axis, 2, angle };
194
      if( layer==1 && !mFixedEdgeIsDown ) return new int[] { axis, 1, angle };
195
      }
196 45dc5cd7 Leszek Koltunski
197
    int maxAngle = mAngles[axis][layer];
198
    angle = maxAngle-angle;
199
    if( angle> 0.5f*maxAngle ) angle -= maxAngle;
200 398f2870 Leszek Koltunski
201 45dc5cd7 Leszek Koltunski
    return new int[] { axis, (1<<layer), angle };
202
    }
203
204 68b59ec3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
205
// 8!*8!/4 --> https://www.jaapsch.net/puzzles/domino.htm
206
207
  int getSize()
208
    {
209
    return 406425600;
210
    }
211
212
///////////////////////////////////////////////////////////////////////////////////////////////////
213
214
  int getMinScramble()
215
    {
216
    return 13;
217
    }
218
219 45dc5cd7 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
220
221
  int[] getMidPruningLevels()
222
    {
223
    return new int[] {6,7};
224
    }
225
226
///////////////////////////////////////////////////////////////////////////////////////////////////
227
228
  int[] getHighPruningLevels()
229
    {
230 08451d7f Leszek Koltunski
    return null;//new int[] {17,18};
231 45dc5cd7 Leszek Koltunski
    }
232
233
///////////////////////////////////////////////////////////////////////////////////////////////////
234
235
  int getGodsNumber()
236
    {
237
    return 18;
238
    }
239
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241
242
  boolean moveCanProceed(int lastA, int lastR, int currA, int currR)
243
    {
244
    return (lastA!=currA) || (lastR!=currR);
245
    }
246
247 6ab0bce9 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
248
249 398f2870 Leszek Koltunski
  private static int findIndex(int[] table, int value)
250 6ab0bce9 Leszek Koltunski
    {
251
    for(int i=0; i<8; i++)
252
      if( table[i]==value ) return i;
253
254
    return -1;
255
    }
256
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258
259
  private boolean isFrontEdgeInItsPlace(int[] perm)
260
    {
261 08451d7f Leszek Koltunski
    return perm[1]==1;
262 45dc5cd7 Leszek Koltunski
    }
263
264
///////////////////////////////////////////////////////////////////////////////////////////////////
265
266 398f2870 Leszek Koltunski
  private void normalizeQuats(int[] quats)
267 45dc5cd7 Leszek Koltunski
    {
268 08451d7f Leszek Koltunski
    int mult=0;
269 45dc5cd7 Leszek Koltunski
270 08451d7f Leszek Koltunski
    switch(quats[9])
271 45dc5cd7 Leszek Koltunski
      {
272
      case 0: case 5: return;
273
      case 4: case 7: mult=2; break;
274
      case 1: case 3: mult=3; break;
275
      case 2: case 6: mult=4; break;
276
      }
277
278
    for(int i=0; i<16; i++) quats[i] = getMultQuat(mult,quats[i]);
279 6ab0bce9 Leszek Koltunski
    }
280
281 398f2870 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
282
283
  public static int[] quatsFromPermutations(int[] corner, int[] edge8)
284
    {
285
    int[] quats = new int[18];
286
287
    for(int i=0; i<8; i++)
288
      {
289
      int q = CORNER_MAP[i][corner[i]];
290
      quats[i] = q;
291
      }
292
    for(int i=0; i<8; i++)
293
      {
294
      int q = EDGE_MAP[i][edge8[i]];
295
      quats[i+8] = q;
296
      }
297
298
    return quats;
299
    }
300
301
///////////////////////////////////////////////////////////////////////////////////////////////////
302
303
  public static void cornerFromQuats(int[] corner_perm, int[] quats)
304
    {
305
    for(int i=0; i<8; i++) corner_perm[i] = findIndex( CORNER_MAP[i], quats[i]);
306
    }
307
308
///////////////////////////////////////////////////////////////////////////////////////////////////
309
310
  public static void edgeFromQuats(int[] edge_perm, int[] quats)
311
    {
312
    for(int i=0; i<8; i++) edge_perm[i] = findIndex( EDGE_MAP[i], quats[i+8]);
313
    }
314
315 68b59ec3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
316
317
  public int[] getQuats(int index)
318
    {
319 45dc5cd7 Leszek Koltunski
    int cornerPermNum = index%40320;
320
    index /= 40320;
321 6ab0bce9 Leszek Koltunski
    boolean inPlace = ((index%2)==0);
322
    int edgePermNum = index/2;
323
324
    int[] corner_perm = new int[8];
325
    TablebaseHelpers.getPermutationFromNum(corner_perm,8,cornerPermNum);
326
    int[] edge_perm7 = new int[7];
327
    TablebaseHelpers.getPermutationFromNum(edge_perm7,7,edgePermNum);
328
    int[] edge_perm8 = edgePermTo8(edge_perm7,inPlace);
329 c64217f7 Leszek Koltunski
/*
330
TablebaseHelpers.displayTable(corner_perm, "CORNER");
331
TablebaseHelpers.displayTable(edge_perm8, "EDGE8");
332
TablebaseHelpers.displayTable(edge_perm7, "EDGE7");
333
android.util.Log.e("D", "inPlace="+inPlace);
334
*/
335 6ab0bce9 Leszek Koltunski
336 398f2870 Leszek Koltunski
    return quatsFromPermutations(corner_perm,edge_perm8);
337 68b59ec3 Leszek Koltunski
    }
338
339
///////////////////////////////////////////////////////////////////////////////////////////////////
340
341
  public int getIndex(int[] quats)
342
    {
343 398f2870 Leszek Koltunski
    normalizeQuats(quats);
344
345 6ab0bce9 Leszek Koltunski
    int[] corner_perm = new int[8];
346 398f2870 Leszek Koltunski
    cornerFromQuats(corner_perm,quats);
347 6ab0bce9 Leszek Koltunski
    int[] edge_perm8  = new int[8];
348 398f2870 Leszek Koltunski
    edgeFromQuats(edge_perm8,quats);
349
    int[] edge_perm7  = edgePermTo7(edge_perm8);
350 6ab0bce9 Leszek Koltunski
351
    int corner_perm_num = TablebaseHelpers.computePermutationNum(corner_perm);
352
    int edge_perm_num = TablebaseHelpers.computePermutationNum(edge_perm7);
353
    boolean inPlace = isFrontEdgeInItsPlace(edge_perm8);
354
355 45dc5cd7 Leszek Koltunski
    return corner_perm_num + 40320*( (inPlace?0:1) + 2*edge_perm_num);
356 68b59ec3 Leszek Koltunski
    }
357
}