Project

General

Profile

« Previous | Next » 

Revision 0e311558

Added by Leszek Koltunski over 3 years ago

Bandaged 3x3: just-in-time scrambling.

View differences:

src/main/java/org/distorted/objectlib/objects/TwistyBandagedGeneric.java
21 21

  
22 22
import org.distorted.library.type.Static3D;
23 23
import org.distorted.library.type.Static4D;
24
import org.distorted.objectlib.scrambling.ScrambleState;
24 25

  
25 26
import java.io.InputStream;
26 27

  
......
45 46
    super( new int[] {3,3,3}, MESH_NICE, iconMode, quat, new Static3D(0,0,0), scale, null);
46 47
    }
47 48

  
49
///////////////////////////////////////////////////////////////////////////////////////////////////
50
// Computing scramble states of many a bandaged 3x3 takes way too long time and too much space.
51
// Return null here and turn to construction of scramble tables just-in-time.
52

  
53
  @Override
54
  public ScrambleState[] getScrambleStates()
55
    {
56
    return null;
57
    }
58

  
59
///////////////////////////////////////////////////////////////////////////////////////////////////
60

  
61
  @Override
62
  public int getScrambleType()
63
    {
64
    return 2;
65
    }
66

  
48 67
///////////////////////////////////////////////////////////////////////////////////////////////////
49 68

  
50 69
  public static void setPositions(float[][] positions)
src/main/java/org/distorted/objectlib/objects/TwistySquare1.java
53 53

  
54 54
///////////////////////////////////////////////////////////////////////////////////////////////////
55 55

  
56
  @Override
56 57
  public ScrambleState[] getScrambleStates()
57 58
    {
58 59
    return null;
src/main/java/org/distorted/objectlib/scrambling/ObjectScrambler.java
19 19

  
20 20
package org.distorted.objectlib.scrambling;
21 21

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

  
24 25
///////////////////////////////////////////////////////////////////////////////////////////////////
......
50 51
  private int mLastRot;
51 52
  private int[][] mQuatMult;
52 53

  
54
  // type=2 , i.e. locally created bandaged 3x3s
55
  private static long mSignature;
56
  private ArrayList<ScrambleStateBandaged3x3> mBandagedStates;
57

  
53 58
///////////////////////////////////////////////////////////////////////////////////////////////////
54 59

  
55 60
  public ObjectScrambler(int type, int numAxis, int[] numLayers, ScrambleState[] states)
......
400 405
      }
401 406
    }
402 407

  
408
///////////////////////////////////////////////////////////////////////////////////////////////////
409
// TYPE 2
410

  
411
  private void buildMoveForced(int[][] scramble, Random rnd, int curr)
412
    {
413
    ScrambleStateBandaged3x3 currState = mBandagedStates.get(curr);
414
    int indexExcluded = curr>0 ? scramble[curr-1][0] : ScrambleStateBandaged3x3.AXIS_NONE;
415
    int numMoves = currState.numMoves(indexExcluded);
416

  
417
    if( numMoves==0 )
418
      {
419
      indexExcluded = ScrambleStateBandaged3x3.AXIS_NONE;
420
      numMoves = currState.numMoves(indexExcluded);
421
      }
422

  
423
    int randMove = rnd.nextInt(numMoves);
424
    int moveIndex = currState.getNthMove(randMove,indexExcluded);
425
    mSignature = currState.getMove(moveIndex);
426

  
427
    scramble[curr][0] = moveIndex/9;
428
    scramble[curr][1] = (moveIndex%9)/3;
429

  
430
    switch(moveIndex%3)
431
      {
432
      case 0: scramble[curr][2] = -1; break;
433
      case 1: scramble[curr][2] =  2; break;
434
      case 2: scramble[curr][2] =  1; break;
435
      }
436

  
437
    ScrambleStateBandaged3x3 nextState = new ScrambleStateBandaged3x3(mSignature);
438
    mBandagedStates.add(nextState);
439
    }
440

  
441
///////////////////////////////////////////////////////////////////////////////////////////////////
442
// TYPE 2
443

  
444
  private boolean buildMove(int[][] scramble, Random rnd, int curr)
445
    {
446
    ScrambleStateBandaged3x3 currState = mBandagedStates.get(curr);
447
    int indexExcluded = curr>0 ? scramble[curr-1][0] : ScrambleStateBandaged3x3.AXIS_NONE;
448
    int numMoves = currState.numMoves(indexExcluded);
449

  
450
    while( numMoves==0 )
451
      {
452
      if( curr>0 )
453
        {
454
        mBandagedStates.remove(curr);
455
        ScrambleStateBandaged3x3 prevState = mBandagedStates.get(curr-1);
456
        long signature = currState.getID();
457
        prevState.removeMoves(signature);
458
        boolean result = buildMove(scramble,rnd,curr-1);
459
        if( !result ) return false;
460
        currState = mBandagedStates.get(curr);
461
        indexExcluded = scramble[curr-1][0];
462
        numMoves = currState.numMoves(indexExcluded);
463
        }
464
      else
465
        {
466
        return false;
467
        }
468
      }
469

  
470
    int randMove = rnd.nextInt(numMoves);
471
    int moveIndex = currState.getNthMove(randMove,indexExcluded);
472
    mSignature = currState.getMove(moveIndex);
473

  
474
    scramble[curr][0] = moveIndex/9;
475
    scramble[curr][1] = (moveIndex%9)/3;
476

  
477
    switch(moveIndex%3)
478
      {
479
      case 0: scramble[curr][2] = -1; break;
480
      case 1: scramble[curr][2] =  2; break;
481
      case 2: scramble[curr][2] =  1; break;
482
      }
483

  
484
    ScrambleStateBandaged3x3 nextState = new ScrambleStateBandaged3x3(mSignature);
485
    mBandagedStates.add(nextState);
486

  
487
    return true;
488
    }
489

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

  
493
  private void initializeType2Scrambling(int[][] scramble, Random rnd, int total)
494
    {
495
    if( mBandagedStates==null ) mBandagedStates = new ArrayList<>();
496
    else                        mBandagedStates.clear();
497

  
498
    ScrambleStateBandaged3x3 state = new ScrambleStateBandaged3x3(mSignature);
499
    mBandagedStates.add(state);
500
    boolean success = true;
501

  
502
    for(int curr=0; curr<total; curr++)
503
      {
504
      boolean result = buildMove(scramble,rnd,curr);
505
      if( !result )
506
        {
507
        success = false;
508
        break;
509
        }
510
      }
511

  
512
    if( !success )
513
      {
514
      mBandagedStates.clear();
515
      state = new ScrambleStateBandaged3x3(mSignature);
516
      mBandagedStates.add(state);
517

  
518
      for(int curr=0; curr<total; curr++)
519
        {
520
        buildMoveForced(scramble,rnd,curr);
521
        }
522
      }
523
    }
524

  
525
///////////////////////////////////////////////////////////////////////////////////////////////////
526
// TYPE 2
527

  
528
  public static void setSignature(long signature)
529
    {
530
    mSignature = signature;
531
    }
532

  
533
///////////////////////////////////////////////////////////////////////////////////////////////////
534
// TYPE 2   (locally-created bandaged 3x3s)
535

  
536
  private void randomizeNewScramble2(int[][] scramble, Random rnd, int curr, int total)
537
    {
538
    if( curr==0 ) initializeType2Scrambling(scramble,rnd,total);
539
    }
540

  
403 541
///////////////////////////////////////////////////////////////////////////////////////////////////
404 542
// PUBLIC API
405 543

  
......
407 545
    {
408 546
    if( mType==0 ) randomizeNewScramble0(scramble, rnd, curr, total);
409 547
    if( mType==1 ) randomizeNewScramble1(scramble, rnd, curr, total);
548
    if( mType==2 ) randomizeNewScramble2(scramble, rnd, curr, total);
410 549
    }
411 550
  }
src/main/java/org/distorted/objectlib/scrambling/ScrambleStateBandaged3x3.java
28 28

  
29 29
public class ScrambleStateBandaged3x3
30 30
{
31
  public static final int AXIS_NONE = -1;
32
  public static final int AXIS_X = 0;
33
  public static final int AXIS_Y = 1;
34
  public static final int AXIS_Z = 2;
35

  
31 36
  private static final long INVALID_MOVE = -1;
32 37
  private static final int NUM_MOVES = 27;
33 38

  
34
  private static final int AXIS_X = 0;
35
  private static final int AXIS_Y = 1;
36
  private static final int AXIS_Z = 2;
37

  
38 39
  private static final int LAYER_L = 0;
39 40
  private static final int LAYER_M = 1;
40 41
  private static final int LAYER_R = 2;
......
45 46

  
46 47
///////////////////////////////////////////////////////////////////////////////////////////////////
47 48

  
48
  private ScrambleStateBandaged3x3(long id)
49
  public ScrambleStateBandaged3x3(long id)
49 50
    {
50 51
    mDistance = -1;
51 52
    mID = id;
......
54 55

  
55 56
///////////////////////////////////////////////////////////////////////////////////////////////////
56 57

  
57
  private long getID()
58
  public long getID()
58 59
    {
59 60
    return mID;
60 61
    }
......
68 69

  
69 70
///////////////////////////////////////////////////////////////////////////////////////////////////
70 71

  
71
  private long getMove(int index)
72
  public long getMove(int index)
72 73
    {
73 74
    return (index>=0 && index<NUM_MOVES) ? mMoves[index] : INVALID_MOVE;
74 75
    }
75 76

  
76 77
///////////////////////////////////////////////////////////////////////////////////////////////////
77 78

  
78
  private int numAxis()
79
  public int numAxis()
79 80
    {
80 81
    int num = 0;
81 82

  
......
94 95
    return num;
95 96
    }
96 97

  
98
///////////////////////////////////////////////////////////////////////////////////////////////////
99

  
100
  private int numXMoves()
101
    {
102
    int num=0;
103

  
104
    if( mMoves[ 0]!=INVALID_MOVE ) num++;
105
    if( mMoves[ 1]!=INVALID_MOVE ) num++;
106
    if( mMoves[ 2]!=INVALID_MOVE ) num++;
107
    if( mMoves[ 3]!=INVALID_MOVE ) num++;
108
    if( mMoves[ 4]!=INVALID_MOVE ) num++;
109
    if( mMoves[ 5]!=INVALID_MOVE ) num++;
110
    if( mMoves[ 6]!=INVALID_MOVE ) num++;
111
    if( mMoves[ 7]!=INVALID_MOVE ) num++;
112
    if( mMoves[ 8]!=INVALID_MOVE ) num++;
113

  
114
    return num;
115
    }
116

  
117
///////////////////////////////////////////////////////////////////////////////////////////////////
118

  
119
  private int numYMoves()
120
    {
121
    int num=0;
122

  
123
    if( mMoves[ 9]!=INVALID_MOVE ) num++;
124
    if( mMoves[10]!=INVALID_MOVE ) num++;
125
    if( mMoves[11]!=INVALID_MOVE ) num++;
126
    if( mMoves[12]!=INVALID_MOVE ) num++;
127
    if( mMoves[13]!=INVALID_MOVE ) num++;
128
    if( mMoves[14]!=INVALID_MOVE ) num++;
129
    if( mMoves[15]!=INVALID_MOVE ) num++;
130
    if( mMoves[16]!=INVALID_MOVE ) num++;
131
    if( mMoves[17]!=INVALID_MOVE ) num++;
132

  
133
    return num;
134
    }
135

  
136
///////////////////////////////////////////////////////////////////////////////////////////////////
137

  
138
  private int numZMoves()
139
    {
140
    int num=0;
141

  
142
    if( mMoves[18]!=INVALID_MOVE ) num++;
143
    if( mMoves[19]!=INVALID_MOVE ) num++;
144
    if( mMoves[20]!=INVALID_MOVE ) num++;
145
    if( mMoves[21]!=INVALID_MOVE ) num++;
146
    if( mMoves[22]!=INVALID_MOVE ) num++;
147
    if( mMoves[23]!=INVALID_MOVE ) num++;
148
    if( mMoves[24]!=INVALID_MOVE ) num++;
149
    if( mMoves[25]!=INVALID_MOVE ) num++;
150
    if( mMoves[26]!=INVALID_MOVE ) num++;
151

  
152
    return num;
153
    }
154

  
155
///////////////////////////////////////////////////////////////////////////////////////////////////
156

  
157
  public int numMoves()
158
    {
159
    return numXMoves()+numYMoves()+numZMoves();
160
    }
161

  
162
///////////////////////////////////////////////////////////////////////////////////////////////////
163

  
164
  public int numMoves(int excludedAxis)
165
    {
166
    switch(excludedAxis)
167
      {
168
      case AXIS_X: return numYMoves()+numZMoves();
169
      case AXIS_Y: return numXMoves()+numZMoves();
170
      case AXIS_Z: return numXMoves()+numYMoves();
171
      }
172

  
173
    int ret= numXMoves()+numYMoves()+numZMoves();
174

  
175
    //android.util.Log.e("D", "numMoves returning "+ret+" "+formatMoves() );
176

  
177
    return ret;
178
    }
179

  
180
///////////////////////////////////////////////////////////////////////////////////////////////////
181

  
182
  public int getNthMove(int n, int excludedAxis)
183
    {
184
    int num = 0;
185

  
186
    for(int m=0; m<NUM_MOVES; m++)
187
      {
188
      if( (m/9)!=excludedAxis && mMoves[m]!=INVALID_MOVE)
189
        {
190
        if( num==n ) return m;
191
        num++;
192
        }
193
      }
194

  
195
    return -1;
196
    }
197

  
198
///////////////////////////////////////////////////////////////////////////////////////////////////
199

  
200
  public void removeMoves(long signature)
201
    {
202
    for(int m=0; m<NUM_MOVES; m++)
203
      if( signature==mMoves[m] ) mMoves[m]=INVALID_MOVE;
204
    }
205

  
97 206
///////////////////////////////////////////////////////////////////////////////////////////////////
98 207

  
99 208
  private void setMove(int index, long newMove)
......
103 212

  
104 213
///////////////////////////////////////////////////////////////////////////////////////////////////
105 214

  
106
  private String formatMoves()
215
  public String formatMoves()
107 216
    {
108 217
    String x = getTable( 0);
109 218
    String y = getTable( 9);
110 219
    String z = getTable(18);
111 220

  
112
    return x+"  "+y+"  "+z;
221
    return mID+"\n"+x+"\n"+y+"\n"+z;
113 222
    }
114 223

  
115 224
///////////////////////////////////////////////////////////////////////////////////////////////////
......
198 307
    Map<Long,ScrambleStateBandaged3x3> graph = new LinkedHashMap<>();
199 308
    graph.put(id,bsg);
200 309

  
201
long t1 = System.currentTimeMillis();
202

  
203 310
    insertChildren(graph,id);
204

  
205
long t2 = System.currentTimeMillis();
206
android.util.Log.e("D", "inserting children: "+(t2-t1));
207

  
208
    // if there's only one single state, do not prune moves which point to itself
209
    if(graph.size()>1)
210
      {
211
      pruneGraph(graph,id);
212
      }
213

  
214
long t3 = System.currentTimeMillis();
215
android.util.Log.e("D", "pruning graph: "+(t3-t2));
216

  
311
    // if there's only one state, do not prune moves which point to itself
312
    if(graph.size()>1) pruneGraph(graph,id);
217 313
    computeDistance(graph,id,0);
218

  
219
long t4 = System.currentTimeMillis();
220
android.util.Log.e("D", "computing distance: "+(t4-t3));
221

  
222 314
    removeDisconnectedParts(graph);
223

  
224
long t5 = System.currentTimeMillis();
225
android.util.Log.e("D", "removing disconnected parts: "+(t5-t4));
226

  
227 315
    remapGraph(graph);
228 316

  
229
long t6 = System.currentTimeMillis();
230
android.util.Log.e("D", "remapping graph: "+(t6-t5));
231

  
232 317
    int num = graph.size();
233 318
    ScrambleState[] ret = new ScrambleState[num];
234 319

  
......
239 324
      ret[mid] = value.produceScrambleState();
240 325
      }
241 326

  
242
//printGraph(graph);
243

  
244
long t7 = System.currentTimeMillis();
245
android.util.Log.e("D", "producing scramble states: "+(t7-t6)+" graph size: "+graph.size() );
246

  
247 327
    return ret;
248 328
    }
249 329

  

Also available in: Unified diff