Project

General

Profile

« Previous | Next » 

Revision a76bb8f6

Added by Leszek Koltunski about 1 year ago

Dino solvers: unroll moves!

View differences:

src/main/java/org/distorted/objectlib/tablebases/TBDino.java
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

  
src/main/java/org/distorted/objectlib/tablebases/TBDino4.java
9 9

  
10 10
package org.distorted.objectlib.tablebases;
11 11

  
12
import static org.distorted.objectlib.main.TwistyObject.SQ3;
13

  
14 12
import android.content.res.Resources;
15 13

  
16
import org.distorted.library.type.Static3D;
17 14
import org.distorted.objectlib.R;
18 15

  
19 16
///////////////////////////////////////////////////////////////////////////////////////////////////
20 17

  
21
public class TBDino4 extends TablebasesAbstract
18
public class TBDino4 extends TBDino
22 19
{
23 20
  private static final int[][] SAME = {{0,3,7},{1,2,5},{4,8,9},{6,10,11}};
24
  private static final int SOLVED1 =  6237;  // part 011021302233
25
  private static final int SOLVED2 = 10837;  // part 001102133223
26
  private int[][] mAngles;
21
  private static final int SOLVED1 =  6237;  // partition 011021302233
22
  private static final int SOLVED2 = 10837;  // partition 001102133223
27 23

  
28 24
///////////////////////////////////////////////////////////////////////////////////////////////////
29 25

  
......
36 32

  
37 33
  public TBDino4(Resources res)
38 34
    {
39
    super(res, R.raw.din4_3_tablebase);
40
    }
41

  
42
///////////////////////////////////////////////////////////////////////////////////////////////////
43

  
44
  int[][] getBasicAngles()
45
    {
46
    if( mAngles==null )
47
      {
48
      int[] tmp = {3,3,3};
49
      mAngles = new int[][] { tmp,tmp,tmp,tmp };
50
      }
51

  
52
    return mAngles;
53
    }
54

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

  
57
  Static3D[] getRotationAxis()
58
    {
59
    return new Static3D[]
60
         {
61
           new Static3D( SQ3/3, SQ3/3, SQ3/3),
62
           new Static3D(-SQ3/3,-SQ3/3, SQ3/3),
63
           new Static3D(-SQ3/3, SQ3/3,-SQ3/3),
64
           new Static3D( SQ3/3,-SQ3/3,-SQ3/3),
65
         };
66
    }
67

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

  
70
  float[][] getPosition()
71
    {
72
    return new float[][]
73
         {
74
             { 0.0f, 1.5f, 1.5f },
75
             { 1.5f, 0.0f, 1.5f },
76
             { 0.0f,-1.5f, 1.5f },
77
             {-1.5f, 0.0f, 1.5f },
78
             { 1.5f, 1.5f, 0.0f },
79
             { 1.5f,-1.5f, 0.0f },
80
             {-1.5f,-1.5f, 0.0f },
81
             {-1.5f, 1.5f, 0.0f },
82
             { 0.0f, 1.5f,-1.5f },
83
             { 1.5f, 0.0f,-1.5f },
84
             { 0.0f,-1.5f,-1.5f },
85
             {-1.5f, 0.0f,-1.5f }
86
         };
87
    }
88

  
89
///////////////////////////////////////////////////////////////////////////////////////////////////
90

  
91
  float[][] getCuts()
92
    {
93
    float[] cut = new float[] { -SQ3/3, SQ3/3 };
94
    return new float[][] { cut,cut,cut,cut };
95
    }
96

  
97
///////////////////////////////////////////////////////////////////////////////////////////////////
98
// exclude the middle layer
99

  
100
  boolean[][] getRotatable()
101
    {
102
    boolean[] tmp = {true,false,true};
103
    return new boolean[][] { tmp,tmp,tmp,tmp };
35
    super(res, new int[] {R.raw.din4_3_pruning2,R.raw.din4_3_pruning3}, new int[] {R.raw.din4_3_pruning7});
104 36
    }
105 37

  
106 38
///////////////////////////////////////////////////////////////////////////////////////////////////
......
124 56
    }
125 57

  
126 58
///////////////////////////////////////////////////////////////////////////////////////////////////
127
// we can never really move the top-front edge, because if we do so, we would also rotate the
128
// rotation axis themselves! (see getIndex() where the cubit quats are normalized so that quat[0]
129
// - i.e. the front-top edge - is always 0).
130
// That's why map the moves (0,2,X) to (0,0&1,-X) and (3,0,X) to (3,1&2,-X)
59
// 15408 really (see https://www.jaapsch.net/puzzles/dinocube.htm)
60
// Here 15400 because we equal positions where colors are simply swapped (those are the same with
61
// respect to distance to the 2 solved positions) so there are (11 choose 2)*(8 choose 2)*(5 choose 2)
62
// = 55*28*10 = 15400 possibilities.
63
// We do not pack those tightly, some positions in the same orbit (by Burnside lemma) have 3 different
64
// indices.
131 65

  
132
  @Override
133
  int[] newMove(int axis, int layer, int angle)
66
  int getSize()
134 67
    {
135
    if( axis==0 && layer==2 ) return new int[] { axis, 3, angle==1 ? 1:-1};
136
    if( axis==3 && layer==0 ) return new int[] { axis, 6, angle==1 ? 1:-1};
137

  
138
    int maxAngle = mAngles[axis][layer];
139
    angle = maxAngle-angle;
140
    if( angle> 0.5f*maxAngle ) angle -= maxAngle;
141
    return new int[] { axis, (1<<layer), angle };
68
    return 15400;
142 69
    }
143 70

  
144 71
///////////////////////////////////////////////////////////////////////////////////////////////////
145 72

  
146
  @Override
147
  void convertMoves(int[][] moves)
73
  int getMinScramble()
148 74
    {
149
    for(int[] move : moves )
150
      {
151
      int[] newMove = newMove(move[0],move[1],move[2]);
75
    return 5;
76
    }
152 77

  
153
      move[0] = newMove[0];
154
      move[1] = newMove[1];
155
      move[2] = newMove[2];
156
      }
78
///////////////////////////////////////////////////////////////////////////////////////////////////
79

  
80
  int[] getMidPruningLevels()
81
    {
82
    return new int[] {2,3};
157 83
    }
158 84

  
159 85
///////////////////////////////////////////////////////////////////////////////////////////////////
160
// 15408 really (see https://www.jaapsch.net/puzzles/dinocube.htm)
161
// Here 15400 because we equal positions where colors are simply swapped (those are the same with
162
// respect to distance to the 2 solved positions) so there are (11 choose 2)*(8 choose 2)*(5 choose 2)
163
// = 55*28*10 = 15400 possibilities.
164
// We do not pack those tightly, some positions in the same orbit (by Burnside lemma) have 3 different
165
// indices.
166 86

  
167
  int getSize()
87
  int[] getHighPruningLevels()
168 88
    {
169
    return 15400;
89
    return new int[] {7};
170 90
    }
171 91

  
172 92
///////////////////////////////////////////////////////////////////////////////////////////////////
173 93

  
174
  int getMinScramble()
94
  int getGodsNumber()
175 95
    {
176
    return 5;
96
    return 7;
177 97
    }
178 98

  
179 99
///////////////////////////////////////////////////////////////////////////////////////////////////
......
340 260
    return part;
341 261
    }
342 262

  
343
///////////////////////////////////////////////////////////////////////////////////////////////////
344
// we rotate the whole thing so that quat[0] is always 0.
345

  
346
  private void normalizeQuats(int[] quats)
347
    {
348
    if( quats[0]!=0 )
349
      {
350
      int inverted = getInvertedQuat(quats[0]);
351
      quats[0] = 0;
352

  
353
      for(int i=1; i<12; i++)
354
        {
355
        int index = quats[i];
356
        quats[i] = getMultQuat(inverted,index);
357
        }
358
      }
359
    }
360

  
361 263
///////////////////////////////////////////////////////////////////////////////////////////////////
362 264

  
363 265
  int[] getQuats(int index)
src/main/java/org/distorted/objectlib/tablebases/TBDino6.java
9 9

  
10 10
package org.distorted.objectlib.tablebases;
11 11

  
12
import static org.distorted.objectlib.main.TwistyObject.SQ3;
13

  
14 12
import android.content.res.Resources;
15 13

  
16
import org.distorted.library.type.Static3D;
17 14
import org.distorted.objectlib.R;
18 15

  
19 16
///////////////////////////////////////////////////////////////////////////////////////////////////
20 17

  
21
public class TBDino6 extends TablebasesPruning
18
public class TBDino6 extends TBDino
22 19
{
23
  private static final int INDEX_INVERTED = 13379863; // quats (0,10,0,10, 11,11,11,11, 0,10,0,10)
24

  
25
  private static final int[][] QUATS =
26
      {
27
          {0,2,10,8, 1,3,5,7,   11,6,9,4},
28
          {1,0,5,10, 2,6,8,4,   7,9,3,11},
29
          {10,6,0,4, 7,5,3,1,   9,2,11,8},
30
          {7,10,3,0, 6,2,4,8,   1,11,5,9},
31
          {2,1,8,5,  0,9,10,11, 4,3,6,7 },
32
          {4,5,6,1,  9,0,11,10, 2,7,8,3 },
33
          {6,7,4,3,  10,11,0,9, 8,5,2,1 },
34
          {8,3,2,7,  11,10,9,0, 6,1,4,5 },
35
          {11,8,9,2, 3,1,7,5,   0,4,10,6},
36
          {5,9,1,11, 4,8,6,2,   3,0,7,10},
37
          {9,4,11,6, 5,7,1,3,   10,8,0,2},
38
          {3,11,7,9, 8,4,2,6,   5,10,1,0}
39
      };
40

  
41
  private int[][] mAngles;
20
  private static final int SOLVED1 =        0;
21
  private static final int SOLVED2 = 13379863; // quats (0,10,0,10, 11,11,11,11, 0,10,0,10)
42 22

  
43 23
///////////////////////////////////////////////////////////////////////////////////////////////////
44 24

  
......
54 34
    super(res,new int[] {R.raw.dino_3_pruning3,R.raw.dino_3_pruning4},new int[] {R.raw.dino_3_pruning10});
55 35
    }
56 36

  
57
///////////////////////////////////////////////////////////////////////////////////////////////////
58

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

  
67
    return mAngles;
68
    }
69

  
70
///////////////////////////////////////////////////////////////////////////////////////////////////
71

  
72
  Static3D[] getRotationAxis()
73
    {
74
    return new Static3D[]
75
         {
76
           new Static3D( SQ3/3, SQ3/3, SQ3/3),
77
           new Static3D(-SQ3/3,-SQ3/3, SQ3/3),
78
           new Static3D(-SQ3/3, SQ3/3,-SQ3/3),
79
           new Static3D( SQ3/3,-SQ3/3,-SQ3/3),
80
         };
81
    }
82

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

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

  
104
///////////////////////////////////////////////////////////////////////////////////////////////////
105

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

  
112
///////////////////////////////////////////////////////////////////////////////////////////////////
113
// exclude the middle layer
114

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

  
121 37
///////////////////////////////////////////////////////////////////////////////////////////////////
122 38
// specifically for the tablebase
123 39
///////////////////////////////////////////////////////////////////////////////////////////////////
......
126 42
  @Override
127 43
  int[] getSolvedIndices()
128 44
    {
129
    return new int[] {0,INDEX_INVERTED};
45
    return new int[] {SOLVED1,SOLVED2};
130 46
    }
131 47

  
132 48
///////////////////////////////////////////////////////////////////////////////////////////////////
......
135 51
  @Override
136 52
  boolean isSolved(int index)
137 53
    {
138
    return index==0 || index==INDEX_INVERTED;
139
    }
140

  
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142
// we can never really move the top-front edge, because if we do so, we would also rotate the
143
// rotation axis themselves! (see getIndex() where the cubit quats are normalized so that quat[0]
144
// - i.e. the front-top edge - is always 0).
145
// That's why map the moves (0,2,X) to (0,0&1,-X) and (3,0,X) to (3,1&2,-X)
146

  
147
  @Override
148
  int[] newMove(int axis, int layer, int angle)
149
    {
150
    if( axis==0 && layer==2 ) return new int[] { axis, 3, angle==1 ? 1:-1};
151
    if( axis==3 && layer==0 ) return new int[] { axis, 6, angle==1 ? 1:-1};
152

  
153
    int maxAngle = mAngles[axis][layer];
154
    angle = maxAngle-angle;
155
    if( angle> 0.5f*maxAngle ) angle -= maxAngle;
156
    return new int[] { axis, (1<<layer), angle };
157
    }
158

  
159
///////////////////////////////////////////////////////////////////////////////////////////////////
160
// here we change back the mapping introduced by 'newMove()'
161

  
162
  @Override
163
  void convertMoves(int[][] moves)
164
    {
165
    for(int[] move : moves )
166
      {
167
      int[] newMove = newMove(move[0],move[1],move[2]);
168

  
169
      move[0] = newMove[0];
170
      move[1] = newMove[1];
171
      move[2] = newMove[2];
172
      }
173
/*
174
    int len = moves.length;
175

  
176
    for(int i=0; i<len; i++)
177
      {
178
      int[] move = moves[i];
179
      if( move[1]==3 || move[1]==6 ) unrollMoves(moves,i);
180
      }
181
 */
182
    }
183

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

  
186
  private void unrollMoves(int[][] moves, int index)
187
    {
188
    int[] move = moves[index];
189
    int len = moves.length;
190

  
191
    if( move[0]==0 && move[1]==3 )
192
      {
193
      move[1] = 4;
194
      move[2] = -move[2];
195
      for(int i=index+1; i<len; i++) unrollMove(moves[i],move[2]>0 ? 0:1);
196
      }
197
    else if( move[0]==3 && move[1]==6 )
198
      {
199
      move[1] = 1;
200
      move[2] = -move[2];
201
      for(int i=index+1; i<len; i++) unrollMove(moves[i],move[2]>0 ? 0:1);
202
      }
203
    }
204

  
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206

  
207
  private void printMoves(String s, int[][] moves)
208
    {
209
    StringBuilder sb = new StringBuilder();
210

  
211
    for(int[] move: moves)
212
      {
213
      sb.append('(');
214
      sb.append(move[0]);
215
      sb.append(' ');
216
      sb.append(move[1]);
217
      sb.append(' ');
218
      sb.append(move[2]);
219
      sb.append(')');
220
      }
221

  
222
    android.util.Log.e("D", s+" : "+sb);
223
    }
224

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

  
227
  private void unrollMove(int[] move, int caseUnroll)
228
    {
229
    int ax = move[0];
230
    int la = move[1];
231

  
232
    switch(caseUnroll)
233
      {
234
      case 0: android.util.Log.e("D", "case 0 ax "+ax);
235
              switch(ax)
236
                {
237
                case 0: break;
238
                case 1: move[0]=3; move[1]=negate(la); move[2] = -move[2]; break;
239
                case 2: move[0]=1; break;
240
                case 3: move[0]=2; move[1]=negate(la); move[2] = -move[2]; break;
241
                }
242
              break;
243
      case 1: android.util.Log.e("D", "case 1 ax "+ax);
244
              switch(ax)
245
                {
246
                case 0: break;
247
                case 1: move[0]=2; break;
248
                case 2: move[0]=3; move[1]=negate(la); move[2] = -move[2]; break;
249
                case 3: move[0]=1; move[1]=negate(la); move[2] = -move[2]; break;
250
                }
251
              break;
252
      case 2: android.util.Log.e("D", "case 2 ax "+ax);
253
              switch(ax)
254
                {
255
                case 0: move[0]=1; move[1]=negate(la); move[2] = -move[2]; break;
256
                case 1: move[0]=2; break;
257
                case 2: move[0]=0; move[1]=negate(la); move[2] = -move[2]; break;
258
                case 3: break;
259
                }
260
              break;
261
      case 3: android.util.Log.e("D", "case 3 ax "+ax);
262
              switch(ax)
263
                {
264
                case 0: move[0]=2; move[1]=negate(la); move[2] = -move[2]; break;
265
                case 1: move[0]=0; move[1]=negate(la); move[2] = -move[2]; break;
266
                case 2: move[0]=1; break;
267
                case 3: break;
268
                }
269
              break;
270
      }
271
    }
272

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

  
275
  private int negate(int layer)
276
    {
277
    switch(layer)
278
      {
279
      case 1: return 4;
280
      case 3: return 6;
281
      case 4: return 1;
282
      case 6: return 3;
283
      }
284
    return layer;
54
    return index==SOLVED1 || index==SOLVED2;
285 55
    }
286 56

  
287 57
///////////////////////////////////////////////////////////////////////////////////////////////////
......
319 89
    return 10;
320 90
    }
321 91

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

  
324
  boolean moveCanProceed(int lastA, int lastR, int currA, int currR)
325
    {
326
    return (lastA!=currA) || (lastR!=currR);
327
    }
328

  
329 92
///////////////////////////////////////////////////////////////////////////////////////////////////
330 93

  
331 94
  public static int getIndexFromPerm(int[] perm)
......
335 98
    return TablebaseHelpers.computeEvenPermutationNum(perm11);
336 99
    }
337 100

  
338
///////////////////////////////////////////////////////////////////////////////////////////////////
339
// in-place!
340

  
341
  public static int[] getPermFromQuats(int[] quats)
342
    {
343
    for(int i=0; i<12; i++)
344
      {
345
      int[] Q = QUATS[i];
346
      int quat = quats[i];
347

  
348
      for(int j=0; j<12; j++)
349
        if( Q[j]==quat )
350
          {
351
          quats[i] = j;
352
          break;
353
          }
354
      }
355

  
356
    return quats;
357
    }
358

  
359
///////////////////////////////////////////////////////////////////////////////////////////////////
360
// in-place!
361

  
362
  public static int[] getQuatsFromPerm(int[] perm)
363
    {
364
    for(int i=0; i<12; i++)
365
      {
366
      int p = perm[i];
367
      perm[i] = QUATS[i][p];
368
      }
369

  
370
    return perm;
371
    }
372

  
373
///////////////////////////////////////////////////////////////////////////////////////////////////
374
// we rotate the whole thing so that quat[0] is always 0.
375

  
376
  private void normalizeQuats(int[] quats)
377
    {
378
    if( quats[0]!=0 )
379
      {
380
      int inverted = getInvertedQuat(quats[0]);
381
      quats[0] = 0;
382

  
383
      for(int i=1; i<12; i++)
384
        {
385
        int index = quats[i];
386
        quats[i] = getMultQuat(inverted,index);
387
        }
388
      }
389
    }
390

  
391 101
///////////////////////////////////////////////////////////////////////////////////////////////////
392 102

  
393 103
  int[] getQuats(int index)

Also available in: Unified diff