Project

General

Profile

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

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

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

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

    
48
  public static void setDown(boolean isDown )
49
    {
50
    mFixedEdgeIsDown = isDown;
51
    }
52

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

    
57
  public static int[] edgePermTo7(int[] perm)
58
    {
59
    int[] ret = new int[7];
60

    
61
    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

    
71
    for(int i=0; i<7; i++)
72
      if( ret[i]>val ) ret[i]--;
73

    
74
    return ret;
75
    }
76

    
77
///////////////////////////////////////////////////////////////////////////////////////////////////
78

    
79
  private static int[] edgePermTo8(int[] perm, boolean inPlace)
80
    {
81
    int[] ret = new int[8];
82
    int val = inPlace ? 1:3;
83

    
84
    ret[0] = perm[0]; if( ret[0]>=val ) ret[0]++;
85
    ret[1] = val;
86
    ret[2] = perm[1]; if( ret[2]>=val ) ret[2]++;
87
    ret[3] = perm[2]; if( ret[3]>=val ) ret[3]++;
88
    ret[4] = perm[3]; if( ret[4]>=val ) ret[4]++;
89
    ret[5] = perm[4]; if( ret[5]>=val ) ret[5]++;
90
    ret[6] = perm[5]; if( ret[6]>=val ) ret[6]++;
91
    ret[7] = perm[6]; if( ret[7]>=val ) ret[7]++;
92

    
93
    return ret;
94
    }
95

    
96
///////////////////////////////////////////////////////////////////////////////////////////////////
97

    
98
  public TBCuboid323()
99
    {
100
    super();
101
    }
102

    
103
///////////////////////////////////////////////////////////////////////////////////////////////////
104

    
105
  public TBCuboid323(OperatingSystemInterface os)
106
    {
107
    super(os,new int[] {R.raw.cu_323_pruning6,R.raw.cu_323_pruning7}, null);//new int[] {R.raw.cu_323_pruning17,R.raw.cu_323_pruning18});
108
    }
109

    
110
///////////////////////////////////////////////////////////////////////////////////////////////////
111

    
112
  int[][] getBasicAngles()
113
    {
114
    if( mAngles==null )
115
      {
116
      int[] tmp2 = {2,2,2};
117
      int[] tmp4 = {4,4};
118
      mAngles = new int[][] { tmp2,tmp4,tmp2 };
119
      }
120

    
121
    return mAngles;
122
    }
123

    
124
///////////////////////////////////////////////////////////////////////////////////////////////////
125

    
126
  Static3D[] getRotationAxis()
127
    {
128
    return new Static3D[]
129
         {
130
           new Static3D(1,0,0),
131
           new Static3D(0,1,0),
132
           new Static3D(0,0,1)
133
         };
134
    }
135

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

    
138
  float[][] getPosition()
139
    {
140
    return new float[][]
141
      {
142
        { -1.0f, -0.5f, -1.0f },
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

    
151
        {  0.0f, -0.5f, -1.0f },
152
        {  0.0f, -0.5f,  1.0f },
153
        {  0.0f,  0.5f, -1.0f },
154
        {  0.0f,  0.5f,  1.0f },
155
        { -1.0f, -0.5f,  0.0f },
156
        { -1.0f,  0.5f,  0.0f },
157
        {  1.0f, -0.5f,  0.0f },
158
        {  1.0f,  0.5f,  0.0f },
159

    
160
        {  0.0f,  0.5f,  0.0f },
161
        {  0.0f, -0.5f,  0.0f },
162
      };
163
    }
164

    
165
///////////////////////////////////////////////////////////////////////////////////////////////////
166

    
167
  float[][] getCuts()
168
    {
169
    return new float[][] { {-0.5f,0.5f}, {0.0f}, {-0.5f,0.5f} };
170
    }
171

    
172
///////////////////////////////////////////////////////////////////////////////////////////////////
173

    
174
  boolean[][] getRotatable()
175
    {
176
    return new boolean[][] { {true,false,true},{true,false},{true,false,true} };
177
    }
178

    
179
///////////////////////////////////////////////////////////////////////////////////////////////////
180
// specifically for the tablebase
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182
// we can never really move the fixed front edge, because if we do so, we would also rotate the
183
// rotation axis themselves! (see getIndex() where the cubit quats are normalized)
184
// Fixed front edge is always in the front, up or down (depending on value of mFixedEdgeIsDown)
185
// If the edge is up and we are moving along Y axis, invert!
186

    
187
  @Override
188
  int[] newMove(int axis, int layer, int angle)
189
    {
190
    if( axis==2 && layer==2 ) mFixedEdgeIsDown = !mFixedEdgeIsDown;
191
    if( axis==1 && layer==1 && !mFixedEdgeIsDown ) return new int[] { axis, 1, -angle };
192

    
193
    int maxAngle = mAngles[axis][layer];
194
    angle = maxAngle-angle;
195
    if( angle> 0.5f*maxAngle ) angle -= maxAngle;
196
    return new int[] { axis, (1<<layer), angle };
197
    }
198

    
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200
// 8!*8!/4 --> https://www.jaapsch.net/puzzles/domino.htm
201

    
202
  int getSize()
203
    {
204
    return 406425600;
205
    }
206

    
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208

    
209
  int getMinScramble()
210
    {
211
    return 13;
212
    }
213

    
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215

    
216
  int[] getMidPruningLevels()
217
    {
218
    return new int[] {6,7};
219
    }
220

    
221
///////////////////////////////////////////////////////////////////////////////////////////////////
222

    
223
  int[] getHighPruningLevels()
224
    {
225
    return null;//new int[] {17,18};
226
    }
227

    
228
///////////////////////////////////////////////////////////////////////////////////////////////////
229

    
230
  int getGodsNumber()
231
    {
232
    return 18;
233
    }
234

    
235
///////////////////////////////////////////////////////////////////////////////////////////////////
236

    
237
  boolean moveCanProceed(int lastA, int lastR, int currA, int currR)
238
    {
239
    return (lastA!=currA) || (lastR!=currR);
240
    }
241

    
242
///////////////////////////////////////////////////////////////////////////////////////////////////
243

    
244
  private int findIndex(int[] table, int value)
245
    {
246
    for(int i=0; i<8; i++)
247
      if( table[i]==value ) return i;
248

    
249
    return -1;
250
    }
251

    
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253

    
254
  private boolean isFrontEdgeInItsPlace(int[] perm)
255
    {
256
    return perm[1]==1;
257
    }
258

    
259
///////////////////////////////////////////////////////////////////////////////////////////////////
260

    
261
  private void correctQuats(int[] quats)
262
    {
263
    int mult=0;
264

    
265
    switch(quats[9])
266
      {
267
      case 0: case 5: return;
268
      case 4: case 7: mult=2; break;
269
      case 1: case 3: mult=3; break;
270
      case 2: case 6: mult=4; break;
271
      }
272

    
273
    for(int i=0; i<16; i++) quats[i] = getMultQuat(mult,quats[i]);
274
    }
275

    
276
///////////////////////////////////////////////////////////////////////////////////////////////////
277

    
278
  public int[] getQuats(int index)
279
    {
280
    int cornerPermNum = index%40320;
281
    index /= 40320;
282
    boolean inPlace = ((index%2)==0);
283
    int edgePermNum = index/2;
284

    
285
    int[] corner_perm = new int[8];
286
    TablebaseHelpers.getPermutationFromNum(corner_perm,8,cornerPermNum);
287
    int[] edge_perm7 = new int[7];
288
    TablebaseHelpers.getPermutationFromNum(edge_perm7,7,edgePermNum);
289
    int[] edge_perm8 = edgePermTo8(edge_perm7,inPlace);
290

    
291
    int[] quats = new int[18];
292

    
293
    for(int i=0; i<8; i++)
294
      {
295
      int q = CORNER_MAP[i][corner_perm[i]];
296
      quats[i] = q;
297
      }
298
    for(int i=0; i<8; i++)
299
      {
300
      int q = EDGE_MAP[i][edge_perm8[i]];
301
      quats[i+8] = q;
302
      }
303

    
304
    return quats;
305
    }
306

    
307
///////////////////////////////////////////////////////////////////////////////////////////////////
308

    
309
  public int getIndex(int[] quats)
310
    {
311
    int[] corner_perm = new int[8];
312
    int[] edge_perm8  = new int[8];
313

    
314
    correctQuats(quats);
315

    
316
    for(int i=0; i<8; i++)
317
      {
318
      corner_perm[i] = findIndex( CORNER_MAP[i], quats[i  ]);
319
      edge_perm8[i]  = findIndex( EDGE_MAP[i]  , quats[i+8]);
320
      }
321

    
322
    int[] edge_perm7 = edgePermTo7(edge_perm8);
323

    
324
    int corner_perm_num = TablebaseHelpers.computePermutationNum(corner_perm);
325
    int edge_perm_num = TablebaseHelpers.computePermutationNum(edge_perm7);
326
    boolean inPlace = isFrontEdgeInItsPlace(edge_perm8);
327

    
328
    return corner_perm_num + 40320*( (inPlace?0:1) + 2*edge_perm_num);
329
    }
330
}  
331

    
(5-5/19)