Project

General

Profile

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

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

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

    
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47
// remove perm[1] which is always equal to 1.
48

    
49
  public static int[] edgePermTo7(int[] perm)
50
    {
51
    int[] ret = new int[7];
52

    
53
    ret[0] = perm[0]; if( ret[0]>1 ) ret[0]--;
54
    ret[1] = perm[2]; if( ret[1]>1 ) ret[1]--;
55
    ret[2] = perm[3]; if( ret[2]>1 ) ret[2]--;
56
    ret[3] = perm[4]; if( ret[3]>1 ) ret[3]--;
57
    ret[4] = perm[5]; if( ret[4]>1 ) ret[4]--;
58
    ret[5] = perm[6]; if( ret[5]>1 ) ret[5]--;
59
    ret[6] = perm[7]; if( ret[6]>1 ) ret[6]--;
60

    
61
    return ret;
62
    }
63

    
64
///////////////////////////////////////////////////////////////////////////////////////////////////
65
// reverse the above
66

    
67
  private static int[] edgePermTo8(int[] perm)
68
    {
69
    int[] ret = new int[8];
70

    
71
    ret[0] = perm[0]; if( ret[0]>=1 ) ret[0]++;
72
    ret[1] = 1;
73
    ret[2] = perm[1]; if( ret[2]>=1 ) ret[2]++;
74
    ret[3] = perm[2]; if( ret[3]>=1 ) ret[3]++;
75
    ret[4] = perm[3]; if( ret[4]>=1 ) ret[4]++;
76
    ret[5] = perm[4]; if( ret[5]>=1 ) ret[5]++;
77
    ret[6] = perm[5]; if( ret[6]>=1 ) ret[6]++;
78
    ret[7] = perm[6]; if( ret[7]>=1 ) ret[7]++;
79

    
80
    return ret;
81
    }
82

    
83
///////////////////////////////////////////////////////////////////////////////////////////////////
84

    
85
  public TBCuboid323()
86
    {
87
    super();
88
    }
89

    
90
///////////////////////////////////////////////////////////////////////////////////////////////////
91

    
92
  public TBCuboid323(OperatingSystemInterface os)
93
    {
94
    super(os,new int[] {R.raw.cu_323_pruning7 ,R.raw.cu_323_pruning8 },
95
             new int[] {R.raw.cu_323_pruning17,R.raw.cu_323_pruning18} );
96
    }
97

    
98
///////////////////////////////////////////////////////////////////////////////////////////////////
99

    
100
  public void initialize()
101
    {
102
    mUpsideDown = false;
103
    }
104

    
105
///////////////////////////////////////////////////////////////////////////////////////////////////
106

    
107
  int[][] getBasicAngles()
108
    {
109
    if( mAngles==null )
110
      {
111
      int[] tmp2 = {2,2,2};
112
      int[] tmp4 = {4,4};
113
      mAngles = new int[][] { tmp2,tmp4,tmp2 };
114
      }
115

    
116
    return mAngles;
117
    }
118

    
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120

    
121
  Static3D[] getRotationAxis()
122
    {
123
    return new Static3D[]
124
         {
125
           new Static3D(1,0,0),
126
           new Static3D(0,1,0),
127
           new Static3D(0,0,1)
128
         };
129
    }
130

    
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132

    
133
  float[][] getPosition()
134
    {
135
    return new float[][]
136
      {
137
        { -1.0f, -0.5f, -1.0f },
138
        { -1.0f, -0.5f,  1.0f },
139
        { -1.0f,  0.5f, -1.0f },
140
        { -1.0f,  0.5f,  1.0f },
141
        {  1.0f, -0.5f, -1.0f },
142
        {  1.0f, -0.5f,  1.0f },
143
        {  1.0f,  0.5f, -1.0f },
144
        {  1.0f,  0.5f,  1.0f },
145

    
146
        {  0.0f, -0.5f, -1.0f },
147
        {  0.0f, -0.5f,  1.0f },
148
        {  0.0f,  0.5f, -1.0f },
149
        {  0.0f,  0.5f,  1.0f },
150
        { -1.0f, -0.5f,  0.0f },
151
        { -1.0f,  0.5f,  0.0f },
152
        {  1.0f, -0.5f,  0.0f },
153
        {  1.0f,  0.5f,  0.0f },
154

    
155
        {  0.0f,  0.5f,  0.0f },
156
        {  0.0f, -0.5f,  0.0f },
157
      };
158
    }
159

    
160
///////////////////////////////////////////////////////////////////////////////////////////////////
161

    
162
  float[][] getCuts()
163
    {
164
    return new float[][] { {-0.5f,0.5f}, {0.0f}, {-0.5f,0.5f} };
165
    }
166

    
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168

    
169
  boolean[][] getRotatable()
170
    {
171
    return new boolean[][] { {true,false,true},{false,true},{true,true,false} };
172
    }
173

    
174
///////////////////////////////////////////////////////////////////////////////////////////////////
175
// we map the move (axis=2, middle layer) to move (axis=2,both middle and back layers).
176
// this way we can imitate move of the front layer (which we do not want to move because
177
// the edge1 piece has to always stay in its place)
178

    
179
  @Override
180
  int computeBitLayer(int ax, int layer)
181
    {
182
    if( ax!=2 ) return (1<<layer);
183

    
184
    switch(layer)
185
      {
186
      case 0 : return 1;
187
      case 1 : return 3;
188
      default: return 4;
189
      }
190
    }
191

    
192
///////////////////////////////////////////////////////////////////////////////////////////////////
193
// this is too slow to be used for scrambling - scramble the 3x3x2 the old way.
194

    
195
  @Override
196
  public boolean useForScrambling()
197
    {
198
    return false;
199
    }
200

    
201
///////////////////////////////////////////////////////////////////////////////////////////////////
202
// specifically for the tablebase
203
///////////////////////////////////////////////////////////////////////////////////////////////////
204
// now turn the (ax=2, middle and back layer) artificial moves [ introduced by computeBitLayer)
205
// back to the natural (ax=2, front layer). Turn the whole thing upside down each time we do it.
206

    
207
  @Override
208
  int[] newMove(int axis, int layer, int angle)
209
    {
210
    if( axis==2 )
211
      {
212
      if( layer==1 )
213
        {
214
        mUpsideDown = !mUpsideDown;
215
        return new int[] { axis, 4, angle };
216
        }
217
      }
218
    else if( mUpsideDown )
219
      {
220
      if( axis==0 ) layer=2-layer;
221
      if( axis==1 ) { layer=1-layer; angle = 4-angle; }
222
      }
223

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

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

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

    
238
///////////////////////////////////////////////////////////////////////////////////////////////////
239

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

    
245
///////////////////////////////////////////////////////////////////////////////////////////////////
246

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

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

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

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

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

    
266
///////////////////////////////////////////////////////////////////////////////////////////////////
267

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

    
273
///////////////////////////////////////////////////////////////////////////////////////////////////
274

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

    
280
    return -1;
281
    }
282

    
283
///////////////////////////////////////////////////////////////////////////////////////////////////
284

    
285
  private int centersInverted(int[] quats)
286
    {
287
    int q = quats[16];
288
    return (q==0 || q==2 || q==3 || q==4) ? 0 : 1;
289
    }
290

    
291
///////////////////////////////////////////////////////////////////////////////////////////////////
292

    
293
  public static int[] quatsFromPermutations(int[] corner, int[] edge8, int centers)
294
    {
295
    int[] quats = new int[18];
296

    
297
    for(int i=0; i<8; i++)
298
      {
299
      int q = CORNER_MAP[i][corner[i]];
300
      quats[i] = q;
301
      }
302
    for(int i=0; i<8; i++)
303
      {
304
      int q = EDGE_MAP[i][edge8[i]];
305
      quats[i+8] = q;
306
      }
307

    
308
    if( centers==0 )
309
      {
310
      quats[16]=0;
311
      quats[17]=0;
312
      }
313
    else
314
      {
315
      quats[16]=5;
316
      quats[17]=5;
317
      }
318

    
319
    return quats;
320
    }
321

    
322
///////////////////////////////////////////////////////////////////////////////////////////////////
323

    
324
  public static void cornerFromQuats(int[] corner_perm, int[] quats)
325
    {
326
    for(int i=0; i<8; i++) corner_perm[i] = findIndex( CORNER_MAP[i], quats[i]);
327
    }
328

    
329
///////////////////////////////////////////////////////////////////////////////////////////////////
330

    
331
  public static void edgeFromQuats(int[] edge_perm, int[] quats)
332
    {
333
    for(int i=0; i<8; i++) edge_perm[i] = findIndex( EDGE_MAP[i], quats[i+8]);
334
    }
335

    
336
///////////////////////////////////////////////////////////////////////////////////////////////////
337

    
338
  public int[] getQuats(int index)
339
    {
340
    int cornerPermNum = (index%40320);
341
    index /= 40320;
342
    int centers = (index%2);
343
    int edgePermNum = index/2;
344

    
345
    int[] corner_perm = new int[8];
346
    TablebaseHelpers.getPermutationFromNum(corner_perm,8,cornerPermNum);
347
    int[] edge_perm7 = new int[7];
348
    TablebaseHelpers.getPermutationFromNum(edge_perm7,7,edgePermNum);
349
    int[] edge_perm8 = edgePermTo8(edge_perm7);
350
/*
351
TablebaseHelpers.displayTable(corner_perm, "CORNER");
352
TablebaseHelpers.displayTable(edge_perm8, "EDGE8");
353
TablebaseHelpers.displayTable(edge_perm7, "EDGE7");
354
android.util.Log.e("D", "inPlace="+inPlace);
355
*/
356

    
357
    return quatsFromPermutations(corner_perm,edge_perm8,centers);
358
    }
359

    
360
///////////////////////////////////////////////////////////////////////////////////////////////////
361

    
362
  public int getIndex(int[] quats)
363
    {
364
    int[] corner_perm = new int[8];
365
    cornerFromQuats(corner_perm,quats);
366
    int[] edge_perm8  = new int[8];
367
    edgeFromQuats(edge_perm8,quats);
368
    int[] edge_perm7  = edgePermTo7(edge_perm8);
369

    
370
    int corner_perm_num = TablebaseHelpers.computePermutationNum(corner_perm);
371
    int edge_perm_num = TablebaseHelpers.computePermutationNum(edge_perm7);
372
    int centers = centersInverted(quats);
373

    
374
    return corner_perm_num + 40320*( centers + 2*edge_perm_num);
375
    }
376
}  
377

    
(5-5/19)