Project

General

Profile

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

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

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.helpers.OperatingSystemInterface;
14

    
15
///////////////////////////////////////////////////////////////////////////////////////////////////
16

    
17
public class TBCuboid323 extends TablebasesPruning
18
{
19
  private static final int[][] CORNER_MAP = new int[][]
20
      {
21
          {0,4,7,1,2,3,5,6},
22
          {2,0,1,6,3,4,7,5},
23
          {7,1,0,4,5,6,2,3},
24
          {1,6,2,0,7,5,3,4},
25
          {4,3,5,7,0,2,6,1},
26
          {3,2,6,5,4,0,1,7},
27
          {5,7,4,3,6,1,0,2},
28
          {6,5,3,2,1,7,4,0}
29
      };
30
  private static final int[][] EDGE_MAP = new int[][]
31
      {
32
          {0,3,5,1,4,7,2,6},
33
          {3,0,1,5,2,6,4,7},
34
          {5,1,0,3,7,4,6,2},
35
          {1,5,3,0,6,2,7,4},
36
          {2,4,7,6,0,1,3,5},
37
          {7,6,2,4,1,0,5,3},
38
          {4,2,6,7,3,5,0,1},
39
          {6,7,4,2,5,3,1,0}
40
      };
41

    
42
  private static boolean mUpper;
43
  private int[][] mAngles;
44

    
45
///////////////////////////////////////////////////////////////////////////////////////////////////
46

    
47
  public static void setUpper(boolean upper)
48
    {
49
    mUpper = upper;
50
    }
51

    
52
///////////////////////////////////////////////////////////////////////////////////////////////////
53
// if mUpper==true, then the edge3 is the 'half-fixed' front edge. Remove it from the permutation.
54
// Otherwise edge1 is the one; remove it.
55

    
56
  public static int[] edgePermTo7(int[] perm, boolean upper)
57
    {
58
    int val;
59
    int[] ret = new int[7];
60

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

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

    
83
      val = perm[1];
84
      }
85

    
86
    for(int i=0; i<7; i++)
87
      if( ret[i]>val ) ret[i]--;
88

    
89
    return ret;
90
    }
91

    
92
///////////////////////////////////////////////////////////////////////////////////////////////////
93

    
94
  private static int[] edgePermTo8(int[] perm, boolean inPlace)
95
    {
96
    int[] ret = new int[8];
97

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

    
123
    return ret;
124
    }
125

    
126
///////////////////////////////////////////////////////////////////////////////////////////////////
127

    
128
  public TBCuboid323()
129
    {
130
    super();
131
    }
132

    
133
///////////////////////////////////////////////////////////////////////////////////////////////////
134

    
135
  public TBCuboid323(OperatingSystemInterface os)
136
    {
137
    super(os,null,null);
138
    }
139

    
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141

    
142
  int[][] getBasicAngles()
143
    {
144
    if( mAngles==null )
145
      {
146
      int[] tmp2 = {2,2,2};
147
      int[] tmp4 = {4,4};
148
      return new int[][] { tmp2,tmp4,tmp2 };
149
      }
150

    
151
    return mAngles;
152
    }
153

    
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155

    
156
  Static3D[] getRotationAxis()
157
    {
158
    return new Static3D[]
159
         {
160
           new Static3D(1,0,0),
161
           new Static3D(0,1,0),
162
           new Static3D(0,0,1)
163
         };
164
    }
165

    
166
///////////////////////////////////////////////////////////////////////////////////////////////////
167

    
168
  float[][] getPosition()
169
    {
170
    return new float[][]
171
      {
172
        { -1.0f, -0.5f, -1.0f },
173
        { -1.0f, -0.5f,  1.0f },
174
        { -1.0f,  0.5f, -1.0f },
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

    
181
        {  0.0f, -0.5f, -1.0f },
182
        {  0.0f, -0.5f,  1.0f },
183
        {  0.0f,  0.5f, -1.0f },
184
        {  0.0f,  0.5f,  1.0f },
185
        { -1.0f, -0.5f,  0.0f },
186
        { -1.0f,  0.5f,  0.0f },
187
        {  1.0f, -0.5f,  0.0f },
188
        {  1.0f,  0.5f,  0.0f },
189

    
190
        {  0.0f,  0.5f,  0.0f },
191
        {  0.0f, -0.5f,  0.0f },
192
      };
193
    }
194

    
195
///////////////////////////////////////////////////////////////////////////////////////////////////
196

    
197
  float[][] getCuts()
198
    {
199
    return new float[][] { {-0.5f,0.5f}, {0.0f}, {-0.5f,0.5f} };
200
    }
201

    
202
///////////////////////////////////////////////////////////////////////////////////////////////////
203

    
204
  boolean[][] getRotatable()
205
    {
206
    return new boolean[][] { {true,false,true},{true,false},{true,false,true} };
207
    }
208

    
209
///////////////////////////////////////////////////////////////////////////////////////////////////
210
// specifically for the tablebase
211
///////////////////////////////////////////////////////////////////////////////////////////////////
212
// we can never really move the fixed front edge, because if we do so, we would also rotate the
213
// rotation axis themselves! (see getIndex() where the cubit quats are normalized)
214
// Fixed front edge is either edge1 or edge3, depending on value of mUpper
215
// (mUpper==true --> fixed==3, else fixed==1)
216
//
217

    
218
  @Override
219
  int[] newMove(int axis, int layer, int angle)
220
    {
221
    //if( axis==0 && layer==2 ) return new int[] { axis, 3, angle==1 ? 1:-1};
222
    //if( axis==3 && layer==0 ) return new int[] { axis, 6, angle==1 ? 1:-1};
223

    
224
    if( axis==1 )
225
      {
226

    
227
      }
228

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

    
235
///////////////////////////////////////////////////////////////////////////////////////////////////
236
// 8!*8!/4 --> https://www.jaapsch.net/puzzles/domino.htm
237

    
238
  int getSize()
239
    {
240
    return 406425600;
241
    }
242

    
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244

    
245
  int getMinScramble()
246
    {
247
    return 13;
248
    }
249

    
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251

    
252
  int[] getMidPruningLevels()
253
    {
254
    return new int[] {6,7};
255
    }
256

    
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258

    
259
  int[] getHighPruningLevels()
260
    {
261
    return new int[] {17,18};
262
    }
263

    
264
///////////////////////////////////////////////////////////////////////////////////////////////////
265

    
266
  int getGodsNumber()
267
    {
268
    return 18;
269
    }
270

    
271
///////////////////////////////////////////////////////////////////////////////////////////////////
272

    
273
  boolean moveCanProceed(int lastA, int lastR, int currA, int currR)
274
    {
275
    return (lastA!=currA) || (lastR!=currR);
276
    }
277

    
278
///////////////////////////////////////////////////////////////////////////////////////////////////
279

    
280
  private int findIndex(int[] table, int value)
281
    {
282
    for(int i=0; i<8; i++)
283
      if( table[i]==value ) return i;
284

    
285
    return -1;
286
    }
287

    
288
///////////////////////////////////////////////////////////////////////////////////////////////////
289

    
290
  private boolean isFrontEdgeInItsPlace(int[] perm)
291
    {
292
    int index = mUpper?3:1;
293
    return perm[index]==index;
294
    }
295

    
296
///////////////////////////////////////////////////////////////////////////////////////////////////
297

    
298
  private void correctQuats(int[] quats)
299
    {
300
    int mult=0, index = mUpper? 11:9;
301

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

    
310
    for(int i=0; i<16; i++) quats[i] = getMultQuat(mult,quats[i]);
311
    }
312

    
313
///////////////////////////////////////////////////////////////////////////////////////////////////
314

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

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

    
328
    int[] quats = new int[18];
329

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

    
341
    return quats;
342
    }
343

    
344
///////////////////////////////////////////////////////////////////////////////////////////////////
345

    
346
  public int getIndex(int[] quats)
347
    {
348
    int[] corner_perm = new int[8];
349
    int[] edge_perm8  = new int[8];
350

    
351
    correctQuats(quats);
352

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

    
359
    int[] edge_perm7 = edgePermTo7(edge_perm8,mUpper);
360

    
361
    int corner_perm_num = TablebaseHelpers.computePermutationNum(corner_perm);
362
    int edge_perm_num = TablebaseHelpers.computePermutationNum(edge_perm7);
363
    boolean inPlace = isFrontEdgeInItsPlace(edge_perm8);
364

    
365
    return corner_perm_num + 40320*( (inPlace?0:1) + 2*edge_perm_num);
366
    }
367
}  
368

    
(5-5/19)