Project

General

Profile

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

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

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
import org.distorted.objectlib.R;
18

    
19
///////////////////////////////////////////////////////////////////////////////////////////////////
20

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

    
39
  private int[][] mAngles;
40

    
41
///////////////////////////////////////////////////////////////////////////////////////////////////
42

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

    
48
///////////////////////////////////////////////////////////////////////////////////////////////////
49

    
50
  public TBDino(Resources res, int[] middle, int[] high)
51
    {
52
    super(res,middle,high);
53
    }
54

    
55
///////////////////////////////////////////////////////////////////////////////////////////////////
56

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

    
65
    return mAngles;
66
    }
67

    
68
///////////////////////////////////////////////////////////////////////////////////////////////////
69

    
70
  Static3D[] getRotationAxis()
71
    {
72
    return new Static3D[]
73
         {
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
           new Static3D( SQ3/3,-SQ3/3,-SQ3/3),
78
         };
79
    }
80

    
81
///////////////////////////////////////////////////////////////////////////////////////////////////
82

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

    
102
///////////////////////////////////////////////////////////////////////////////////////////////////
103

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

    
110
///////////////////////////////////////////////////////////////////////////////////////////////////
111
// exclude the middle layer
112

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

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

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

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

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

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

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

    
154
    int len = moves.length;
155

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

    
163
///////////////////////////////////////////////////////////////////////////////////////////////////
164

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

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

    
184
///////////////////////////////////////////////////////////////////////////////////////////////////
185

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

    
225
///////////////////////////////////////////////////////////////////////////////////////////////////
226

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

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

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

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

    
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251
// in-place!
252

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

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

    
268
    return quats;
269
    }
270

    
271
///////////////////////////////////////////////////////////////////////////////////////////////////
272
// in-place!
273

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

    
282
    return perm;
283
    }
284
}  
285

    
(5-5/17)