Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / tablebases / TBDino.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 static org.distorted.objectlib.main.TwistyObject.SQ3;
13

    
14
import org.distorted.library.type.Static3D;
15
import org.distorted.objectlib.helpers.OperatingSystemInterface;
16

    
17
///////////////////////////////////////////////////////////////////////////////////////////////////
18

    
19
public abstract class TBDino extends TablebasesPruning
20
{
21
  static final int[][] QUATS =
22
      {
23
          {0,2,10,8, 1,3,5,7,   11,6,9,4},
24
          {1,0,5,10, 2,6,8,4,   7,9,3,11},
25
          {10,6,0,4, 7,5,3,1,   9,2,11,8},
26
          {7,10,3,0, 6,2,4,8,   1,11,5,9},
27
          {2,1,8,5,  0,9,10,11, 4,3,6,7 },
28
          {4,5,6,1,  9,0,11,10, 2,7,8,3 },
29
          {6,7,4,3,  10,11,0,9, 8,5,2,1 },
30
          {8,3,2,7,  11,10,9,0, 6,1,4,5 },
31
          {11,8,9,2, 3,1,7,5,   0,4,10,6},
32
          {5,9,1,11, 4,8,6,2,   3,0,7,10},
33
          {9,4,11,6, 5,7,1,3,   10,8,0,2},
34
          {3,11,7,9, 8,4,2,6,   5,10,1,0}
35
      };
36

    
37
  private int[][] mAngles;
38

    
39
///////////////////////////////////////////////////////////////////////////////////////////////////
40

    
41
  public TBDino()
42
    {
43
    super();
44
    }
45

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

    
48
  public TBDino(OperatingSystemInterface os, int[] middle, int[] high)
49
    {
50
    super(os,middle,high);
51
    }
52

    
53
///////////////////////////////////////////////////////////////////////////////////////////////////
54

    
55
  int[][] getBasicAngles()
56
    {
57
    if( mAngles==null )
58
      {
59
      int[] tmp = {3,3,3};
60
      mAngles = new int[][] { tmp,tmp,tmp,tmp };
61
      }
62

    
63
    return mAngles;
64
    }
65

    
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67

    
68
  Static3D[] getRotationAxis()
69
    {
70
    return new Static3D[]
71
         {
72
           new Static3D( SQ3/3, SQ3/3, SQ3/3),
73
           new Static3D(-SQ3/3,-SQ3/3, SQ3/3),
74
           new Static3D(-SQ3/3, SQ3/3,-SQ3/3),
75
           new Static3D( SQ3/3,-SQ3/3,-SQ3/3),
76
         };
77
    }
78

    
79
///////////////////////////////////////////////////////////////////////////////////////////////////
80

    
81
  float[][] getPosition()
82
    {
83
    return new float[][]
84
         {
85
             { 0.0f, 1.5f, 1.5f },
86
             { 1.5f, 0.0f, 1.5f },
87
             { 0.0f,-1.5f, 1.5f },
88
             {-1.5f, 0.0f, 1.5f },
89
             { 1.5f, 1.5f, 0.0f },
90
             { 1.5f,-1.5f, 0.0f },
91
             {-1.5f,-1.5f, 0.0f },
92
             {-1.5f, 1.5f, 0.0f },
93
             { 0.0f, 1.5f,-1.5f },
94
             { 1.5f, 0.0f,-1.5f },
95
             { 0.0f,-1.5f,-1.5f },
96
             {-1.5f, 0.0f,-1.5f }
97
         };
98
    }
99

    
100
///////////////////////////////////////////////////////////////////////////////////////////////////
101

    
102
  float[][] getCuts()
103
    {
104
    float[] cut = new float[] { -SQ3/3, SQ3/3 };
105
    return new float[][] { cut,cut,cut,cut };
106
    }
107

    
108
///////////////////////////////////////////////////////////////////////////////////////////////////
109
// exclude the middle layer
110

    
111
  boolean[][] getRotatable()
112
    {
113
    boolean[] tmp = {true,false,true};
114
    return new boolean[][] { tmp,tmp,tmp,tmp };
115
    }
116

    
117
///////////////////////////////////////////////////////////////////////////////////////////////////
118
// specifically for the tablebase
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120
// we can never really move the top-front edge, because if we do so, we would also rotate the
121
// rotation axis themselves! (see getIndex() where the cubit quats are normalized so that quat[0]
122
// - i.e. the front-top edge - is always 0).
123
// That's why map the moves (0,2,X) to (0,0&1,-X) and (3,0,X) to (3,1&2,-X)
124

    
125
  @Override
126
  int[] newMove(int axis, int layer, int angle)
127
    {
128
    if( axis==0 && layer==2 ) return new int[] { axis, 3, angle==1 ? 1:-1};
129
    if( axis==3 && layer==0 ) return new int[] { axis, 6, angle==1 ? 1:-1};
130

    
131
    int maxAngle = mAngles[axis][layer];
132
    angle = maxAngle-angle;
133
    if( angle> 0.5f*maxAngle ) angle -= maxAngle;
134
    return new int[] { axis, (1<<layer), angle };
135
    }
136

    
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138
// here we change back the mapping introduced by 'newMove()'
139

    
140
  @Override
141
  void convertMoves(int[][] moves)
142
    {
143
    for(int[] move : moves )
144
      {
145
      int[] newMove = newMove(move[0],move[1],move[2]);
146

    
147
      move[0] = newMove[0];
148
      move[1] = newMove[1];
149
      move[2] = newMove[2];
150
      }
151

    
152
    int len = moves.length;
153

    
154
    for(int i=0; i<len; i++)
155
      {
156
      int[] move = moves[i];
157
      if( move[1]==3 || move[1]==6 ) unrollMoves(moves,i);
158
      }
159
    }
160

    
161
///////////////////////////////////////////////////////////////////////////////////////////////////
162

    
163
  private void unrollMoves(int[][] moves, int index)
164
    {
165
    int[] move = moves[index];
166
    int len = moves.length;
167

    
168
    if( move[1]==3 )
169
      {
170
      move[1] = 4;
171
      move[2] = -move[2];
172
      for(int i=index+1; i<len; i++) unrollMove(moves[i],move[0],move[2]<0);
173
      }
174
    else if( move[1]==6 )
175
      {
176
      move[1] = 1;
177
      move[2] = -move[2];
178
      for(int i=index+1; i<len; i++) unrollMove(moves[i],move[0],move[2]<0);
179
      }
180
    }
181

    
182
///////////////////////////////////////////////////////////////////////////////////////////////////
183

    
184
  private void unrollMove(int[] move, int axis, boolean clockwise)
185
    {
186
    switch(axis)
187
      {
188
      case 0: switch(move[0])
189
                {
190
                case 0: break;
191
                case 1: move[0]= (clockwise? 2 : 3); break;
192
                case 2: move[0]= (clockwise? 3 : 1); break;
193
                case 3: move[0]= (clockwise? 1 : 2); break;
194
                }
195
              break;
196
      case 1: switch(move[0])
197
                {
198
                case 0: move[0]= (clockwise? 3 : 2); break;
199
                case 1: break;
200
                case 2: move[0]= (clockwise? 0 : 3); break;
201
                case 3: move[0]= (clockwise? 2 : 0); break;
202
                }
203
              break;
204
      case 2: switch(move[0])
205
                {
206
                case 0: move[0]= (clockwise? 1 : 3); break;
207
                case 1: move[0]= (clockwise? 3 : 0); break;
208
                case 2: break;
209
                case 3: move[0]= (clockwise? 0 : 1); break;
210
                }
211
              break;
212
      case 3: switch(move[0])
213
                {
214
                case 0: move[0]= (clockwise? 2 : 1); break;
215
                case 1: move[0]= (clockwise? 0 : 2); break;
216
                case 2: move[0]= (clockwise? 1 : 0); break;
217
                case 3: break;
218
                }
219
              break;
220
      }
221
    }
222

    
223
///////////////////////////////////////////////////////////////////////////////////////////////////
224

    
225
  boolean moveCanProceed(int lastA, int lastR, int currA, int currR)
226
    {
227
    return (lastA!=currA) || (lastR!=currR);
228
    }
229

    
230
///////////////////////////////////////////////////////////////////////////////////////////////////
231
// we rotate the whole thing so that quat[0] is always 0.
232

    
233
  void normalizeQuats(int[] quats)
234
    {
235
    if( quats[0]!=0 )
236
      {
237
      int inverted = getInvertedQuat(quats[0]);
238
      quats[0] = 0;
239

    
240
      for(int i=1; i<12; i++)
241
        {
242
        int index = quats[i];
243
        quats[i] = getMultQuat(inverted,index);
244
        }
245
      }
246
    }
247

    
248
///////////////////////////////////////////////////////////////////////////////////////////////////
249
// in-place!
250

    
251
  public static int[] getPermFromQuats(int[] quats)
252
    {
253
    for(int i=0; i<12; i++)
254
      {
255
      int[] Q = QUATS[i];
256
      int quat = quats[i];
257

    
258
      for(int j=0; j<12; j++)
259
        if( Q[j]==quat )
260
          {
261
          quats[i] = j;
262
          break;
263
          }
264
      }
265

    
266
    return quats;
267
    }
268

    
269
///////////////////////////////////////////////////////////////////////////////////////////////////
270
// in-place!
271

    
272
  public static int[] getQuatsFromPerm(int[] perm)
273
    {
274
    for(int i=0; i<12; i++)
275
      {
276
      int p = perm[i];
277
      perm[i] = QUATS[i][p];
278
      }
279

    
280
    return perm;
281
    }
282
}  
283

    
(6-6/19)