Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / tablebases / TablebasesAbstract.java @ 2d697abd

1 a110ebe1 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 352b3356 Leszek Koltunski
import android.content.res.Resources;
13
14 a110ebe1 Leszek Koltunski
import org.distorted.library.main.QuatHelper;
15
import org.distorted.library.type.Static3D;
16
import org.distorted.library.type.Static4D;
17
import org.distorted.objectlib.helpers.QuatGroupGenerator;
18
19 352b3356 Leszek Koltunski
import java.io.ByteArrayOutputStream;
20
import java.io.IOException;
21
import java.io.InputStream;
22 bf5c802b Leszek Koltunski
import java.util.ArrayList;
23 3addecce Leszek Koltunski
import java.util.Random;
24 bf5c802b Leszek Koltunski
25 a110ebe1 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
26
27 1725b607 Leszek Koltunski
public abstract class TablebasesAbstract
28 a110ebe1 Leszek Koltunski
{
29
  private final Static3D[] mAxis;
30 c0266cb1 Leszek Koltunski
  private final int mSize, mMinScramble;
31 a110ebe1 Leszek Koltunski
  private final int[][] mAngles;
32
  private final int[] mNumLayers;
33
  private final int mNumQuats;
34
  private final Static4D[] mQuats;
35
  private final float[][] mCuts;
36
  private final int[] mNumCuts;
37 b4111717 Leszek Koltunski
38 a110ebe1 Leszek Koltunski
  private int[][] mQuatMult;
39
40 15d1f6ad Leszek Koltunski
  Tablebase mTablebase;
41 db2ed801 Leszek Koltunski
  boolean mInitialized;
42
43 bdcb662f Leszek Koltunski
  final int mScalingFactor;
44
  final int mNumAxis;
45
  final float[][] mPosition;
46
  final int[][] mRotRow;
47
  final int mNumCubits;
48
  final boolean[][] mRotatable;
49 15d1f6ad Leszek Koltunski
50 b4111717 Leszek Koltunski
  private static final float[] mTmp = new float[4];
51
52 a110ebe1 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
53
54
  abstract int[][] getBasicAngles();
55
  abstract Static3D[] getRotationAxis();
56
  abstract float[][] getPosition();
57
  abstract float[][] getCuts();
58
59 b4111717 Leszek Koltunski
  abstract boolean[][] getRotatable();
60
61 c0266cb1 Leszek Koltunski
  abstract int getMinScramble();
62 b4111717 Leszek Koltunski
  abstract int getSize();
63
  abstract int[] getQuats(int index);
64
  abstract int getIndex(int[] quats);
65
66 a110ebe1 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
67
68 1725b607 Leszek Koltunski
  public TablebasesAbstract()
69 a110ebe1 Leszek Koltunski
    {
70
    mSize = getSize();
71 c0266cb1 Leszek Koltunski
    mMinScramble = getMinScramble();
72 a110ebe1 Leszek Koltunski
    mAngles = getBasicAngles();
73
    mAxis = getRotationAxis();
74
    mNumAxis = mAxis.length;
75
    mNumLayers = new int[mNumAxis];
76
    for(int i=0; i<mNumAxis; i++) mNumLayers[i] = mAngles[i].length;
77
    mQuats = QuatGroupGenerator.computeGroup(mAxis,mAngles);
78
    mNumQuats = mQuats.length;
79
    mPosition = getPosition();
80
    mNumCubits = mPosition.length;
81 b4111717 Leszek Koltunski
    mRotatable = getRotatable();
82 a110ebe1 Leszek Koltunski
    mCuts = getCuts();
83
    mNumCuts = new int[mNumAxis];
84
85 3addecce Leszek Koltunski
    int scaling = 0;
86
87 a110ebe1 Leszek Koltunski
    for(int i=0; i<mNumAxis; i++)
88
      {
89
      mNumCuts[i] = (mCuts==null || mCuts[i]==null ? 0 : mCuts[i].length);
90 3addecce Leszek Koltunski
      int numLayers = mNumLayers[i];
91
      for(int j=0; j<numLayers; j++) scaling+=(mAngles[i][j]-1);
92 a110ebe1 Leszek Koltunski
      }
93
94 3addecce Leszek Koltunski
    mScalingFactor = scaling;
95 a110ebe1 Leszek Koltunski
    mRotRow = new int[mNumCubits][mNumAxis];
96 5e501d98 Leszek Koltunski
    mInitialized = false;
97 352b3356 Leszek Koltunski
    }
98
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100
101 1725b607 Leszek Koltunski
  public TablebasesAbstract(Resources res, int resource)
102 352b3356 Leszek Koltunski
    {
103
    this();
104
105 f9980f6a Leszek Koltunski
    mInitialized = true;
106 352b3356 Leszek Koltunski
    InputStream stream = res.openRawResource(resource);
107
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
108
109
    int nRead;
110
    byte[] tmp = new byte[16384];
111
112
    try
113
      {
114
      while ((nRead = stream.read(tmp, 0, tmp.length)) != -1)
115
        {
116
        buffer.write(tmp, 0, nRead);
117
        }
118 1725b607 Leszek Koltunski
      stream.close();
119 352b3356 Leszek Koltunski
      byte[] data = buffer.toByteArray();
120 1725b607 Leszek Koltunski
      buffer.close();
121 352b3356 Leszek Koltunski
      mTablebase = new Tablebase(data);
122
      }
123
    catch(IOException ex)
124
      {
125
      mInitialized = false;
126
      }
127 a110ebe1 Leszek Koltunski
    }
128
129
///////////////////////////////////////////////////////////////////////////////////////////////////
130
131 bdcb662f Leszek Koltunski
  int computeRow(float[] pos, int quat, int axisIndex)
132 a110ebe1 Leszek Koltunski
    {
133
    int ret=0;
134
    int len = pos.length/3;
135
    Static3D axis = mAxis[axisIndex];
136
    float axisX = axis.get0();
137
    float axisY = axis.get1();
138
    float axisZ = axis.get2();
139
    float casted, xoff=0, yoff=0, zoff=0;
140 b4111717 Leszek Koltunski
    Static4D q = mQuats[quat];
141 a110ebe1 Leszek Koltunski
142
    for(int i=0; i<len; i++)
143
      {
144 b4111717 Leszek Koltunski
      QuatHelper.rotateVectorByQuat(mTmp,pos[3*i],pos[3*i+1],pos[3*i+2],1.0f,q);
145
      casted = (mTmp[0]+xoff)*axisX + (mTmp[1]+yoff)*axisY + (mTmp[2]+zoff)*axisZ;
146 a110ebe1 Leszek Koltunski
      ret |= computeSingleRow(axisIndex,casted);
147
      }
148
149
    return ret;
150
    }
151
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153
154
  private int computeSingleRow(int axisIndex,float casted)
155
    {
156
    int num = mNumCuts[axisIndex];
157
158
    for(int i=0; i<num; i++)
159
      {
160
      if( casted<mCuts[axisIndex][i] ) return (1<<i);
161
      }
162
163
    return (1<<num);
164
    }
165
166
///////////////////////////////////////////////////////////////////////////////////////////////////
167
// remember about the double cover or unit quaternions!
168
169
  private int mulQuat(int q1, int q2)
170
    {
171
    Static4D result = QuatHelper.quatMultiply(mQuats[q1],mQuats[q2]);
172
173
    float rX = result.get0();
174
    float rY = result.get1();
175
    float rZ = result.get2();
176
    float rW = result.get3();
177
178
    final float MAX_ERROR = 0.1f;
179
    float dX,dY,dZ,dW;
180
181
    for(int i=0; i<mNumQuats; i++)
182
      {
183
      dX = mQuats[i].get0() - rX;
184
      dY = mQuats[i].get1() - rY;
185
      dZ = mQuats[i].get2() - rZ;
186
      dW = mQuats[i].get3() - rW;
187
188
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
189
          dY<MAX_ERROR && dY>-MAX_ERROR &&
190
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
191
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
192
193
      dX = mQuats[i].get0() + rX;
194
      dY = mQuats[i].get1() + rY;
195
      dZ = mQuats[i].get2() + rZ;
196
      dW = mQuats[i].get3() + rW;
197
198
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
199
          dY<MAX_ERROR && dY>-MAX_ERROR &&
200
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
201
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
202
      }
203
204
    return -1;
205
    }
206
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208
209 bdcb662f Leszek Koltunski
  int getMultQuat(int index1, int index2)
210 a110ebe1 Leszek Koltunski
    {
211
    if( mQuatMult==null )
212
      {
213
      mQuatMult = new int[mNumQuats][mNumQuats];
214
215
      for(int i=0; i<mNumQuats; i++)
216
        for(int j=0; j<mNumQuats; j++) mQuatMult[i][j] = -1;
217
      }
218
219
    if( index1<mNumQuats && index2<mNumQuats )
220
      {
221
      if( mQuatMult[index1][index2]==-1 ) mQuatMult[index1][index2] = mulQuat(index1,index2);
222
      return mQuatMult[index1][index2];
223
      }
224
225
    return -2;
226
    }
227
228
///////////////////////////////////////////////////////////////////////////////////////////////////
229
// assumption: all layers have the same basicAngles!
230
231
  private int insertAllChildren(int index, byte level)
232
    {
233
    int ret = 0;
234
    int[] quats = getQuats(index);
235
    int numQuats = quats.length;
236
    int[] tmpQuats = new int[numQuats];
237
    byte newLevel = (byte)(level+1);
238
    int quatBasis = 0;
239
240 ce7202ef Leszek Koltunski
    for(int ax=0; ax<mNumAxis; ax++)
241
      for(int cubit=0; cubit<mNumCubits; cubit++)
242
        mRotRow[cubit][ax] = computeRow(mPosition[cubit],quats[cubit],ax);
243
244 a110ebe1 Leszek Koltunski
    for(int ax=0; ax<mNumAxis; ax++)
245
      {
246
      for(int layer=0; layer<mNumLayers[ax]; layer++)
247
        {
248 b4111717 Leszek Koltunski
        if( !mRotatable[ax][layer] ) continue;
249
        int bitLayer = (1<<layer);
250 a110ebe1 Leszek Koltunski
        int maxAngle = mAngles[ax][layer];
251
252
        for(int angle=1; angle<maxAngle; angle++ )
253
          {
254
          System.arraycopy(quats, 0, tmpQuats, 0, numQuats);
255
          int quat = quatBasis + angle;
256
257
          for(int cubit=0; cubit<mNumCubits; cubit++)
258 ce7202ef Leszek Koltunski
            if( mRotRow[cubit][ax]==bitLayer )
259 a110ebe1 Leszek Koltunski
              {
260
              int currQuat = tmpQuats[cubit];
261 b4111717 Leszek Koltunski
              int newQuat = getMultQuat(quat,currQuat);
262 a110ebe1 Leszek Koltunski
              tmpQuats[cubit] = newQuat;
263
              }
264
265
          int childIndex = getIndex(tmpQuats);
266
          if( mTablebase.insertUnpacked(childIndex,newLevel) ) ret++;
267
          }
268
        }
269
270
      quatBasis += (mAngles[ax][0]-1);
271
      }
272
273
    return ret;
274
    }
275
276
///////////////////////////////////////////////////////////////////////////////////////////////////
277
278 5e30b196 Leszek Koltunski
  public void createTablebase(int maxLevel)
279 a110ebe1 Leszek Koltunski
    {
280
    mTablebase = new Tablebase(mSize);
281
    mTablebase.insertUnpacked(0,(byte)0);
282
283 f9980f6a Leszek Koltunski
    int numInserted, totalInserted=1;
284 a110ebe1 Leszek Koltunski
    byte insertingLevel = 0;
285
286 462911fd Leszek Koltunski
    android.util.Log.e("D", "creating tablebase of size "+mSize);
287
288 a110ebe1 Leszek Koltunski
    do
289
      {
290
      numInserted = 0;
291
292
      for(int i=0; i<mSize; i++)
293
        {
294
        byte level = mTablebase.retrieveUnpacked(i);
295
        if( level==insertingLevel ) numInserted += insertAllChildren(i,level);
296
        }
297
298
      insertingLevel++;
299 f9980f6a Leszek Koltunski
      totalInserted += numInserted;
300 bf5c802b Leszek Koltunski
      android.util.Log.e("D", "inserted "+numInserted+" positions at level "+insertingLevel);
301 a110ebe1 Leszek Koltunski
      }
302 5e30b196 Leszek Koltunski
    while( numInserted>0 && insertingLevel!=maxLevel );
303 bf5c802b Leszek Koltunski
304 f9980f6a Leszek Koltunski
    android.util.Log.e("D", "total Inserted: "+totalInserted);
305 5e30b196 Leszek Koltunski
    }
306
307
///////////////////////////////////////////////////////////////////////////////////////////////////
308
309
  public void pack()
310
    {
311 462911fd Leszek Koltunski
    android.util.Log.e("D", "packing...");
312 bf5c802b Leszek Koltunski
    mTablebase.pack();
313 462911fd Leszek Koltunski
    android.util.Log.e("D", "all done");
314 5e501d98 Leszek Koltunski
    mInitialized = true;
315 462911fd Leszek Koltunski
    }
316
317
///////////////////////////////////////////////////////////////////////////////////////////////////
318
319 15d1f6ad Leszek Koltunski
  public byte[][] getPacked()
320 462911fd Leszek Koltunski
    {
321 b8a7c09d Leszek Koltunski
    if( !mInitialized )
322
      {
323
      createTablebase(-1);
324
      pack();
325
      }
326 15d1f6ad Leszek Koltunski
327 b8a7c09d Leszek Koltunski
    byte[] data = mTablebase.getPacked();
328 15d1f6ad Leszek Koltunski
    return new byte[][] { data };
329 a110ebe1 Leszek Koltunski
    }
330 3ee79c9c Leszek Koltunski
331 bdcb662f Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
332
333
  void convertMoves(int[][] moves)
334
    {
335
    for(int[] move : moves )
336
      {
337
      int axis = move[0];
338
      int layer= move[1];
339
      int angle= move[2];
340
341
      int maxAngle = mAngles[axis][layer];
342
      angle = maxAngle-angle;
343
      if( angle> 0.5f*maxAngle ) angle -= maxAngle;
344
345
      move[1] = (1<<layer);
346
      move[2] = angle;
347
      }
348
    }
349
350 3ee79c9c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
351
352 bf5c802b Leszek Koltunski
  private void addMove(ArrayList<int[]> moves, int axis, int layer, int angle)
353 3ee79c9c Leszek Koltunski
    {
354
    int maxAngle = mAngles[axis][layer];
355
    angle = maxAngle-angle;
356
    if( angle> 0.5f*maxAngle ) angle -= maxAngle;
357
358 bf5c802b Leszek Koltunski
    int[] move = new int[] { axis, (1<<layer), angle };
359
    moves.add(move);
360
    }
361
362
///////////////////////////////////////////////////////////////////////////////////////////////////
363
364
  private int[][] convertMoves(ArrayList<int[]> moves)
365
    {
366
    int len = moves.size();
367
    int[][] ret = new int[len][];
368
    for(int i=0; i<len; i++) ret[i] = moves.get(i);
369
    return ret;
370 3ee79c9c Leszek Koltunski
    }
371
372 3addecce Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
373
374 bdcb662f Leszek Koltunski
  void getNextAxisLayerAngleQuat(int[] data)
375 3addecce Leszek Koltunski
    {
376
    int axis = data[0];
377
    int layer= data[1];
378
    int angle= data[2];
379
380
    if( angle< mAngles[axis][layer]-1 ) data[2]++;
381
    else
382
      {
383
      data[2] = 1;
384
385
      if( layer< mNumLayers[axis]-1 ) data[1]++;
386
      else
387
        {
388
        data[1] = 0;
389
        data[0] = (axis<mNumAxis-1) ? axis+1 : 0;
390
        }
391
      }
392 971a184e Leszek Koltunski
393
    data[3] = data[2];
394
    for(int i=0; i<data[0]; i++) data[3] += (mAngles[i][0]-1);
395 3addecce Leszek Koltunski
    }
396
397 3ee79c9c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
398
399 6d637f71 Leszek Koltunski
  int[][] extraInfo(int[][] moves, int[] extra)
400
    {
401
    return moves;
402
    }
403
404
///////////////////////////////////////////////////////////////////////////////////////////////////
405
406
  public int[][] solution(int index, int[] extra)
407 3ee79c9c Leszek Koltunski
    {
408 352b3356 Leszek Koltunski
    if( !mInitialized ) return null;
409
410 971a184e Leszek Koltunski
    int[] data = new int[4];
411 431ee33b Leszek Koltunski
    byte level = mTablebase.retrievePacked(index);
412 bf5c802b Leszek Koltunski
    ArrayList<int[]> moves = new ArrayList<>();
413 3ee79c9c Leszek Koltunski
    int[] quats = getQuats(index);
414
    int numQuats = quats.length;
415
    int[] tmpQuats = new int[numQuats];
416
417 bf5c802b Leszek Koltunski
    while(index!=0)
418 3ee79c9c Leszek Koltunski
      {
419 7c1a110c Leszek Koltunski
      boolean found = false;
420
421 3addecce Leszek Koltunski
      data[0]=0;
422
      data[1]=0;
423
      data[2]=1;
424 971a184e Leszek Koltunski
      data[3]=1;
425 3addecce Leszek Koltunski
426 ce7202ef Leszek Koltunski
      for(int ax=0; ax<mNumAxis; ax++)
427
        for(int cubit=0; cubit<mNumCubits; cubit++)
428
          mRotRow[cubit][ax] = computeRow(mPosition[cubit],quats[cubit],ax);
429
430 3addecce Leszek Koltunski
      for(int s=0; s<mScalingFactor && !found; s++)
431 3ee79c9c Leszek Koltunski
        {
432 3addecce Leszek Koltunski
        int ax    = data[0];
433
        int layer = data[1];
434
        int angle = data[2];
435 971a184e Leszek Koltunski
        int quat  = data[3];
436 3ee79c9c Leszek Koltunski
437 3addecce Leszek Koltunski
        if( mRotatable[ax][layer] )
438 3ee79c9c Leszek Koltunski
          {
439
          int bitLayer = (1<<layer);
440 3addecce Leszek Koltunski
          System.arraycopy(quats, 0, tmpQuats, 0, numQuats);
441 3ee79c9c Leszek Koltunski
442 3addecce Leszek Koltunski
          for(int cubit=0; cubit<mNumCubits; cubit++)
443
            if( mRotRow[cubit][ax]==bitLayer )
444 3ee79c9c Leszek Koltunski
              {
445 3addecce Leszek Koltunski
              int currQuat = tmpQuats[cubit];
446
              int newQuat = getMultQuat(quat,currQuat);
447
              tmpQuats[cubit] = newQuat;
448 3ee79c9c Leszek Koltunski
              }
449 3addecce Leszek Koltunski
450
          int childIndex = getIndex(tmpQuats);
451
          byte newLevel = mTablebase.retrievePacked(childIndex);
452
453
          if( ((newLevel-level+1)%3) == 0 )
454
            {
455
            addMove(moves,ax,layer,angle);
456
            index = childIndex;
457
            level = (level==0 ? 2 : (byte)(level-1));
458
            found = true;
459 3ee79c9c Leszek Koltunski
            }
460
          }
461
462 971a184e Leszek Koltunski
        getNextAxisLayerAngleQuat(data);
463 3ee79c9c Leszek Koltunski
        }
464
465
      quats = getQuats(index);
466 7c1a110c Leszek Koltunski
467
      if( !found )
468
        {
469 74cc695a Leszek Koltunski
        android.util.Log.e("D", "----> solution error: no move found!");
470 7c1a110c Leszek Koltunski
        return null;
471
        }
472 3ee79c9c Leszek Koltunski
      }
473
474 6d637f71 Leszek Koltunski
    int[][] ret = convertMoves(moves);
475
    return extraInfo(ret,extra);
476 3ee79c9c Leszek Koltunski
    }
477 462911fd Leszek Koltunski
478
///////////////////////////////////////////////////////////////////////////////////////////////////
479
480 c0266cb1 Leszek Koltunski
  public void scramble(Random rnd, int depth, int[][] scramble)
481 462911fd Leszek Koltunski
    {
482 c0266cb1 Leszek Koltunski
    if( !mInitialized ) return;
483 3addecce Leszek Koltunski
484 c0266cb1 Leszek Koltunski
    int solDepth = 0;
485
    int scraLen = scramble.length;
486
    if( depth>mMinScramble ) depth = mMinScramble;
487 462911fd Leszek Koltunski
488 6d637f71 Leszek Koltunski
    int[] cornerTwist = new int[4];
489
    for(int i=0; i<4; i++) cornerTwist[i] = (rnd.nextInt(3)-1);
490
491 c0266cb1 Leszek Koltunski
    while( solDepth<depth )
492 462911fd Leszek Koltunski
      {
493 c0266cb1 Leszek Koltunski
      int randomPosition = rnd.nextInt(mSize-1);
494 6d637f71 Leszek Koltunski
      int[][] sol = solution(randomPosition,cornerTwist);
495 c0266cb1 Leszek Koltunski
      solDepth = sol.length;
496 ce7202ef Leszek Koltunski
497 c0266cb1 Leszek Koltunski
      if( solDepth>=depth )
498 462911fd Leszek Koltunski
        {
499 c0266cb1 Leszek Koltunski
        int num = Math.min(scraLen,solDepth);
500 462911fd Leszek Koltunski
501 c0266cb1 Leszek Koltunski
        for(int i=0; i<num; i++)
502 462911fd Leszek Koltunski
          {
503 c0266cb1 Leszek Koltunski
          int[] source = sol[solDepth-1-i];
504
          scramble[i][0] = source[0];
505 00057bb1 Leszek Koltunski
          scramble[i][1] = source[1];
506 c0266cb1 Leszek Koltunski
          scramble[i][2] =-source[2];
507 462911fd Leszek Koltunski
          }
508
        }
509
      }
510
    }
511 74cc695a Leszek Koltunski
512
///////////////////////////////////////////////////////////////////////////////////////////////////
513
514
  public boolean test(int index)
515
    {
516
    if( !mInitialized ) return false;
517
518
    int[] data = new int[4];
519
    byte level = mTablebase.retrievePacked(index);
520
    int[] quats = getQuats(index);
521
    int numQuats = quats.length;
522
    int[] tmpQuats = new int[numQuats];
523
524
    data[0]=0;
525
    data[1]=0;
526
    data[2]=1;
527
    data[3]=1;
528
529
    for(int ax=0; ax<mNumAxis; ax++)
530
      for(int cubit=0; cubit<mNumCubits; cubit++)
531
        mRotRow[cubit][ax] = computeRow(mPosition[cubit],quats[cubit],ax);
532
533
    for(int s=0; s<mScalingFactor; s++)
534
      {
535
      int ax    = data[0];
536
      int layer = data[1];
537
      int quat  = data[3];
538
539
      if( mRotatable[ax][layer] )
540
        {
541
        int bitLayer = (1<<layer);
542
        System.arraycopy(quats, 0, tmpQuats, 0, numQuats);
543
544
        for(int cubit=0; cubit<mNumCubits; cubit++)
545
          if( mRotRow[cubit][ax]==bitLayer )
546
            {
547
            int currQuat = tmpQuats[cubit];
548
            int newQuat = getMultQuat(quat,currQuat);
549
            tmpQuats[cubit] = newQuat;
550
            }
551
552
        int childIndex = getIndex(tmpQuats);
553
        byte newLevel = mTablebase.retrievePacked(childIndex);
554
555
        if( ((newLevel-level+1)%3) == 0 ) return true;
556
        }
557
558
      getNextAxisLayerAngleQuat(data);
559
      }
560
561
    return false;
562
    }
563 5e30b196 Leszek Koltunski
564
///////////////////////////////////////////////////////////////////////////////////////////////////
565
566
    public void testPruning(int level)
567
      {
568 f079bf77 Leszek Koltunski
      for( int supp : PruningTable.SUPPORTED )
569
        {
570
        PruningTable table = new PruningTable(mTablebase, level, supp);
571
        int size = mTablebase.getSize();
572 5e30b196 Leszek Koltunski
573 f079bf77 Leszek Koltunski
        StringBuilder sb = new StringBuilder();
574
        int num = 0;
575 5e30b196 Leszek Koltunski
576 f079bf77 Leszek Koltunski
        for(int i=0; i<size; i++)
577 5e30b196 Leszek Koltunski
          {
578 bdcb662f Leszek Koltunski
          if (table.contains(i))
579 f079bf77 Leszek Koltunski
            {
580
            if ((num % 10) == 0) sb.append("\n");
581
            num++;
582
            sb.append(i);
583
            sb.append(' ');
584
            }
585 5e30b196 Leszek Koltunski
          }
586 3798a303 Leszek Koltunski
587 f079bf77 Leszek Koltunski
        android.util.Log.e("D", "numbers: " + sb);
588
        }
589 5e30b196 Leszek Koltunski
      }
590 2d697abd Leszek Koltunski
591
///////////////////////////////////////////////////////////////////////////////////////////////////
592
593
    private void printQuats(int[] quats)
594
      {
595
      StringBuilder sb = new StringBuilder();
596
      for(int q : quats )
597
        {
598
        sb.append(' ');
599
        sb.append(q);
600
        }
601
      android.util.Log.e("D", "quats: "+sb);
602
      }
603
604
///////////////////////////////////////////////////////////////////////////////////////////////////
605
606
    public void test()
607
      {
608
      int[] q1 = {1,1,1,0,1,0,0,0, 1,0,1,0,1,0 };
609
      int index1 = getIndex(q1);
610
      android.util.Log.e("D", "index1: "+index1);
611
612
      int[] q2 = getQuats(index1);
613
      printQuats(q2);
614
/*
615
      int[] q2 = {0,0,3,0,4,0,0,0, 0,0,0,0,0,0 };
616
      int index2 = getIndex(q2);
617
      android.util.Log.e("D", "index2: "+index2);
618
619
 */
620
      }
621 a110ebe1 Leszek Koltunski
}