Project

General

Profile

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

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

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 android.content.res.Resources;
15

    
16
import org.distorted.library.type.Static3D;
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(Resources res, int[] middle, int[] high)
50
    {
51
    super(res,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 new Static3D[]
72
         {
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
           new Static3D( SQ3/3,-SQ3/3,-SQ3/3),
77
         };
78
    }
79

    
80
///////////////////////////////////////////////////////////////////////////////////////////////////
81

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

    
101
///////////////////////////////////////////////////////////////////////////////////////////////////
102

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

    
109
///////////////////////////////////////////////////////////////////////////////////////////////////
110
// exclude the middle layer
111

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

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

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

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

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

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

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

    
153
    int len = moves.length;
154

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

    
162
///////////////////////////////////////////////////////////////////////////////////////////////////
163

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

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

    
183
///////////////////////////////////////////////////////////////////////////////////////////////////
184

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

    
224
///////////////////////////////////////////////////////////////////////////////////////////////////
225

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

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

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

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

    
249
///////////////////////////////////////////////////////////////////////////////////////////////////
250
// in-place!
251

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

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

    
267
    return quats;
268
    }
269

    
270
///////////////////////////////////////////////////////////////////////////////////////////////////
271
// in-place!
272

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

    
281
    return perm;
282
    }
283
}  
284

    
(5-5/17)