Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / tablebases / TBDino.java @ 6777e712

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
import org.distorted.objectlib.objects.TwistyDino6;
17

    
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

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

    
38
  private int[][] mAngles;
39

    
40
///////////////////////////////////////////////////////////////////////////////////////////////////
41

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

    
47
///////////////////////////////////////////////////////////////////////////////////////////////////
48

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

    
54
///////////////////////////////////////////////////////////////////////////////////////////////////
55

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

    
64
    return mAngles;
65
    }
66

    
67
///////////////////////////////////////////////////////////////////////////////////////////////////
68

    
69
  Static3D[] getRotationAxis()
70
    {
71
    return TwistyDino6.ROT_AXIS;
72
    }
73

    
74
///////////////////////////////////////////////////////////////////////////////////////////////////
75

    
76
  float[][] getPosition()
77
    {
78
    return new float[][]
79
         {
80
             { 0.0f, 1.5f, 1.5f },
81
             { 1.5f, 0.0f, 1.5f },
82
             { 0.0f,-1.5f, 1.5f },
83
             {-1.5f, 0.0f, 1.5f },
84
             { 1.5f, 1.5f, 0.0f },
85
             { 1.5f,-1.5f, 0.0f },
86
             {-1.5f,-1.5f, 0.0f },
87
             {-1.5f, 1.5f, 0.0f },
88
             { 0.0f, 1.5f,-1.5f },
89
             { 1.5f, 0.0f,-1.5f },
90
             { 0.0f,-1.5f,-1.5f },
91
             {-1.5f, 0.0f,-1.5f }
92
         };
93
    }
94

    
95
///////////////////////////////////////////////////////////////////////////////////////////////////
96

    
97
  float[][] getCuts()
98
    {
99
    float[] cut = new float[] { -SQ3/3, SQ3/3 };
100
    return new float[][] { cut,cut,cut,cut };
101
    }
102

    
103
///////////////////////////////////////////////////////////////////////////////////////////////////
104
// exclude the middle layer
105

    
106
  boolean[][] getRotatable()
107
    {
108
    boolean[] tmp = {true,false,true};
109
    return new boolean[][] { tmp,tmp,tmp,tmp };
110
    }
111

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

    
120
  @Override
121
  int[] newMove(int axis, int layer, int angle)
122
    {
123
    if( axis==0 && layer==2 ) return new int[] { axis, 3, angle==1 ? 1:-1};
124
    if( axis==3 && layer==0 ) return new int[] { axis, 6, angle==1 ? 1:-1};
125

    
126
    int maxAngle = mAngles[axis][layer];
127
    angle = maxAngle-angle;
128
    if( angle> 0.5f*maxAngle ) angle -= maxAngle;
129
    return new int[] { axis, (1<<layer), angle };
130
    }
131

    
132
///////////////////////////////////////////////////////////////////////////////////////////////////
133
// here we change back the mapping introduced by 'newMove()'
134

    
135
  @Override
136
  void convertMoves(int[][] moves)
137
    {
138
    for(int[] move : moves )
139
      {
140
      int[] newMove = newMove(move[0],move[1],move[2]);
141

    
142
      move[0] = newMove[0];
143
      move[1] = newMove[1];
144
      move[2] = newMove[2];
145
      }
146

    
147
    int len = moves.length;
148

    
149
    for(int i=0; i<len; i++)
150
      {
151
      int[] move = moves[i];
152
      if( move[1]==3 || move[1]==6 ) unrollMoves(moves,i);
153
      }
154
    }
155

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

    
158
  private void unrollMoves(int[][] moves, int index)
159
    {
160
    int[] move = moves[index];
161
    int len = moves.length;
162

    
163
    if( move[1]==3 )
164
      {
165
      move[1] = 4;
166
      move[2] = -move[2];
167
      for(int i=index+1; i<len; i++) unrollMove(moves[i],move[0],move[2]<0);
168
      }
169
    else if( move[1]==6 )
170
      {
171
      move[1] = 1;
172
      move[2] = -move[2];
173
      for(int i=index+1; i<len; i++) unrollMove(moves[i],move[0],move[2]<0);
174
      }
175
    }
176

    
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178

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

    
218
///////////////////////////////////////////////////////////////////////////////////////////////////
219

    
220
  boolean moveCanProceed(int lastA, int lastR, int currA, int currR)
221
    {
222
    return (lastA!=currA) || (lastR!=currR);
223
    }
224

    
225
///////////////////////////////////////////////////////////////////////////////////////////////////
226
// we rotate the whole thing so that quat[0] is always 0.
227

    
228
  void normalizeQuats(int[] quats)
229
    {
230
    if( quats[0]!=0 )
231
      {
232
      int inverted = getInvertedQuat(quats[0]);
233
      quats[0] = 0;
234

    
235
      for(int i=1; i<12; i++)
236
        {
237
        int index = quats[i];
238
        quats[i] = getMultQuat(inverted,index);
239
        }
240
      }
241
    }
242

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

    
245
  public static int[] getPermFromQuats(int[] quats)
246
    {
247
    int[] perm = new int[12];
248

    
249
    for(int i=0; i<12; i++)
250
      {
251
      int[] Q = QUATS[i];
252
      int quat = quats[i];
253

    
254
      for(int j=0; j<12; j++)
255
        if( Q[j]==quat )
256
          {
257
          perm[i] = j;
258
          break;
259
          }
260
      }
261

    
262
    return perm;
263
    }
264

    
265
///////////////////////////////////////////////////////////////////////////////////////////////////
266
// in-place!
267

    
268
  public static int[] getQuatsFromPerm(int[] perm)
269
    {
270
    for(int i=0; i<12; i++)
271
      {
272
      int p = perm[i];
273
      perm[i] = QUATS[i][p];
274
      }
275

    
276
    return perm;
277
    }
278
}  
279

    
(6-6/19)