Project

General

Profile

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

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

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 static boolean mFixedEdgeIsDown;
44
  private int[][] mAngles;
45

    
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47

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

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

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

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

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

    
85
      val = perm[1];
86
      }
87

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

    
91
    return ret;
92
    }
93

    
94
///////////////////////////////////////////////////////////////////////////////////////////////////
95

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

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

    
125
    return ret;
126
    }
127

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

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

    
135
///////////////////////////////////////////////////////////////////////////////////////////////////
136

    
137
  public TBCuboid323(OperatingSystemInterface os)
138
    {
139
    super(os,null,null);
140
    }
141

    
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143

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

    
153
    return mAngles;
154
    }
155

    
156
///////////////////////////////////////////////////////////////////////////////////////////////////
157

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

    
168
///////////////////////////////////////////////////////////////////////////////////////////////////
169

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

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

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

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

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

    
204
///////////////////////////////////////////////////////////////////////////////////////////////////
205

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

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

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

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

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

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

    
239
///////////////////////////////////////////////////////////////////////////////////////////////////
240

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

    
246
///////////////////////////////////////////////////////////////////////////////////////////////////
247

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

    
253
///////////////////////////////////////////////////////////////////////////////////////////////////
254

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

    
260
///////////////////////////////////////////////////////////////////////////////////////////////////
261

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

    
267
///////////////////////////////////////////////////////////////////////////////////////////////////
268

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

    
274
///////////////////////////////////////////////////////////////////////////////////////////////////
275

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

    
281
    return -1;
282
    }
283

    
284
///////////////////////////////////////////////////////////////////////////////////////////////////
285

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

    
292
///////////////////////////////////////////////////////////////////////////////////////////////////
293

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

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

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

    
309
///////////////////////////////////////////////////////////////////////////////////////////////////
310

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

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

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

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

    
337
    return quats;
338
    }
339

    
340
///////////////////////////////////////////////////////////////////////////////////////////////////
341

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

    
347
    correctQuats(quats);
348

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

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

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

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

    
(5-5/19)