Project

General

Profile

« Previous | Next » 

Revision c0266cb1

Added by Leszek Koltunski about 1 year ago

Tablebase-based scrambling.

View differences:

src/main/java/org/distorted/objectlib/effects/scramble/ScrambleEffect.java
95 95
    for(int scramble=0; scramble<mNumScramblesLeft; scramble++)
96 96
      {
97 97
      mObject.randomizeNewScramble(mScrambles, mRnd, scramble, numScrambles);
98
      axis  = mScrambles[scramble][0];
99
      row   = mScrambles[scramble][1];
100
      angle = mScrambles[scramble][2];
98
      int[] s = mScrambles[scramble];
99
      axis  = s[0];
100
      row   = s[1];
101
      angle = s[2];
101 102
      absAngle = (angle<0 ? -angle : angle);
102 103
      basicDegrees = 360/mBasicAngle[axis][row];
103 104
      totalDegrees += absAngle*basicDegrees;
104 105
      }
105 106

  
107
    // tablebase scrambling can return a scramble which is shorter than requested,
108
    // padding the end with three 0s. Take note of that.
109
    for(int scramble=0; scramble<mNumScramblesLeft; scramble++)
110
      {
111
      int[] s = mScrambles[scramble];
112
      if( s[0]==0 && s[1]==0 && s[2]==0 ) mNumScramblesLeft = scramble;
113
      }
114

  
106 115
    mDurationPerDegree = duration/totalDegrees;
107 116
    mNumScrambles = 0;
108 117

  
src/main/java/org/distorted/objectlib/helpers/QuatGroupGenerator.java
161 161
      table[i] = new Static4D(mTable[i]);
162 162
      }
163 163

  
164
    if( mInserted> ObjectControl.MAX_QUATS )
165
      {
166
      android.util.Log.e("D", "ERROR! too large quat group="+mInserted);
167
      }
168

  
169 164
    return table;
170 165
    }
171 166

  
src/main/java/org/distorted/objectlib/main/InitAssets.java
9 9

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

  
12
import android.content.res.Resources;
13

  
12 14
import java.io.IOException;
13 15
import java.io.InputStream;
14 16

  
......
16 18

  
17 19
public class InitAssets
18 20
  {
19
  InputStream mJsonStream;
20
  InputStream mMeshStream;
21
  private final InputStream mJsonStream;
22
  private final InputStream mMeshStream;
23
  private final Resources mRes;
21 24

  
22 25
///////////////////////////////////////////////////////////////////////////////////////////////////
23 26

  
24
  public InitAssets(InputStream jsonStream, InputStream meshStream)
27
  public InitAssets(InputStream jsonStream, InputStream meshStream, Resources res)
25 28
    {
26 29
    mJsonStream = jsonStream;
27 30
    mMeshStream = meshStream;
31
    mRes = res;
28 32
    }
29 33

  
30 34
///////////////////////////////////////////////////////////////////////////////////////////////////
......
48 52
    return mMeshStream;
49 53
    }
50 54

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

  
57
  public Resources getResources()
58
    {
59
    return mRes;
60
    }
61

  
51 62
///////////////////////////////////////////////////////////////////////////////////////////////////
52 63

  
53 64
  public void close()
src/main/java/org/distorted/objectlib/main/ObjectType.java
44 44
  MORP_3 ( TwistyMorphix.class        , 17, R.drawable.morp_3, true ,   60, new InitData(new int[] {3,3,3})),
45 45
  MORP_4 ( TwistyMorphix.class        , 24, R.drawable.morp_4, true ,   70, new InitData(new int[] {4,4,4})),
46 46
  JING_2 ( TwistyJing.class           , 11, R.drawable.jing_2, true,    50, new InitData(new int[] {2,2,2,2})),
47
  PYRA_3 ( TwistyPyraminx.class       , 10, R.drawable.pyra_3, true,     0, new InitData(new int[] {3,3,3,3})),
47
  PYRA_3 ( TwistyPyraminx.class       , 11, R.drawable.pyra_3, true,     0, new InitData(new int[] {3,3,3,3})),
48 48

  
49 49
  PYRA_4 ( TwistyPyraminx.class       , 17, R.drawable.pyra_4, true,    50, new InitData(new int[] {4,4,4,4})),
50 50
  PYRA_5 ( TwistyPyraminx.class       , 23, R.drawable.pyra_5, true,    70, new InitData(new int[] {5,5,5,5})),
src/main/java/org/distorted/objectlib/main/TwistyObject.java
15 15
import java.util.Random;
16 16

  
17 17
import android.content.SharedPreferences;
18
import android.content.res.Resources;
18 19
import android.graphics.Bitmap;
19 20
import android.graphics.Canvas;
20 21
import android.graphics.Paint;
......
53 54
import org.distorted.objectlib.scrambling.ObjectScrambler;
54 55
import org.distorted.objectlib.json.JsonReader;
55 56
import org.distorted.objectlib.scrambling.ScrambleEdgeGenerator;
57
import org.distorted.objectlib.tablebases.ImplementedTablebasesList;
58
import org.distorted.objectlib.tablebases.TablebasesAbstract;
56 59
import org.distorted.objectlib.touchcontrol.*;
57 60

  
58 61
import static org.distorted.objectlib.touchcontrol.TouchControl.*;
......
158 161

  
159 162
///////////////////////////////////////////////////////////////////////////////////////////////////
160 163

  
161
  TwistyObject(int meshState, int iconMode, Static4D quat, Static3D move, float scale, InitAssets assets)
164
  TwistyObject(int meshState, int iconMode, Static4D quat, Static3D move, float scale, InitAssets asset)
162 165
    {
163 166
    try
164 167
      {
165
      InputStream jsonStream = assets!=null ? assets.getJsonStream(): null;
166
      InputStream meshStream = assets!=null ? assets.getMeshStream(): null;
168
      InputStream jsonStream = asset!=null ? asset.getJsonStream(): null;
167 169
      JsonReader reader = new JsonReader();
168 170
      reader.parseJsonFile(jsonStream);
169 171
      setReader(reader);
170 172
      mNumLayers = reader.getNumLayers();
171 173
      mSize      = reader.getSize();
172 174
      mInitData  = null;
173
      initialize(meshState,iconMode,quat,move,scale,meshStream,true);
174
      if( assets!=null ) assets.close();
175
      initialize(meshState,iconMode,quat,move,scale,asset,true);
176
      if( asset!=null ) asset.close();
175 177
      mError = false;
176 178
      mErrorString=null;
177 179
      }
......
184 186

  
185 187
///////////////////////////////////////////////////////////////////////////////////////////////////
186 188

  
187
  public TwistyObject(int meshState, int iconMode, float size, Static4D quat, Static3D move, float scale, InitData data, InitAssets assets)
189
  public TwistyObject(int meshState, int iconMode, float size, Static4D quat, Static3D move, float scale, InitData data, InitAssets asset)
188 190
    {
189 191
    mNumLayers = data.getNumLayers();
190 192
    mSize      = size;
191 193
    mInitData  = data;
192
    InputStream meshStream = assets!=null ? assets.getMeshStream() : null;
193
    initialize(meshState,iconMode,quat,move,scale,meshStream,false);
194
    if( assets!=null ) assets.close();
194
    initialize(meshState,iconMode,quat,move,scale,asset,false);
195
    if( asset!=null ) asset.close();
195 196
    mError = false;
196 197
    mErrorString = null;
197 198
    }
......
211 212

  
212 213
///////////////////////////////////////////////////////////////////////////////////////////////////
213 214

  
214
  private void initialize(int meshState, int iconMode, Static4D quat, Static3D move, float scale, InputStream meshStream, boolean fromJSON)
215
  private void initialize(int meshState, int iconMode, Static4D quat, Static3D move, float scale, InitAssets asset, boolean fromJSON)
215 216
    {
216 217
    mRotationState = STATE_NOTHING;
217 218
    mIconMode = iconMode;
......
244 245
    int[][] edges = getScrambleEdges();
245 246
    int[][] algorithms = getScrambleAlgorithms();
246 247

  
247
    mScrambler = new ObjectScrambler(scramblingType,mNumAxis,mNumLayers,algorithms,edges);
248
    Resources res = asset==null ? null : asset.getResources();
249
    TablebasesAbstract tablebase = res!=null ? getTablebase(res) : null;
250
    mScrambler = new ObjectScrambler(scramblingType,mNumAxis,mNumLayers,algorithms,edges,tablebase);
248 251

  
249 252
    boolean bandaged=false;
250 253

  
......
277 280
    MatrixEffectQuaternion quatEffect = new MatrixEffectQuaternion(mQuat, CENTER);
278 281
    MatrixEffectMove moveEffect = new MatrixEffectMove(move);
279 282

  
283
    InputStream meshStream = asset!=null ? asset.getMeshStream(): null;
280 284
    boolean fromDMESH = (meshStream!=null && meshState==MESH_NICE);
281 285
    getQuatsAndShapes(fromDMESH,fromJSON);
282 286
    createMeshAndCubits(meshStream,meshState,fromDMESH);
......
294 298
    mNode = new DistortedNode(mTexture,mEffects,mMesh);
295 299
    }
296 300

  
301
///////////////////////////////////////////////////////////////////////////////////////////////////
302

  
303
  private TablebasesAbstract getTablebase(Resources res)
304
    {
305
    ObjectSignature signature = getSignature();
306
    long[] array = signature.getArray();
307
    int len = array.length;
308
    int sig = (int)array[len-1];
309

  
310
    return ImplementedTablebasesList.createPacked(res,sig);
311
    }
312

  
297 313
///////////////////////////////////////////////////////////////////////////////////////////////////
298 314

  
299 315
  private void createQuaternionEffects()
src/main/java/org/distorted/objectlib/scrambling/ObjectScrambler.java
13 13
import java.util.Random;
14 14

  
15 15
import org.distorted.objectlib.helpers.ObjectSignature;
16
import org.distorted.objectlib.tablebases.TablebasesAbstract;
16 17

  
17 18
///////////////////////////////////////////////////////////////////////////////////////////////////
18 19

  
......
21 22
  public static final int SCRAMBLING_ALGORITHMS = 0;
22 23
  public static final int SCRAMBLING_SQUARE1    = 1;
23 24
  public static final int SCRAMBLING_BANDAGED   = 2;
24
  public static final int SCRAMBLING_TABLEBASES = 3;
25 25

  
26 26
  private final ScrambleState[] mStates;
27 27
  private final int mType;
......
56 56
  private ArrayList<ScrambleStateBandagedCuboid> mStatesHistory;
57 57
  private BlacklistedSignatures mBlacklisted;
58 58

  
59
  // type==3 (tablebases)
60
  private TablebasesAbstract mTablebase;
61

  
59 62
///////////////////////////////////////////////////////////////////////////////////////////////////
60 63

  
61
  public ObjectScrambler(int type, int numAxis, int[] numLayers, int[][] algorithms, int[][] edges)
64
  public ObjectScrambler(int type, int numAxis, int[] numLayers, int[][] algorithms, int[][] edges, TablebasesAbstract tablebase)
62 65
    {
63 66
    mType       = type;
64 67
    mNumAxis    = numAxis;
......
84 87
      mCornerQuat = new int[8];
85 88
      mLastRot = LAST_SL;
86 89
      }
90

  
91
    mTablebase = tablebase;
87 92
    }
88 93

  
89 94
///////////////////////////////////////////////////////////////////////////////////////////////////
......
615 620
    if( curr==0 ) initializeType2Scrambling(scramble,rnd,total,signature);
616 621
    }
617 622

  
618
///////////////////////////////////////////////////////////////////////////////////////////////////
619
// TYPE 3   (tablebases)
620

  
621
  private void randomizeNewScramble3(int[][] scramble, Random rnd, int curr, int total, ObjectSignature signature)
622
    {
623
    // TODO
624
    }
625

  
626 623
///////////////////////////////////////////////////////////////////////////////////////////////////
627 624
// PUBLIC API
628 625

  
629 626
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total, ObjectSignature signature)
630 627
    {
631
    switch(mType)
628
    if( mTablebase!=null )
629
      {
630
      if( curr==0 ) mTablebase.scramble(rnd,total,scramble);
631
      }
632
    else
632 633
      {
633
      case SCRAMBLING_ALGORITHMS: randomizeNewScramble0(scramble, rnd, curr); break;
634
      case SCRAMBLING_SQUARE1   : randomizeNewScramble1(scramble, rnd, curr); break;
635
      case SCRAMBLING_BANDAGED  : randomizeNewScramble2(scramble, rnd, curr, total, signature); break;
636
      case SCRAMBLING_TABLEBASES: randomizeNewScramble3(scramble, rnd, curr, total, signature); break;
634
      switch(mType)
635
        {
636
        case SCRAMBLING_ALGORITHMS: randomizeNewScramble0(scramble, rnd, curr); break;
637
        case SCRAMBLING_SQUARE1   : randomizeNewScramble1(scramble, rnd, curr); break;
638
        case SCRAMBLING_BANDAGED  : randomizeNewScramble2(scramble, rnd, curr, total, signature); break;
639
        }
637 640
      }
638 641
    }
639 642
  }
src/main/java/org/distorted/objectlib/tablebases/ImplementedTablebasesList.java
11 11

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

  
14
import org.distorted.objectlib.main.ObjectType;
14
import org.distorted.objectlib.main.ObjectSignatures;
15 15

  
16 16
import java.lang.reflect.Constructor;
17 17
import java.lang.reflect.InvocationTargetException;
......
20 20

  
21 21
public enum ImplementedTablebasesList
22 22
{
23
  PYRAMINX_DUO  (ObjectType.PDUO_2, TablebasesPyraminxDuo.class),
24
  IVY_CUBE      (ObjectType.IVY_2 , TablebasesIvyCube.class),
25
  CU_232        (ObjectType.CU_232, TablebasesCuboid232.class),
26
  PYRA_3        (ObjectType.PYRA_3, TablebasesPyraminx.class),
27
  DIAMOND       (ObjectType.DIAM_2, TablebasesSkewbDiamond.class),
23
  PYRAMINX_DUO  (ObjectSignatures.PDUO_2, TablebasesPyraminxDuo.class),
24
  IVY_CUBE      (ObjectSignatures.IVY_2 , TablebasesIvyCube.class),
25
  CU_232        (ObjectSignatures.CU_232, TablebasesCuboid232.class),
26
  PYRA_3        (ObjectSignatures.PYRA_3, TablebasesPyraminx.class),
27
  DIAMOND       (ObjectSignatures.DIAM_2, TablebasesSkewbDiamond.class),
28 28
  ;
29 29

  
30 30
  public static final int NUM_OBJECTS = values().length;
31 31

  
32
  private final ObjectType mType;
32
  private final int mSignature;
33 33
  private final Class<? extends TablebasesAbstract> mClass;
34 34

  
35 35
  private static final ImplementedTablebasesList[] objects;
......
47 47

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

  
50
  public static boolean hasTablebase(ObjectType type)
50
  public static boolean hasTablebase(int signature)
51 51
    {
52 52
    for(int i=0; i<NUM_OBJECTS; i++)
53
      if( objects[i].mType == type ) return true;
53
      if( objects[i].mSignature == signature ) return true;
54 54

  
55 55
    return false;
56 56
    }
57 57

  
58 58
///////////////////////////////////////////////////////////////////////////////////////////////////
59 59

  
60
  ImplementedTablebasesList(ObjectType type, final Class<? extends TablebasesAbstract> clazz)
60
  ImplementedTablebasesList(int sig, final Class<? extends TablebasesAbstract> clazz)
61 61
    {
62
    mType = type;
62
    mSignature = sig;
63 63
    mClass= clazz;
64 64
    }
65 65

  
66 66
///////////////////////////////////////////////////////////////////////////////////////////////////
67 67

  
68
  public ObjectType getType()
68
  public int getSignature()
69 69
    {
70
    return mType;
70
    return mSignature;
71 71
    }
72 72

  
73 73
///////////////////////////////////////////////////////////////////////////////////////////////////
74 74

  
75
  public static TablebasesAbstract createPacked(Resources res, ObjectType type)
75
  public static TablebasesAbstract createPacked(Resources res, int signature)
76 76
    {
77 77
    Class<? extends TablebasesAbstract> clazz=null;
78 78

  
79 79
    for(int i=0; i<NUM_OBJECTS; i++)
80
      if( objects[i].mType == type )
80
      if( objects[i].mSignature == signature )
81 81
        {
82 82
        clazz = objects[i].mClass;
83 83
        break;
......
117 117

  
118 118
///////////////////////////////////////////////////////////////////////////////////////////////////
119 119

  
120
  public static TablebasesAbstract createUnpacked(ObjectType type)
120
  public static TablebasesAbstract createUnpacked(int signatures)
121 121
    {
122 122
    Class<? extends TablebasesAbstract> clazz=null;
123 123

  
124 124
    for(int i=0; i<NUM_OBJECTS; i++)
125
      if( objects[i].mType == type )
125
      if( objects[i].mSignature == signatures )
126 126
        {
127 127
        clazz = objects[i].mClass;
128 128
        break;
src/main/java/org/distorted/objectlib/tablebases/TablebasesAbstract.java
27 27
public abstract class TablebasesAbstract
28 28
{
29 29
  private final Static3D[] mAxis;
30
  private final int mSize;
30
  private final int mSize, mMinScramble;
31 31
  private final int[][] mAngles;
32 32
  private final int mNumAxis;
33 33
  private final int[] mNumLayers;
......
56 56

  
57 57
  abstract boolean[][] getRotatable();
58 58

  
59
  abstract int getMinScramble();
59 60
  abstract int getSize();
60 61
  abstract int[] getQuats(int index);
61 62
  abstract int getIndex(int[] quats);
......
65 66
  public TablebasesAbstract()
66 67
    {
67 68
    mSize = getSize();
69
    mMinScramble = getMinScramble();
68 70
    mAngles = getBasicAngles();
69 71
    mAxis = getRotationAxis();
70 72
    mNumAxis = mAxis.length;
......
122 124
      }
123 125
    }
124 126

  
127
///////////////////////////////////////////////////////////////////////////////////////////////////
128

  
129
  private int computeRowFromBitmap(int rowBitmap)
130
    {
131
    int index = 0;
132

  
133
    while(index<32)
134
      {
135
      if( (rowBitmap&0x1) != 0 ) return index;
136
      rowBitmap>>=1;
137
      index++;
138
      }
139
    return 0;
140
    }
141

  
125 142
///////////////////////////////////////////////////////////////////////////////////////////////////
126 143

  
127 144
  private int computeRow(float[] pos, int quat, int axisIndex)
......
323 340
    moves.add(move);
324 341
    }
325 342

  
326
///////////////////////////////////////////////////////////////////////////////////////////////////
327

  
328
  private void addMove(int[] moves, int axis, int layer, int angle)
329
    {
330
    int maxAngle = mAngles[axis][layer];
331
    angle = maxAngle-angle;
332
    if( angle> 0.5f*maxAngle ) angle -= maxAngle;
333

  
334
    moves[0] = axis;
335
    moves[1] = (1<<layer);
336
    moves[2] = angle;
337
    }
338

  
339 343
///////////////////////////////////////////////////////////////////////////////////////////////////
340 344

  
341 345
  private int[][] convertMoves(ArrayList<int[]> moves)
......
446 450

  
447 451
///////////////////////////////////////////////////////////////////////////////////////////////////
448 452

  
449
  public int[][] scramble(Random rnd, int depth)
453
  public void scramble(Random rnd, int depth, int[][] scramble)
450 454
    {
451
    if( !mInitialized ) return null;
455
    if( !mInitialized ) return;
452 456

  
453
    int[] data = new int[4];
454
    int level=0;
455
    int[][] moves = new int[depth][3];
456
    int[] quats = getQuats(0);
457
    int numQuats = quats.length;
458
    int[] tmpQuats = new int[numQuats];
457
    int solDepth = 0;
458
    int scraLen = scramble.length;
459
    if( depth>mMinScramble ) depth = mMinScramble;
459 460

  
460
    while(level<depth)
461
    while( solDepth<depth )
461 462
      {
462
      boolean found = false;
463

  
464
      data[0]=0;
465
      data[1]=0;
466
      data[2]=1;
467
      data[3]=1;
468

  
469
      int random = rnd.nextInt(mScalingFactor);
470
      for(int i=0; i<random; i++) getNextAxisLayerAngleQuat(data);
471

  
472
      for(int ax=0; ax<mNumAxis; ax++)
473
        for(int cubit=0; cubit<mNumCubits; cubit++)
474
          mRotRow[cubit][ax] = computeRow(mPosition[cubit],quats[cubit],ax);
463
      int randomPosition = rnd.nextInt(mSize-1);
464
      int[][] sol = solution(randomPosition);
465
      solDepth = sol.length;
475 466

  
476
      for(int s=0; s<mScalingFactor && !found; s++)
467
      if( solDepth>=depth )
477 468
        {
478
        int ax    = data[0];
479
        int layer = data[1];
480
        int angle = data[2];
481
        int quat  = data[3];
469
        int num = Math.min(scraLen,solDepth);
482 470

  
483
        if( mRotatable[ax][layer] )
471
        for(int i=0; i<num; i++)
484 472
          {
485
          int bitLayer = (1<<layer);
486
          System.arraycopy(quats, 0, tmpQuats, 0, numQuats);
487

  
488
          for(int cubit=0; cubit<mNumCubits; cubit++)
489
            if( mRotRow[cubit][ax]==bitLayer )
490
              {
491
              int currQuat = tmpQuats[cubit];
492
              int newQuat = getMultQuat(quat,currQuat);
493
              tmpQuats[cubit] = newQuat;
494
              }
495

  
496
          int childIndex = getIndex(tmpQuats);
497
          byte newLevel = mTablebase.retrievePacked(childIndex);
498

  
499
          if( ((newLevel-level-1)%3) == 0 )
500
            {
501
            addMove(moves[level],ax,layer,angle);
502
            level++;
503
            quats = getQuats(childIndex);
504
            found = true;
505
            }
473
          int[] source = sol[solDepth-1-i];
474
          scramble[i][0] = source[0];
475
          scramble[i][1] = computeRowFromBitmap(source[1]);
476
          scramble[i][2] =-source[2];
506 477
          }
507

  
508
        getNextAxisLayerAngleQuat(data);
509
        }
510

  
511
      if( !found )
512
        {
513
        android.util.Log.e("D", "scramble error: no move found!");
514
        return null;
515 478
        }
516 479
      }
517

  
518
    return moves;
519 480
    }
520 481

  
521 482
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objectlib/tablebases/TablebasesCuboid232.java
110 110
    return 241920;
111 111
    }
112 112

  
113
///////////////////////////////////////////////////////////////////////////////////////////////////
114

  
115
 int getMinScramble()
116
    {
117
    return 12;
118
    }
119

  
113 120
///////////////////////////////////////////////////////////////////////////////////////////////////
114 121

  
115 122
  private void getCornerQuats(int[] output, int[] perm)
src/main/java/org/distorted/objectlib/tablebases/TablebasesIvyCube.java
112 112
    return (3*3*3*3)*(6*5*4*3);
113 113
    }
114 114

  
115
///////////////////////////////////////////////////////////////////////////////////////////////////
116

  
117
 int getMinScramble()
118
    {
119
    return 7;
120
    }
121

  
115 122
///////////////////////////////////////////////////////////////////////////////////////////////////
116 123

  
117 124
  private int findFirst(int[] table, int value)
src/main/java/org/distorted/objectlib/tablebases/TablebasesPyraminx.java
112 112
    return 933120;  // see https://www.jaapsch.net/puzzles/pyraminx.htm
113 113
    }
114 114

  
115
///////////////////////////////////////////////////////////////////////////////////////////////////
116

  
117
 int getMinScramble()
118
    {
119
    return 9;
120
    }
121

  
115 122
///////////////////////////////////////////////////////////////////////////////////////////////////
116 123

  
117 124
  public static void getEdgePermutation(int[] output, int[] quats, int index)
src/main/java/org/distorted/objectlib/tablebases/TablebasesPyraminxDuo.java
99 99
    return 324;  // see https://www.jaapsch.net/puzzles/pyraduo.htm
100 100
    }
101 101

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

  
104
 int getMinScramble()
105
    {
106
    return 4;
107
    }
108

  
102 109
///////////////////////////////////////////////////////////////////////////////////////////////////
103 110

  
104 111
  int[] getQuats(int index)
src/main/java/org/distorted/objectlib/tablebases/TablebasesSkewbDiamond.java
124 124
    return 138240;  // see https://www.jaapsch.net/puzzles/diamond.htm
125 125
    }
126 126

  
127
///////////////////////////////////////////////////////////////////////////////////////////////////
128

  
129
 int getMinScramble()
130
    {
131
    return 8;
132
    }
133

  
127 134
///////////////////////////////////////////////////////////////////////////////////////////////////
128 135

  
129 136
  private int computeCenterQuat(int originalLocation, int newLocation)

Also available in: Unified diff