Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / scrambling / ObjectScrambler.java @ 1d581993

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2021 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.objectlib.scrambling;
21

    
22
import java.util.ArrayList;
23
import java.util.Random;
24

    
25
import org.distorted.objectlib.helpers.ObjectSignature;
26

    
27
///////////////////////////////////////////////////////////////////////////////////////////////////
28

    
29
public class ObjectScrambler
30
  {
31
  private final ScrambleState[] mStates;
32
  private final int mType;
33
  private final int mNumAxis;
34
  private final int[] mNumLayers;
35

    
36
  // type=0, i.e. main
37
  private int mCurrState;
38
  private int mIndexExcluded;
39
  private int[][] mScrambleTable;
40
  private int[] mNumOccurences;
41

    
42
  // type=1, i.e. the exception: Square-1
43
  private static final int BASIC_ANGLE = 12;
44
  private static final int LAST_SL = 0; // automatic rotations: last rot was a 'slash' i.e. along ROT_AXIS[1]
45
  private static final int LAST_UP = 1; // last rot was along ROT_AXIS[0], upper layer and forelast was a slash
46
  private static final int LAST_LO = 2; // last rot was along ROT_AXIS[0], lower layer and forelast was a slash
47
  private static final int LAST_UL = 3; // two last rots were along ROT_AXIS[0] (so the next must be a slash)
48

    
49
  private int[][] mPermittedAngles;
50
  private int[] mCornerQuat;
51
  private int mPermittedUp, mPermittedDo;
52
  private int[][] mBadCornerQuats;
53
  private int mLastRot;
54
  private int[][] mQuatMult;
55

    
56
  // type=2 , i.e. locally created bandaged cuboids
57
  private static ObjectSignature mSignature;
58
  private ArrayList<ScrambleStateBandagedCuboid> mBandagedStates;
59
  private int[] mSize, mTurns;
60

    
61
///////////////////////////////////////////////////////////////////////////////////////////////////
62

    
63
  public ObjectScrambler(int type, int numAxis, int[] numLayers, ScrambleState[] states)
64
    {
65
    mType = type;
66
    mNumAxis = numAxis;
67
    mNumLayers = numLayers;
68
    mStates = states;
69

    
70
    if( mType==1 )
71
      {
72
      mPermittedAngles = new int[2][BASIC_ANGLE];
73
      mCornerQuat = new int[8];
74
      mLastRot = LAST_SL;
75
      }
76
    if( mType==2 )
77
      {
78
      mSize = new int[3];
79
      mTurns= new int[3];
80

    
81
      mSize[0] = (mNumLayers[0]>1 ? mNumLayers[0] : 0);
82
      mSize[1] = (mNumLayers[1]>1 ? mNumLayers[1] : 0);
83
      mSize[2] = (mNumLayers[2]>1 ? mNumLayers[2] : 0);
84

    
85
      mTurns[0] = mNumLayers[1]==mNumLayers[2] ? 3:1;
86
      mTurns[1] = mNumLayers[0]==mNumLayers[2] ? 3:1;
87
      mTurns[2] = mNumLayers[0]==mNumLayers[1] ? 3:1;
88
      }
89
    }
90

    
91
///////////////////////////////////////////////////////////////////////////////////////////////////
92

    
93
  private void initializeScrambling()
94
    {
95
    if( mScrambleTable ==null )
96
      {
97
      mScrambleTable = new int[mNumAxis][];
98
      }
99
    if( mNumOccurences ==null )
100
      {
101
      int max=0;
102

    
103
      for (ScrambleState mState : mStates)
104
        {
105
        int tmp = mState.getTotal(-1);
106
        if (max < tmp) max = tmp;
107
        }
108

    
109
      mNumOccurences = new int[max];
110
      }
111

    
112
    for(int i=0; i<mNumAxis; i++)
113
      {
114
      int len = mNumLayers[i];
115
      mScrambleTable[i] = new int[len];
116
      for(int j=0; j<len; j++) mScrambleTable[i][j] = 0;
117
      }
118
    }
119

    
120
///////////////////////////////////////////////////////////////////////////////////////////////////
121
// PUBLIC API
122

    
123
  private void randomizeNewScramble0(int[][] scramble, Random rnd, int curr, int total)
124
    {
125
    if( curr==0 )
126
      {
127
      mCurrState     = 0;
128
      mIndexExcluded =-1;
129
      initializeScrambling();
130
      }
131

    
132
    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
133

    
134
    scramble[curr][0] = info[0];
135
    scramble[curr][1] = info[1];
136
    scramble[curr][2] = info[2];
137

    
138
    mCurrState     = info[3];
139
    mIndexExcluded = info[0];
140
    }
141

    
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143
// TYPE 1
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145
// QUATS[i]*QUATS[j] = QUATS[QUAT_MULT[i][j]]
146
///////////////////////////////////////////////////////////////////////////////////////////////////
147

    
148
  void initializeQuatMult()
149
    {
150
    mQuatMult = new int[][]
151
      {
152
        {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,},
153
        {  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,  0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 12,},
154
        {  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,  0,  1, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 12, 13,},
155
        {  3,  4,  5,  6,  7,  8,  9, 10, 11,  0,  1,  2, 15, 16, 17, 18, 19, 20, 21, 22, 23, 12, 13, 14,},
156
        {  4,  5,  6,  7,  8,  9, 10, 11,  0,  1,  2,  3, 16, 17, 18, 19, 20, 21, 22, 23, 12, 13, 14, 15,},
157
        {  5,  6,  7,  8,  9, 10, 11,  0,  1,  2,  3,  4, 17, 18, 19, 20, 21, 22, 23, 12, 13, 14, 15, 16,},
158
        {  6,  7,  8,  9, 10, 11,  0,  1,  2,  3,  4,  5, 18, 19, 20, 21, 22, 23, 12, 13, 14, 15, 16, 17,},
159
        {  7,  8,  9, 10, 11,  0,  1,  2,  3,  4,  5,  6, 19, 20, 21, 22, 23, 12, 13, 14, 15, 16, 17, 18,},
160
        {  8,  9, 10, 11,  0,  1,  2,  3,  4,  5,  6,  7, 20, 21, 22, 23, 12, 13, 14, 15, 16, 17, 18, 19,},
161
        {  9, 10, 11,  0,  1,  2,  3,  4,  5,  6,  7,  8, 21, 22, 23, 12, 13, 14, 15, 16, 17, 18, 19, 20,},
162
        { 10, 11,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 22, 23, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,},
163
        { 11,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 23, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,},
164
        { 12, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13,  0, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,},
165
        { 13, 12, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14,  1,  0, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,},
166
        { 14, 13, 12, 23, 22, 21, 20, 19, 18, 17, 16, 15,  2,  1,  0, 11, 10,  9,  8,  7,  6,  5,  4,  3,},
167
        { 15, 14, 13, 12, 23, 22, 21, 20, 19, 18, 17, 16,  3,  2,  1,  0, 11, 10,  9,  8,  7,  6,  5,  4,},
168
        { 16, 15, 14, 13, 12, 23, 22, 21, 20, 19, 18, 17,  4,  3,  2,  1,  0, 11, 10,  9,  8,  7,  6,  5,},
169
        { 17, 16, 15, 14, 13, 12, 23, 22, 21, 20, 19, 18,  5,  4,  3,  2,  1,  0, 11, 10,  9,  8,  7,  6,},
170
        { 18, 17, 16, 15, 14, 13, 12, 23, 22, 21, 20, 19,  6,  5,  4,  3,  2,  1,  0, 11, 10,  9,  8,  7,},
171
        { 19, 18, 17, 16, 15, 14, 13, 12, 23, 22, 21, 20,  7,  6,  5,  4,  3,  2,  1,  0, 11, 10,  9,  8,},
172
        { 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 22, 21,  8,  7,  6,  5,  4,  3,  2,  1,  0, 11, 10,  9,},
173
        { 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 22,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0, 11, 10,},
174
        { 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0, 11,},
175
        { 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0,}
176
      };
177
    }
178

    
179
///////////////////////////////////////////////////////////////////////////////////////////////////
180
// TYPE 1
181

    
182
  private boolean cornerIsUp(int index)
183
    {
184
    return ((index<4) ^ (mCornerQuat[index]>=12));
185
    }
186

    
187
///////////////////////////////////////////////////////////////////////////////////////////////////
188
// TYPE 1
189

    
190
  private boolean cornerIsLeft(int index)
191
    {
192
    int q = mCornerQuat[index];
193

    
194
    switch(index)
195
      {
196
      case 0:
197
      case 4: return ((q>=3 && q<= 7) || (q>=18 && q<=22));
198
      case 1:
199
      case 5: return ((q>=6 && q<=10) || (q>=15 && q<=19));
200
      case 2:
201
      case 6: return ((q==0 || q==1 || (q>=9 && q<=11)) || (q>=12 && q<=16));
202
      case 3:
203
      case 7: return ((q>=0 && q<=4) || (q==12 || q==13 || (q>=21 && q<=23)));
204
      }
205

    
206
    return false;
207
    }
208

    
209
///////////////////////////////////////////////////////////////////////////////////////////////////
210
// TYPE 1
211

    
212
  private boolean quatIsBad(int quatIndex, int corner)
213
    {
214
    if( mBadCornerQuats ==null )
215
      {
216
      // quat indices that make corner cubits bandage the puzzle.
217
      mBadCornerQuats = new int[][] { { 2, 8,17,23}, { 5,11,14,20} };
218
      }
219

    
220
    int index = (corner%2);
221

    
222
    return ( quatIndex== mBadCornerQuats[index][0] ||
223
             quatIndex== mBadCornerQuats[index][1] ||
224
             quatIndex== mBadCornerQuats[index][2] ||
225
             quatIndex== mBadCornerQuats[index][3]  );
226
    }
227

    
228
///////////////////////////////////////////////////////////////////////////////////////////////////
229
// TYPE 1
230

    
231
  private boolean isPermittedDo(int angle)
232
    {
233
    if( mQuatMult==null ) initializeQuatMult();
234

    
235
    for(int corner=0; corner<8; corner++)
236
      {
237
      if( !cornerIsUp(corner) )
238
        {
239
        int currQuat = mCornerQuat[corner];
240
        int finalQuat= mQuatMult[angle][currQuat];
241
        if( quatIsBad(finalQuat,corner) ) return false;
242
        }
243
      }
244

    
245
    return true;
246
    }
247

    
248
///////////////////////////////////////////////////////////////////////////////////////////////////
249
// TYPE 1
250

    
251
  private boolean isPermittedUp(int angle)
252
    {
253
    if( mQuatMult==null ) initializeQuatMult();
254

    
255
    for(int corner=0; corner<8; corner++)
256
      {
257
      if( cornerIsUp(corner) )
258
        {
259
        int currQuat = mCornerQuat[corner];
260
        int finalQuat= mQuatMult[angle][currQuat];
261
        if( quatIsBad(finalQuat,corner) ) return false;
262
        }
263
      }
264

    
265
    return true;
266
    }
267

    
268
///////////////////////////////////////////////////////////////////////////////////////////////////
269
// TYPE 1
270

    
271
  private void computePermittedAngles()
272
    {
273
    mPermittedDo = 0;
274

    
275
    for(int angle=0; angle<BASIC_ANGLE; angle++)
276
      {
277
      if( isPermittedDo(angle ) ) mPermittedAngles[0][mPermittedDo++] = angle;
278
      }
279

    
280
    mPermittedUp = 0;
281

    
282
    for(int angle=0; angle<BASIC_ANGLE; angle++)
283
      {
284
      if( isPermittedUp(angle ) ) mPermittedAngles[1][mPermittedUp++] = angle;
285
      }
286
    }
287

    
288
///////////////////////////////////////////////////////////////////////////////////////////////////
289
// TYPE 1
290

    
291
  private int getNextAngle(Random rnd, int layer)
292
    {
293
    int num = layer==0 ? mPermittedDo:mPermittedUp;
294
    int index = rnd.nextInt(num);
295
    int angle = mPermittedAngles[layer][index];
296
    return angle<BASIC_ANGLE/2 ? -angle : BASIC_ANGLE-angle;
297
    }
298

    
299
///////////////////////////////////////////////////////////////////////////////////////////////////
300
// TYPE 1
301

    
302
  private int getNextAngleNotZero(Random rnd, int layer)
303
    {
304
    int num = layer==0 ? mPermittedDo:mPermittedUp;
305
    int index = rnd.nextInt(num-1);
306
    int angle = mPermittedAngles[layer][index+1];
307
    return angle<BASIC_ANGLE/2 ? -angle : BASIC_ANGLE-angle;
308
    }
309

    
310
///////////////////////////////////////////////////////////////////////////////////////////////////
311
// TYPE 1
312

    
313
  private int makeQuat(int axis,int index)
314
    {
315
    if( axis==1 ) return 13;
316
    if( index<0 ) index+=12;
317
    return index;
318
    }
319

    
320
///////////////////////////////////////////////////////////////////////////////////////////////////
321
// TYPE 1
322

    
323
  private boolean cornerBelongs(int index, int axis, int layer)
324
    {
325
    if( axis==0 )
326
      {
327
      boolean up = cornerIsUp(index);
328
      return ((up && layer==2) || (!up && layer==0));
329
      }
330
    else
331
      {
332
      boolean le = cornerIsLeft(index);
333
      return ((le && layer==0) || (!le && layer==1));
334
      }
335
    }
336

    
337
///////////////////////////////////////////////////////////////////////////////////////////////////
338
// TYPE 1
339

    
340
  private void updateCornerQuats(int[] rotInfo)
341
    {
342
    if( mQuatMult==null ) initializeQuatMult();
343

    
344
    int axis = rotInfo[0];
345
    int layer= rotInfo[1];
346
    int index=-rotInfo[2];
347

    
348
    int quat = makeQuat(axis,index);
349

    
350
    for(int corner=0; corner<8; corner++)
351
      {
352
      if( cornerBelongs(corner,axis,layer) )
353
        {
354
        int curr = mCornerQuat[corner];
355
        mCornerQuat[corner] = mQuatMult[quat][curr];
356
        }
357
      }
358
    }
359

    
360
///////////////////////////////////////////////////////////////////////////////////////////////////
361
// TYPE 1
362

    
363
  private void randomizeNewScramble1(int[][] scramble, Random rnd, int curr, int total)
364
    {
365
    int layer, nextAngle;
366

    
367
    if( curr==0 )
368
      {
369
      for(int corner=0; corner<8; corner++) mCornerQuat[corner] = 0;
370
      mLastRot = rnd.nextInt(4);
371
      computePermittedAngles();
372
      }
373

    
374
    switch(mLastRot)
375
      {
376
      case LAST_SL: layer = rnd.nextInt(2);
377
                    nextAngle = getNextAngle(rnd,layer);
378

    
379
                    if( nextAngle==0 )
380
                      {
381
                      layer = 1-layer;
382
                      nextAngle = getNextAngleNotZero(rnd,layer);
383
                      }
384

    
385
                    scramble[curr][0] = 0;
386
                    scramble[curr][1] = 2*layer;
387
                    scramble[curr][2] = nextAngle;
388
                    mLastRot = layer==0 ? LAST_LO : LAST_UP;
389
                    updateCornerQuats(scramble[curr]);
390
                    break;
391
      case LAST_LO:
392
      case LAST_UP: layer = mLastRot==LAST_LO ? 1:0;
393
                    nextAngle = getNextAngle(rnd,layer);
394

    
395
                    if( nextAngle!=0 )
396
                      {
397
                      scramble[curr][0] = 0;
398
                      scramble[curr][1] = 2*layer;
399
                      scramble[curr][2] = nextAngle;
400
                      updateCornerQuats(scramble[curr]);
401
                      mLastRot = LAST_UL;
402
                      }
403
                    else
404
                      {
405
                      scramble[curr][0] = 1;
406
                      scramble[curr][1] = rnd.nextInt(2);
407
                      scramble[curr][2] = 1;
408
                      mLastRot = LAST_SL;
409
                      updateCornerQuats(scramble[curr]);
410
                      computePermittedAngles();
411
                      }
412

    
413
                    break;
414
      case LAST_UL: scramble[curr][0] = 1;
415
                    scramble[curr][1] = rnd.nextInt(2);
416
                    scramble[curr][2] = 1;
417
                    mLastRot = LAST_SL;
418
                    updateCornerQuats(scramble[curr]);
419
                    computePermittedAngles();
420
                    break;
421
      }
422
    }
423

    
424
///////////////////////////////////////////////////////////////////////////////////////////////////
425
// TYPE 2
426

    
427
  private void fillOutScramble(int[] scramble, int moveIndex)
428
    {
429
    for(int axis=0; axis<3; axis++)
430
      {
431
      int size = mTurns[axis]*mSize[axis];
432

    
433
      if( moveIndex<size )
434
        {
435
        scramble[0] = axis;
436
        scramble[1] = moveIndex/mTurns[axis];
437

    
438
        if( mTurns[axis]==3 )
439
          {
440
          switch(moveIndex%3)
441
            {
442
            case 0: scramble[2] = -1; break;
443
            case 1: scramble[2] =  2; break;
444
            case 2: scramble[2] =  1; break;
445
            }
446
          }
447
        else scramble[2] =  1;
448
        return;
449
        }
450

    
451
      moveIndex -= size;
452
      }
453

    
454
    android.util.Log.e("D", "ERROR in fillOutScramble moveIndex="+moveIndex);
455
    }
456

    
457
///////////////////////////////////////////////////////////////////////////////////////////////////
458
// TYPE 2
459

    
460
  private void buildMoveForced(int[][] scramble, Random rnd, int curr)
461
    {
462
    ScrambleStateBandagedCuboid currState = mBandagedStates.get(curr);
463
    int indexExcluded = curr>0 ? scramble[curr-1][0] : ScrambleStateBandagedCuboid.AXIS_NONE;
464
    int numMoves = currState.numMoves(indexExcluded);
465

    
466
    if( numMoves==0 )
467
      {
468
      indexExcluded = ScrambleStateBandagedCuboid.AXIS_NONE;
469
      numMoves = currState.numMoves(indexExcluded);
470
      }
471

    
472
    if( numMoves==0 )
473
      {
474
      scramble[curr][0] = 0;
475
      scramble[curr][1] = 0;
476
      scramble[curr][2] = 0;
477
      }
478
    else
479
      {
480
      int randMove = rnd.nextInt(numMoves);
481
      int moveIndex = currState.getNthMove(randMove,indexExcluded);
482
      mSignature = currState.getMove(moveIndex);
483
      fillOutScramble(scramble[curr],moveIndex);
484
      }
485

    
486
    ScrambleStateBandagedCuboid nextState = new ScrambleStateBandagedCuboid(mNumLayers[0], mNumLayers[1], mNumLayers[2], mSignature);
487
    mBandagedStates.add(nextState);
488
    }
489

    
490
///////////////////////////////////////////////////////////////////////////////////////////////////
491
// TYPE 2
492

    
493
  private boolean buildMove(int[][] scramble, Random rnd, int curr)
494
    {
495
    ScrambleStateBandagedCuboid currState = mBandagedStates.get(curr);
496
    int indexExcluded = curr>0 ? scramble[curr-1][0] : ScrambleStateBandagedCuboid.AXIS_NONE;
497
    int numMoves = currState.numMoves(indexExcluded);
498

    
499
    while( numMoves==0 )
500
      {
501
      if( curr>0 )
502
        {
503
        mBandagedStates.remove(curr);
504
        ScrambleStateBandagedCuboid prevState = mBandagedStates.get(curr-1);
505
        ObjectSignature signature = currState.getSignature();
506
        prevState.removeMoves(signature);
507
        boolean result = buildMove(scramble,rnd,curr-1);
508
        if( !result ) return false;
509
        currState = mBandagedStates.get(curr);
510
        indexExcluded = scramble[curr-1][0];
511
        numMoves = currState.numMoves(indexExcluded);
512
        }
513
      else
514
        {
515
        return false;
516
        }
517
      }
518

    
519
    int randMove = rnd.nextInt(numMoves);
520
    int moveIndex = currState.getNthMove(randMove,indexExcluded);
521
    mSignature = currState.getMove(moveIndex);
522
    fillOutScramble(scramble[curr],moveIndex);
523

    
524
    ScrambleStateBandagedCuboid nextState = new ScrambleStateBandagedCuboid(mNumLayers[0], mNumLayers[1], mNumLayers[2], mSignature);
525
    mBandagedStates.add(nextState);
526

    
527
    return true;
528
    }
529

    
530
///////////////////////////////////////////////////////////////////////////////////////////////////
531
// TYPE 2
532

    
533
  private void initializeType2Scrambling(int[][] scramble, Random rnd, int total)
534
    {
535
    if( mBandagedStates==null ) mBandagedStates = new ArrayList<>();
536
    else                        mBandagedStates.clear();
537

    
538
    ScrambleStateBandagedCuboid state = new ScrambleStateBandagedCuboid(mNumLayers[0], mNumLayers[1], mNumLayers[2], mSignature);
539
    mBandagedStates.add(state);
540
    boolean success = true;
541

    
542
    for(int curr=0; curr<total; curr++)
543
      {
544
      boolean result = buildMove(scramble,rnd,curr);
545
      if( !result )
546
        {
547
        success = false;
548
        break;
549
        }
550
      }
551

    
552
    if( !success )
553
      {
554
      mBandagedStates.clear();
555
      state = new ScrambleStateBandagedCuboid(mNumLayers[0], mNumLayers[1], mNumLayers[2], mSignature);
556
      mBandagedStates.add(state);
557

    
558
      for(int curr=0; curr<total; curr++)
559
        {
560
        buildMoveForced(scramble,rnd,curr);
561
        }
562
      }
563

    
564
for(int i=0; i<total; i++)
565
  {
566
  android.util.Log.e("D", "scramble "+i+" axis: "+scramble[i][0]+" layer="+scramble[i][1]+" angle="+scramble[i][2]);
567
  }
568
    }
569

    
570
///////////////////////////////////////////////////////////////////////////////////////////////////
571
// TYPE 2
572

    
573
  public static void setSignature(ObjectSignature signature)
574
    {
575
    mSignature = signature;
576
    }
577

    
578
///////////////////////////////////////////////////////////////////////////////////////////////////
579
// TYPE 2   (locally-created bandaged cuboids)
580

    
581
  private void randomizeNewScramble2(int[][] scramble, Random rnd, int curr, int total)
582
    {
583
    if( curr==0 ) initializeType2Scrambling(scramble,rnd,total);
584
    }
585

    
586
///////////////////////////////////////////////////////////////////////////////////////////////////
587
// PUBLIC API
588

    
589
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total)
590
    {
591
    if( mType==0 ) randomizeNewScramble0(scramble, rnd, curr, total);
592
    if( mType==1 ) randomizeNewScramble1(scramble, rnd, curr, total);
593
    if( mType==2 ) randomizeNewScramble2(scramble, rnd, curr, total);
594
    }
595
  }
(1-1/5)