Project

General

Profile

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

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

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.objectlib.tablebases;
11

    
12
import org.distorted.library.type.Static3D;
13
import org.distorted.objectlib.R;
14
import org.distorted.objectlib.helpers.OperatingSystemInterface;
15

    
16
///////////////////////////////////////////////////////////////////////////////////////////////////
17

    
18
public class TBCuboid323 extends TablebasesPruning
19
{
20
  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
  private static boolean mUpper;
44
  private static boolean mFixedEdgeIsDown;
45
  private int[][] mAngles;
46

    
47
///////////////////////////////////////////////////////////////////////////////////////////////////
48

    
49
  public static void setUpper(boolean upper, boolean isDown )
50
    {
51
    mUpper = upper;
52
    mFixedEdgeIsDown = isDown;
53
    }
54

    
55
///////////////////////////////////////////////////////////////////////////////////////////////////
56
// if upper==true, then the edge3 is the 'half-fixed' front edge. Remove it from the permutation.
57
// Otherwise edge1 is the one; remove it.
58

    
59
  public static int[] edgePermTo7(int[] perm, boolean upper)
60
    {
61
    int val;
62
    int[] ret = new int[7];
63

    
64
    if( upper )
65
      {
66
      ret[0] = perm[0];
67
      ret[1] = perm[1];
68
      ret[2] = perm[2];
69
      ret[3] = perm[4];
70
      ret[4] = perm[5];
71
      ret[5] = perm[6];
72
      ret[6] = perm[7];
73

    
74
      val = perm[3];
75
      }
76
    else
77
      {
78
      ret[0] = perm[0];
79
      ret[1] = perm[2];
80
      ret[2] = perm[3];
81
      ret[3] = perm[4];
82
      ret[4] = perm[5];
83
      ret[5] = perm[6];
84
      ret[6] = perm[7];
85

    
86
      val = perm[1];
87
      }
88

    
89
    for(int i=0; i<7; i++)
90
      if( ret[i]>val ) ret[i]--;
91

    
92
    return ret;
93
    }
94

    
95
///////////////////////////////////////////////////////////////////////////////////////////////////
96

    
97
  private static int[] edgePermTo8(int[] perm, boolean inPlace)
98
    {
99
    int[] ret = new int[8];
100

    
101
    if( mUpper )
102
      {
103
      int val = inPlace ? 3:1;
104
      ret[0] = perm[0]; if( ret[0]>=val ) ret[0]++;
105
      ret[1] = perm[1]; if( ret[1]>=val ) ret[1]++;
106
      ret[2] = perm[2]; if( ret[2]>=val ) ret[2]++;
107
      ret[3] = val;
108
      ret[4] = perm[3]; if( ret[4]>=val ) ret[4]++;
109
      ret[5] = perm[4]; if( ret[5]>=val ) ret[5]++;
110
      ret[6] = perm[5]; if( ret[6]>=val ) ret[6]++;
111
      ret[7] = perm[6]; if( ret[7]>=val ) ret[7]++;
112
      }
113
    else
114
      {
115
      int val = inPlace ? 1:3;
116
      ret[0] = perm[0]; if( ret[0]>=val ) ret[0]++;
117
      ret[1] = val;
118
      ret[2] = perm[1]; if( ret[2]>=val ) ret[2]++;
119
      ret[3] = perm[2]; if( ret[3]>=val ) ret[3]++;
120
      ret[4] = perm[3]; if( ret[4]>=val ) ret[4]++;
121
      ret[5] = perm[4]; if( ret[5]>=val ) ret[5]++;
122
      ret[6] = perm[5]; if( ret[6]>=val ) ret[6]++;
123
      ret[7] = perm[6]; if( ret[7]>=val ) ret[7]++;
124
      }
125

    
126
    return ret;
127
    }
128

    
129
///////////////////////////////////////////////////////////////////////////////////////////////////
130

    
131
  public TBCuboid323()
132
    {
133
    super();
134
    }
135

    
136
///////////////////////////////////////////////////////////////////////////////////////////////////
137

    
138
  public TBCuboid323(OperatingSystemInterface os)
139
    {
140
    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});
141
    }
142

    
143
///////////////////////////////////////////////////////////////////////////////////////////////////
144

    
145
  int[][] getBasicAngles()
146
    {
147
    if( mAngles==null )
148
      {
149
      int[] tmp2 = {2,2,2};
150
      int[] tmp4 = {4,4};
151
      mAngles = new int[][] { tmp2,tmp4,tmp2 };
152
      }
153

    
154
    return mAngles;
155
    }
156

    
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158

    
159
  Static3D[] getRotationAxis()
160
    {
161
    return new Static3D[]
162
         {
163
           new Static3D(1,0,0),
164
           new Static3D(0,1,0),
165
           new Static3D(0,0,1)
166
         };
167
    }
168

    
169
///////////////////////////////////////////////////////////////////////////////////////////////////
170

    
171
  float[][] getPosition()
172
    {
173
    return new float[][]
174
      {
175
        { -1.0f, -0.5f, -1.0f },
176
        { -1.0f, -0.5f,  1.0f },
177
        { -1.0f,  0.5f, -1.0f },
178
        { -1.0f,  0.5f,  1.0f },
179
        {  1.0f, -0.5f, -1.0f },
180
        {  1.0f, -0.5f,  1.0f },
181
        {  1.0f,  0.5f, -1.0f },
182
        {  1.0f,  0.5f,  1.0f },
183

    
184
        {  0.0f, -0.5f, -1.0f },
185
        {  0.0f, -0.5f,  1.0f },
186
        {  0.0f,  0.5f, -1.0f },
187
        {  0.0f,  0.5f,  1.0f },
188
        { -1.0f, -0.5f,  0.0f },
189
        { -1.0f,  0.5f,  0.0f },
190
        {  1.0f, -0.5f,  0.0f },
191
        {  1.0f,  0.5f,  0.0f },
192

    
193
        {  0.0f,  0.5f,  0.0f },
194
        {  0.0f, -0.5f,  0.0f },
195
      };
196
    }
197

    
198
///////////////////////////////////////////////////////////////////////////////////////////////////
199

    
200
  float[][] getCuts()
201
    {
202
    return new float[][] { {-0.5f,0.5f}, {0.0f}, {-0.5f,0.5f} };
203
    }
204

    
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206

    
207
  boolean[][] getRotatable()
208
    {
209
    return new boolean[][] { {true,false,true},{true,false},{true,false,true} };
210
    }
211

    
212
///////////////////////////////////////////////////////////////////////////////////////////////////
213
// specifically for the tablebase
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215
// we can never really move the fixed front edge, because if we do so, we would also rotate the
216
// rotation axis themselves! (see getIndex() where the cubit quats are normalized)
217
// Fixed front edge is always iin the front, up or down (depending on value of mFixedEdgeIsDown)
218
// If the edge is up and we are moving along Y axis, invert!
219

    
220
  @Override
221
  int[] newMove(int axis, int layer, int angle)
222
    {
223
    if( axis==2 && layer==2 ) mFixedEdgeIsDown = !mFixedEdgeIsDown;
224
    if( axis==1 && layer==1 && !mFixedEdgeIsDown ) return new int[] { axis, 1, -angle };
225

    
226
    int maxAngle = mAngles[axis][layer];
227
    angle = maxAngle-angle;
228
    if( angle> 0.5f*maxAngle ) angle -= maxAngle;
229
    return new int[] { axis, (1<<layer), angle };
230
    }
231

    
232
///////////////////////////////////////////////////////////////////////////////////////////////////
233
// 8!*8!/4 --> https://www.jaapsch.net/puzzles/domino.htm
234

    
235
  int getSize()
236
    {
237
    return 406425600;
238
    }
239

    
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241

    
242
  int getMinScramble()
243
    {
244
    return 13;
245
    }
246

    
247
///////////////////////////////////////////////////////////////////////////////////////////////////
248

    
249
  int[] getMidPruningLevels()
250
    {
251
    return new int[] {6,7};
252
    }
253

    
254
///////////////////////////////////////////////////////////////////////////////////////////////////
255

    
256
  int[] getHighPruningLevels()
257
    {
258
    return new int[] {17,18};
259
    }
260

    
261
///////////////////////////////////////////////////////////////////////////////////////////////////
262

    
263
  int getGodsNumber()
264
    {
265
    return 18;
266
    }
267

    
268
///////////////////////////////////////////////////////////////////////////////////////////////////
269

    
270
  boolean moveCanProceed(int lastA, int lastR, int currA, int currR)
271
    {
272
    return (lastA!=currA) || (lastR!=currR);
273
    }
274

    
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276

    
277
  private int findIndex(int[] table, int value)
278
    {
279
    for(int i=0; i<8; i++)
280
      if( table[i]==value ) return i;
281

    
282
    return -1;
283
    }
284

    
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286

    
287
  private boolean isFrontEdgeInItsPlace(int[] perm)
288
    {
289
    int index = mUpper?3:1;
290
    return perm[index]==index;
291
    }
292

    
293
///////////////////////////////////////////////////////////////////////////////////////////////////
294

    
295
  private void correctQuats(int[] quats)
296
    {
297
    int mult=0, index = mUpper? 11:9;
298

    
299
    switch(quats[index])
300
      {
301
      case 0: case 5: return;
302
      case 4: case 7: mult=2; break;
303
      case 1: case 3: mult=3; break;
304
      case 2: case 6: mult=4; break;
305
      }
306

    
307
    for(int i=0; i<16; i++) quats[i] = getMultQuat(mult,quats[i]);
308
    }
309

    
310
///////////////////////////////////////////////////////////////////////////////////////////////////
311

    
312
  public int[] getQuats(int index)
313
    {
314
    int cornerPermNum = index%40320;
315
    index /= 40320;
316
    boolean inPlace = ((index%2)==0);
317
    int edgePermNum = index/2;
318

    
319
    int[] corner_perm = new int[8];
320
    TablebaseHelpers.getPermutationFromNum(corner_perm,8,cornerPermNum);
321
    int[] edge_perm7 = new int[7];
322
    TablebaseHelpers.getPermutationFromNum(edge_perm7,7,edgePermNum);
323
    int[] edge_perm8 = edgePermTo8(edge_perm7,inPlace);
324

    
325
    int[] quats = new int[18];
326

    
327
    for(int i=0; i<8; i++)
328
      {
329
      int q = CORNER_MAP[i][corner_perm[i]];
330
      quats[i] = q;
331
      }
332
    for(int i=0; i<8; i++)
333
      {
334
      int q = EDGE_MAP[i][edge_perm8[i]];
335
      quats[i+8] = q;
336
      }
337

    
338
    return quats;
339
    }
340

    
341
///////////////////////////////////////////////////////////////////////////////////////////////////
342

    
343
  public int getIndex(int[] quats)
344
    {
345
    int[] corner_perm = new int[8];
346
    int[] edge_perm8  = new int[8];
347

    
348
    correctQuats(quats);
349

    
350
    for(int i=0; i<8; i++)
351
      {
352
      corner_perm[i] = findIndex( CORNER_MAP[i], quats[i  ]);
353
      edge_perm8[i]  = findIndex( EDGE_MAP[i]  , quats[i+8]);
354
      }
355

    
356
    int[] edge_perm7 = edgePermTo7(edge_perm8,mUpper);
357

    
358
    int corner_perm_num = TablebaseHelpers.computePermutationNum(corner_perm);
359
    int edge_perm_num = TablebaseHelpers.computePermutationNum(edge_perm7);
360
    boolean inPlace = isFrontEdgeInItsPlace(edge_perm8);
361

    
362
    return corner_perm_num + 40320*( (inPlace?0:1) + 2*edge_perm_num);
363
    }
364
}  
365

    
(5-5/19)