Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / tablebases / TBCuboid323.java @ 5f8356d7

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 5f8356d7 Leszek Koltunski
  private static final int[][] CORNER_MAP_INVERTED = new int[8][8];
44
  private static final int[][] EDGE_MAP_INVERTED = new int[8][8];
45
46
  static
47
    {
48
    for(int i=0; i<8; i++)
49
      for(int j=0; j<8; j++)
50
        {
51
        CORNER_MAP_INVERTED[i][j] = findIndex(CORNER_MAP[i],j);
52
        EDGE_MAP_INVERTED[i][j]   = findIndex(EDGE_MAP[i],j);
53
        }
54
    };
55
56 d3fa1eed Leszek Koltunski
  private int[][] mAngles;
57
  private boolean mUpsideDown;
58
59 6ab0bce9 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
60 5b9e0ba4 Leszek Koltunski
// remove perm[1] which is always equal to 1.
61 6ab0bce9 Leszek Koltunski
62 08451d7f Leszek Koltunski
  public static int[] edgePermTo7(int[] perm)
63 6ab0bce9 Leszek Koltunski
    {
64
    int[] ret = new int[7];
65
66 5b9e0ba4 Leszek Koltunski
    ret[0] = perm[0]; if( ret[0]>1 ) ret[0]--;
67
    ret[1] = perm[2]; if( ret[1]>1 ) ret[1]--;
68
    ret[2] = perm[3]; if( ret[2]>1 ) ret[2]--;
69
    ret[3] = perm[4]; if( ret[3]>1 ) ret[3]--;
70
    ret[4] = perm[5]; if( ret[4]>1 ) ret[4]--;
71
    ret[5] = perm[6]; if( ret[5]>1 ) ret[5]--;
72
    ret[6] = perm[7]; if( ret[6]>1 ) ret[6]--;
73 6ab0bce9 Leszek Koltunski
74
    return ret;
75
    }
76
77
///////////////////////////////////////////////////////////////////////////////////////////////////
78 c64217f7 Leszek Koltunski
// reverse the above
79 6ab0bce9 Leszek Koltunski
80 5b9e0ba4 Leszek Koltunski
  private static int[] edgePermTo8(int[] perm)
81 6ab0bce9 Leszek Koltunski
    {
82
    int[] ret = new int[8];
83
84 5b9e0ba4 Leszek Koltunski
    ret[0] = perm[0]; if( ret[0]>=1 ) ret[0]++;
85
    ret[1] = 1;
86
    ret[2] = perm[1]; if( ret[2]>=1 ) ret[2]++;
87
    ret[3] = perm[2]; if( ret[3]>=1 ) ret[3]++;
88
    ret[4] = perm[3]; if( ret[4]>=1 ) ret[4]++;
89
    ret[5] = perm[4]; if( ret[5]>=1 ) ret[5]++;
90
    ret[6] = perm[5]; if( ret[6]>=1 ) ret[6]++;
91
    ret[7] = perm[6]; if( ret[7]>=1 ) ret[7]++;
92 6ab0bce9 Leszek Koltunski
93
    return ret;
94
    }
95
96
///////////////////////////////////////////////////////////////////////////////////////////////////
97
98 68b59ec3 Leszek Koltunski
  public TBCuboid323()
99
    {
100
    super();
101
    }
102
103
///////////////////////////////////////////////////////////////////////////////////////////////////
104
105
  public TBCuboid323(OperatingSystemInterface os)
106
    {
107 e1e92738 Leszek Koltunski
    super(os,new int[] {R.raw.cu_323_pruning7 ,R.raw.cu_323_pruning8 },
108
             new int[] {R.raw.cu_323_pruning17,R.raw.cu_323_pruning18} );
109 68b59ec3 Leszek Koltunski
    }
110
111 d3fa1eed Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
112
113
  public void initialize()
114
    {
115
    mUpsideDown = false;
116
    }
117
118 68b59ec3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
119
120
  int[][] getBasicAngles()
121
    {
122 d3fa1eed Leszek Koltunski
    if( mAngles==null )
123
      {
124
      int[] tmp2 = {2,2,2};
125
      int[] tmp4 = {4,4};
126
      mAngles = new int[][] { tmp2,tmp4,tmp2 };
127
      }
128
129
    return mAngles;
130 68b59ec3 Leszek Koltunski
    }
131
132
///////////////////////////////////////////////////////////////////////////////////////////////////
133
134
  Static3D[] getRotationAxis()
135
    {
136
    return new Static3D[]
137
         {
138
           new Static3D(1,0,0),
139
           new Static3D(0,1,0),
140
           new Static3D(0,0,1)
141
         };
142
    }
143
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145
146
  float[][] getPosition()
147
    {
148
    return new float[][]
149
      {
150
        { -1.0f, -0.5f, -1.0f },
151
        { -1.0f, -0.5f,  1.0f },
152
        { -1.0f,  0.5f, -1.0f },
153
        { -1.0f,  0.5f,  1.0f },
154
        {  1.0f, -0.5f, -1.0f },
155
        {  1.0f, -0.5f,  1.0f },
156
        {  1.0f,  0.5f, -1.0f },
157
        {  1.0f,  0.5f,  1.0f },
158
159
        {  0.0f, -0.5f, -1.0f },
160
        {  0.0f, -0.5f,  1.0f },
161
        {  0.0f,  0.5f, -1.0f },
162
        {  0.0f,  0.5f,  1.0f },
163
        { -1.0f, -0.5f,  0.0f },
164
        { -1.0f,  0.5f,  0.0f },
165
        {  1.0f, -0.5f,  0.0f },
166
        {  1.0f,  0.5f,  0.0f },
167
168
        {  0.0f,  0.5f,  0.0f },
169
        {  0.0f, -0.5f,  0.0f },
170
      };
171
    }
172
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174
175
  float[][] getCuts()
176
    {
177
    return new float[][] { {-0.5f,0.5f}, {0.0f}, {-0.5f,0.5f} };
178
    }
179
180
///////////////////////////////////////////////////////////////////////////////////////////////////
181
182
  boolean[][] getRotatable()
183
    {
184 5b9e0ba4 Leszek Koltunski
    return new boolean[][] { {true,false,true},{false,true},{true,true,false} };
185 68b59ec3 Leszek Koltunski
    }
186
187 3feba94e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
188
// we map the move (axis=2, middle layer) to move (axis=2,both middle and back layers).
189
// this way we can imitate move of the front layer (which we do not want to move because
190
// the edge1 piece has to always stay in its place)
191
192
  @Override
193
  int computeBitLayer(int ax, int layer)
194
    {
195
    if( ax!=2 ) return (1<<layer);
196
197
    switch(layer)
198
      {
199
      case 0 : return 1;
200
      case 1 : return 3;
201
      default: return 4;
202
      }
203
    }
204
205 31d0a3fc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
206
// this is too slow to be used for scrambling - scramble the 3x3x2 the old way.
207
208
  @Override
209
  public boolean useForScrambling()
210
    {
211
    return false;
212
    }
213
214 68b59ec3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
215
// specifically for the tablebase
216
///////////////////////////////////////////////////////////////////////////////////////////////////
217 d3fa1eed Leszek Koltunski
// now turn the (ax=2, middle and back layer) artificial moves [ introduced by computeBitLayer)
218
// back to the natural (ax=2, front layer). Turn the whole thing upside down each time we do it.
219
220
  @Override
221
  int[] newMove(int axis, int layer, int angle)
222
    {
223
    if( axis==2 )
224
      {
225
      if( layer==1 )
226
        {
227
        mUpsideDown = !mUpsideDown;
228
        return new int[] { axis, 4, angle };
229
        }
230
      }
231
    else if( mUpsideDown )
232
      {
233
      if( axis==0 ) layer=2-layer;
234
      if( axis==1 ) { layer=1-layer; angle = 4-angle; }
235
      }
236
237
    int maxAngle = mAngles[axis][layer];
238
    angle = maxAngle-angle;
239
    if( angle> 0.5f*maxAngle ) angle -= maxAngle;
240
    return new int[] { axis, (1<<layer), angle };
241
    }
242
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244 68b59ec3 Leszek Koltunski
// 8!*8!/4 --> https://www.jaapsch.net/puzzles/domino.htm
245
246
  int getSize()
247
    {
248
    return 406425600;
249
    }
250
251
///////////////////////////////////////////////////////////////////////////////////////////////////
252
253
  int getMinScramble()
254
    {
255
    return 13;
256
    }
257
258 45dc5cd7 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
259
260
  int[] getMidPruningLevels()
261
    {
262 5b9e0ba4 Leszek Koltunski
    return new int[] {7,8};
263 45dc5cd7 Leszek Koltunski
    }
264
265
///////////////////////////////////////////////////////////////////////////////////////////////////
266
267
  int[] getHighPruningLevels()
268
    {
269 3feba94e Leszek Koltunski
    return new int[] {17,18};
270 45dc5cd7 Leszek Koltunski
    }
271
272
///////////////////////////////////////////////////////////////////////////////////////////////////
273
274
  int getGodsNumber()
275
    {
276
    return 18;
277
    }
278
279
///////////////////////////////////////////////////////////////////////////////////////////////////
280
281
  boolean moveCanProceed(int lastA, int lastR, int currA, int currR)
282
    {
283
    return (lastA!=currA) || (lastR!=currR);
284
    }
285
286 6ab0bce9 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
287
288 398f2870 Leszek Koltunski
  private static int findIndex(int[] table, int value)
289 6ab0bce9 Leszek Koltunski
    {
290
    for(int i=0; i<8; i++)
291
      if( table[i]==value ) return i;
292
293
    return -1;
294
    }
295
296
///////////////////////////////////////////////////////////////////////////////////////////////////
297
298 5b9e0ba4 Leszek Koltunski
  private int centersInverted(int[] quats)
299 6ab0bce9 Leszek Koltunski
    {
300 5b9e0ba4 Leszek Koltunski
    int q = quats[16];
301
    return (q==0 || q==2 || q==3 || q==4) ? 0 : 1;
302 6ab0bce9 Leszek Koltunski
    }
303
304 398f2870 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
305
306 5b9e0ba4 Leszek Koltunski
  public static int[] quatsFromPermutations(int[] corner, int[] edge8, int centers)
307 398f2870 Leszek Koltunski
    {
308
    int[] quats = new int[18];
309
310
    for(int i=0; i<8; i++)
311
      {
312
      int q = CORNER_MAP[i][corner[i]];
313
      quats[i] = q;
314
      }
315
    for(int i=0; i<8; i++)
316
      {
317
      int q = EDGE_MAP[i][edge8[i]];
318
      quats[i+8] = q;
319
      }
320
321 5b9e0ba4 Leszek Koltunski
    if( centers==0 )
322
      {
323
      quats[16]=0;
324
      quats[17]=0;
325
      }
326
    else
327
      {
328
      quats[16]=5;
329
      quats[17]=5;
330
      }
331
332 398f2870 Leszek Koltunski
    return quats;
333
    }
334
335
///////////////////////////////////////////////////////////////////////////////////////////////////
336
337
  public static void cornerFromQuats(int[] corner_perm, int[] quats)
338
    {
339 5f8356d7 Leszek Koltunski
    for(int i=0; i<8; i++) corner_perm[i] = CORNER_MAP_INVERTED[i][quats[i]];
340 398f2870 Leszek Koltunski
    }
341
342
///////////////////////////////////////////////////////////////////////////////////////////////////
343
344
  public static void edgeFromQuats(int[] edge_perm, int[] quats)
345
    {
346 5f8356d7 Leszek Koltunski
    for(int i=0; i<8; i++) edge_perm[i] = EDGE_MAP_INVERTED[i][quats[i+8]];
347 398f2870 Leszek Koltunski
    }
348
349 68b59ec3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
350
351
  public int[] getQuats(int index)
352
    {
353 5b9e0ba4 Leszek Koltunski
    int cornerPermNum = (index%40320);
354 45dc5cd7 Leszek Koltunski
    index /= 40320;
355 5b9e0ba4 Leszek Koltunski
    int centers = (index%2);
356 6ab0bce9 Leszek Koltunski
    int edgePermNum = index/2;
357
358
    int[] corner_perm = new int[8];
359
    TablebaseHelpers.getPermutationFromNum(corner_perm,8,cornerPermNum);
360
    int[] edge_perm7 = new int[7];
361
    TablebaseHelpers.getPermutationFromNum(edge_perm7,7,edgePermNum);
362 5b9e0ba4 Leszek Koltunski
    int[] edge_perm8 = edgePermTo8(edge_perm7);
363 6ab0bce9 Leszek Koltunski
364 5b9e0ba4 Leszek Koltunski
    return quatsFromPermutations(corner_perm,edge_perm8,centers);
365 68b59ec3 Leszek Koltunski
    }
366
367
///////////////////////////////////////////////////////////////////////////////////////////////////
368
369
  public int getIndex(int[] quats)
370
    {
371 6ab0bce9 Leszek Koltunski
    int[] corner_perm = new int[8];
372 398f2870 Leszek Koltunski
    cornerFromQuats(corner_perm,quats);
373 6ab0bce9 Leszek Koltunski
    int[] edge_perm8  = new int[8];
374 398f2870 Leszek Koltunski
    edgeFromQuats(edge_perm8,quats);
375
    int[] edge_perm7  = edgePermTo7(edge_perm8);
376 6ab0bce9 Leszek Koltunski
377
    int corner_perm_num = TablebaseHelpers.computePermutationNum(corner_perm);
378
    int edge_perm_num = TablebaseHelpers.computePermutationNum(edge_perm7);
379 5b9e0ba4 Leszek Koltunski
    int centers = centersInverted(quats);
380 6ab0bce9 Leszek Koltunski
381 5b9e0ba4 Leszek Koltunski
    return corner_perm_num + 40320*( centers + 2*edge_perm_num);
382 68b59ec3 Leszek Koltunski
    }
383
}