Project

General

Profile

« Previous | Next » 

Revision d12d901a

Added by Leszek Koltunski over 2 years ago

Generalized ScrambleState generator: finished. Remove the specialized 'Evil' generator.

View differences:

src/main/java/org/distorted/objectlib/scrambling/ScrambleStateBandaged3x3.java
28 28
{
29 29
  private static final long INVALID_MOVE = -1;
30 30
  private static final int NUM_MOVES = 27;
31
  private static final int NUM_ISOMETRIES = 24;
32 31

  
33 32
  private static final int AXIS_X = 0;
34 33
  private static final int AXIS_Y = 1;
......
39 38
  private static final int LAYER_R = 2;
40 39

  
41 40
  private long mID;
42
  private final long[] mIsometries;
41
  private int mDistance;
43 42
  private final long[] mMoves;
44 43

  
45 44
///////////////////////////////////////////////////////////////////////////////////////////////////
46 45

  
47 46
  public ScrambleStateBandaged3x3(long id)
48 47
    {
48
    mDistance = -1;
49 49
    mID = id;
50
    mIsometries = createIsometries(mID);
51 50
    mMoves = createMoves(mID);
52 51
    }
53 52

  
......
60 59
    graph.add(bsg);
61 60

  
62 61
    insertChildren(graph,id);
63
    pruneGraph(graph,id);
62
    pruneGraph(graph,id,false);
63
    computeDistance(graph,id,0);
64
    removeDisconnectedParts(graph);
64 65
    remapGraph(graph);
65 66

  
66 67
    int num = graph.size();
......
79 80
    {
80 81
    ScrambleStateBandaged3x3 bsg = findState(list,id);
81 82

  
82
android.util.Log.e("D", "inserting children of "+id);
83

  
84 83
    if( bsg==null )
85 84
      {
86 85
      android.util.Log.e("D", "error: "+id+" doesn't exist");
......
103 102
          }
104 103
        else if( tmp.mID != move )
105 104
          {
106
          android.util.Log.e("D", "id "+id+" move: "+move+" leads to already existing "+tmp.mID);
107 105
          bsg.setMove(i,tmp.mID);
108 106
          }
109 107
        }
......
112 110

  
113 111
///////////////////////////////////////////////////////////////////////////////////////////////////
114 112

  
115
  private static void pruneGraph(ArrayList<ScrambleStateBandaged3x3> list, long id)
113
  private static void pruneGraph(ArrayList<ScrambleStateBandaged3x3> list, long id, boolean startingPrunedAlready)
116 114
    {
117 115
    int num = list.size();
118 116
    boolean pruned = false;
......
125 123
      if( bsg.numAxis()<2 )
126 124
        {
127 125
        long prunedID = bsg.getID();
126
        if( id!=prunedID || !startingPrunedAlready )
127
          {
128
          startingPrunedAlready = true;
129
          remapID(list,prunedID,INVALID_MOVE);
130
          }
128 131

  
129
android.util.Log.e("D", "pruning id "+prunedID+" axis: "+bsg.numAxis() );
130
bsg.printMoves();
131

  
132
        if( id!=prunedID ) list.remove(i);  // do not remove the starting point, even if
133
                                            // it does have only 1 axis
134
        pruned = true;
135
        remapID(list,prunedID,INVALID_MOVE);
136
        break;
132
        // do not remove the starting point, even if it does have only 1 axis
133
        if( id!=prunedID )
134
          {
135
          list.remove(i);
136
          pruned = true;
137
          break;
138
          }
137 139
        }
138 140
      }
139 141

  
140
    if( pruned ) pruneGraph(list,id);
141
    }
142

  
143
///////////////////////////////////////////////////////////////////////////////////////////////////
144

  
145
  private void printMoves()
146
    {
147
    String moves = "";
148

  
149
    for(int i=0; i<NUM_MOVES; i++)
150
      {
151
      moves += (" " + mMoves[i]);
152
      }
153

  
154
    android.util.Log.e("D", moves);
142
    if( pruned ) pruneGraph(list,id,startingPrunedAlready);
155 143
    }
156 144

  
157 145
///////////////////////////////////////////////////////////////////////////////////////////////////
......
191 179

  
192 180
///////////////////////////////////////////////////////////////////////////////////////////////////
193 181

  
194
  private static boolean isAnIsometry(ScrambleStateBandaged3x3 bsg, long id)
182
  private static void computeDistance(ArrayList<ScrambleStateBandaged3x3> list, long id, int distance)
195 183
    {
196
    if( bsg.mID==id ) return true;
197
    for(int i=0; i<NUM_ISOMETRIES-1; i++) if ( bsg.mIsometries[i]==id ) return true;
198
    return false;
184
    ScrambleStateBandaged3x3 state = findState(list,id);
185

  
186
    if( state==null )
187
      {
188
      android.util.Log.e("D", "error: "+id+" doesn't exist");
189
      return;
190
      }
191

  
192
    if( state.mDistance<0 )
193
      {
194
      state.mDistance = distance;
195

  
196
      for(int i=0; i<NUM_MOVES; i++)
197
        {
198
        long move = state.getMove(i);
199

  
200
        if( move!=INVALID_MOVE )
201
          {
202
          computeDistance(list,move,distance+1);
203
          }
204
        }
205
      }
206
    }
207

  
208
///////////////////////////////////////////////////////////////////////////////////////////////////
209

  
210
  private static void removeDisconnectedParts(ArrayList<ScrambleStateBandaged3x3> list)
211
    {
212
    int num = list.size();
213
    ScrambleStateBandaged3x3 bsg;
214

  
215
    for(int i=0; i<num; i++)
216
      {
217
      bsg = list.get(i);
218

  
219
      if( bsg.mDistance<0 )
220
        {
221
        list.remove(i);
222
        i--;
223
        num--;
224
        }
225
      }
199 226
    }
200 227

  
201 228
///////////////////////////////////////////////////////////////////////////////////////////////////
......
208 235
    for(int i=0; i<num; i++)
209 236
      {
210 237
      bsg= list.get(i);
211
      if( isAnIsometry(bsg,id) ) return bsg;
238
      if( bsg.mID==id ) return bsg;
212 239
      }
213 240

  
214 241
    return null;
......
222 249
    String y = getTable(bsg, 9);
223 250
    String z = getTable(bsg,18);
224 251

  
225
    return "    new ScrambleStateGraph( new int[][] { "+x+", "+y+", "+z+" } ),";
252
    return "    new ScrambleState( new int[][] { "+x+", "+y+", "+z+" } ),";
226 253
    }
227 254

  
228 255
///////////////////////////////////////////////////////////////////////////////////////////////////
......
241 268

  
242 269
    String ret = "";
243 270

  
244
    if( m0!=INVALID_MOVE ) ret += formatRet(ret,0, 1,m0);
271
    if( m0!=INVALID_MOVE ) ret += formatRet(ret,0,-1,m0);
245 272
    if( m1!=INVALID_MOVE ) ret += formatRet(ret,0, 2,m1);
246
    if( m2!=INVALID_MOVE ) ret += formatRet(ret,0,-1,m2);
247
    if( m3!=INVALID_MOVE ) ret += formatRet(ret,1, 1,m3);
273
    if( m2!=INVALID_MOVE ) ret += formatRet(ret,0, 1,m2);
274
    if( m3!=INVALID_MOVE ) ret += formatRet(ret,1,-1,m3);
248 275
    if( m4!=INVALID_MOVE ) ret += formatRet(ret,1, 2,m4);
249
    if( m5!=INVALID_MOVE ) ret += formatRet(ret,1,-1,m5);
250
    if( m6!=INVALID_MOVE ) ret += formatRet(ret,2, 1,m6);
276
    if( m5!=INVALID_MOVE ) ret += formatRet(ret,1, 1,m5);
277
    if( m6!=INVALID_MOVE ) ret += formatRet(ret,2,-1,m6);
251 278
    if( m7!=INVALID_MOVE ) ret += formatRet(ret,2, 2,m7);
252
    if( m8!=INVALID_MOVE ) ret += formatRet(ret,2,-1,m8);
279
    if( m8!=INVALID_MOVE ) ret += formatRet(ret,2, 1,m8);
253 280

  
254 281
    return formatL("{" + ret + "}");
255 282
    }
......
367 394
    }
368 395

  
369 396
///////////////////////////////////////////////////////////////////////////////////////////////////
370

  
371
  private static long[] createIsometries(long id)
372
    {
373
    long[] ret = new long[NUM_ISOMETRIES-1];
374

  
375
    ret[ 0] = turnWhole(     id,AXIS_X);
376
    ret[ 1] = turnWhole(ret[ 0],AXIS_X);
377
    ret[ 2] = turnWhole(ret[ 1],AXIS_X);
378
    ret[ 3] = turnWhole(ret[ 2],AXIS_Y);
379
    ret[ 4] = turnWhole(ret[ 3],AXIS_Y);
380
    ret[ 5] = turnWhole(ret[ 4],AXIS_Y);
381
    ret[ 6] = turnWhole(ret[ 5],AXIS_Z);
382
    ret[ 7] = turnWhole(ret[ 6],AXIS_Z);
383
    ret[ 8] = turnWhole(ret[ 7],AXIS_Z);
384
    ret[ 9] = turnWhole(ret[ 8],AXIS_X);
385
    ret[10] = turnWhole(ret[ 9],AXIS_X);
386
    ret[11] = turnWhole(ret[10],AXIS_X);
387
    ret[12] = turnWhole(ret[11],AXIS_Y);
388
    ret[13] = turnWhole(ret[12],AXIS_Y);
389
    ret[14] = turnWhole(ret[13],AXIS_Y);
390
    ret[15] = turnWhole(ret[ 5],AXIS_X);
391
    ret[16] = turnWhole(ret[15],AXIS_Y);
392
    ret[17] = turnWhole(ret[16],AXIS_Y);
393
    ret[18] = turnWhole(ret[ 4],AXIS_X);
394
    ret[19] = turnWhole(ret[18],AXIS_X);
395
    ret[20] = turnWhole(ret[19],AXIS_X);
396
    ret[21] = turnWhole(ret[ 3],AXIS_Z);
397
    ret[22] = turnWhole(ret[21],AXIS_Z);
398
/*
399
    String iso = "isometries of "+id+" :";
400

  
401
    for(int i=0; i<NUM_ISOMETRIES-1; i++)
402
      {
403
      iso += (" " + ret[i]);
404
      }
405

  
406
    android.util.Log.e("D", iso);
407
*/
408
/*
409
 long t = turnWhole(1,AXIS_X);
410

  
411
 android.util.Log.e("D", "1 turned along X: "+t);
412
*/
413
    return ret;
414
    }
415

  
416
///////////////////////////////////////////////////////////////////////////////////////////////////
417
// 0 : DF,DRF
418
// 1 : DF,DLF
419
// 2 : DR,DRF
420
// 3 : D,DF
421
// 4 : DL,DLF
422
// 5 : D,DR
423
// 6 : D,DL
424
// 7 : DR,DRB
425
// 8 : D,DB
426
// 9 : DL,DLB
427
//10 : DB,DRB
428
//11 : DB,DLB
429
//12 : FR,DRF
430
//13 : F,DF
431
//14 : FL,DLF
432
//15 : R,DR
433
//16 : D,CORE
434
//17 : L,DL
435
//18 : BR,DRB
436
//19 : B,DB
437
//20 : BL,DLB
438
//21 : F,FR
439
//22 : F,FL
440
//23 : R,FR
441
//24 : F,CORE
442
//25 : L,FL
443
//26 : R,CORE
444
//27 : L,CORE
445
//28 : R,BR
446
//29 : B,CORE
447
//30 : L,BL
448
//31 : B,BR
449
//32 : B,BL
450
//33 : FR,URF
451
//34 : F,UF
452
//35 : FL,ULF
453
//36 : R,UR
454
//37 : U,CORE
455
//38 : L,UL
456
//39 : BR,URB
457
//40 : B,UB
458
//41 : BL,ULB
459
//42 : UF,URF
460
//43 : UF,ULF
461
//44 : UR,URF
462
//45 : U,UF
463
//46 : UL,ULF
464
//47 : U,UR
465
//48 : U,UL
466
//49 : UR,URB
467
//50 : U,UB
468
//51 : UL,ULB
469
//52 : UB,URB
470
//53 : UB,ULB
397
// Definition of the id: it's an 'Andreas signature' of a bandaged cube.
398
// https://twistypuzzles.com/forum/viewtopic.php?t=24452&sid=f3b4ac0c611c4713e4d7840f1aabbb0b&start=350
471 399

  
472 400
  private static long turn(long id, int axis, int layer)
473 401
    {
......
567 495
    return 0;
568 496
    }
569 497

  
570
///////////////////////////////////////////////////////////////////////////////////////////////////
571

  
572
  private static long turnWhole(long id, int axis)
573
    {
574
    switch(axis)
575
      {
576
      case AXIS_X: long x1 = cycle(id,9,14,46,41); //
577
                   long x2 = cycle(x1,4,35,51,20); // left layer
578
                   long x3 = cycle(x2,17,25,38,30);//
579

  
580
                   long x4 = cycle(x3,8,13,45,40); //
581
                   long x5 = cycle(x4,3,34,50,19); // mid layer
582
                   long x6 = cycle(x5,16,24,37,29);//
583

  
584
                   long x7 = cycle(x6,7,12,44,39); //
585
                   long x8 = cycle(x7,2,33,49,18); // right layer
586
                   long x9 = cycle(x8,15,23,36,28);//
587

  
588
                   long x10= cycle(x9,1,43,53,11); //
589
                   long x11= cycle(x10,6,22,48,32);// left lock
590
                   long x12= cycle(x11,0,42,52,10);//
591
                   return    cycle(x12,5,21,47,31);// right lock
592

  
593
      case AXIS_Y: long y1 = cycle(id,1,9,10,2);   //
594
                   long y2 = cycle(y1,0,4,11,7);   // bottom layer
595
                   long y3 = cycle(y2,3,6,8,5);    //
596

  
597
                   long y4 = cycle(y3,21,25,32,28);//
598
                   long y5 = cycle(y4,22,30,31,23);// mid layer
599
                   long y6 = cycle(y5,24,27,29,26);//
600

  
601
                   long y7 = cycle(y6,42,46,53,49);//
602
                   long y8 = cycle(y7,43,51,52,44);// top layer
603
                   long y9 = cycle(y8,45,48,50,47);//
604

  
605
                   long y10= cycle(y9,12,14,20,18); //
606
                   long y11= cycle(y10,13,17,19,15);// bottom lock
607
                   long y12= cycle(y11,33,35,41,39);//
608
                   return    cycle(y12,34,38,40,36);// top lock
609

  
610
      case AXIS_Z: long z1 = cycle(id,10,20,53,39);//
611
                   long z2 = cycle(z1,11,41,52,18);// back layer
612
                   long z3 = cycle(z2,19,32,40,31);//
613

  
614
                   long z4 = cycle(z3,5,17,48,36); //
615
                   long z5 = cycle(z4,6,38,47,15); // mid layer
616
                   long z6 = cycle(z5,16,27,37,26);//
617

  
618
                   long z7 = cycle(z6,0,14,43,33); //
619
                   long z8 = cycle(z7,1,35,42,12); // front layer
620
                   long z9 = cycle(z8,13,22,34,21);//
621

  
622
                   long z10= cycle(z9,7,9,51,49);  //
623
                   long z11= cycle(z10,8,30,50,28);// back lock
624
                   long z12= cycle(z11,2,4,46,44); //
625
                   return    cycle(z12,3,25,45,23);// front lock
626
      }
627

  
628
    return 0;
629
    }
630

  
631 498
///////////////////////////////////////////////////////////////////////////////////////////////////
632 499
// bit b1 in place of b2 etc.
633 500

  
......
644 511
    return    setBit(i3,b1,bit4);
645 512
    }
646 513

  
647

  
648 514
///////////////////////////////////////////////////////////////////////////////////////////////////
649
// bit b1 in place of b2 etc.
650 515

  
651
  private static long cyclePriv(long id, int b1, int b2, int b3, int b4)
516
  private static long getBit(long id, int bit)
652 517
    {
653
    long bit1 = getBit(id,b1);
654
    long bit2 = getBit(id,b2);
655
    long bit3 = getBit(id,b3);
656
    long bit4 = getBit(id,b4);
657

  
658
android.util.Log.e("D", "bit1="+bit1+" bit2="+bit2+" bit3="+bit3+" bit4="+bit4);
659

  
660
    long i1 = setBitPriv(id,b2,bit1);
661
    long i2 = setBitPriv(i1,b3,bit2);
662
    long i3 = setBitPriv(i2,b4,bit3);
663
    long i4 = setBitPriv(i3,b1,bit4);
664

  
665

  
666
android.util.Log.e("D", "i1="+i1+" i2="+i2+" i3="+i3+" i4="+i4);
667

  
668
    return i4;
518
    return (id>>bit)&0x1;
669 519
    }
670 520

  
671

  
672 521
///////////////////////////////////////////////////////////////////////////////////////////////////
673 522

  
674
  private static long setBitPriv(long id, int bit, long value)
523
  private static long setBit(long id, int bit, long value)
675 524
    {
676 525
    long old = getBit(id,bit);
677 526

  
......
681 530
      id += (value==0 ? -diff : diff);
682 531
      }
683 532

  
684
android.util.Log.e("D", "setBit: id: "+id+" bit="+bit+" value="+value+" old="+old+" ret="+id);
685

  
686 533
    return id;
687 534
    }
688
///////////////////////////////////////////////////////////////////////////////////////////////////
689 535

  
690
  private static long getBit(long id, int bit)
536
///////////////////////////////////////////////////////////////////////////////////////////////////
537
/*
538
  private void printMoves()
691 539
    {
692
    return (id>>bit)&0x1;
540
    String moves = "";
541

  
542
    for(int i=0; i<NUM_MOVES; i++)
543
      {
544
      moves += (" " + mMoves[i]);
545
      }
546

  
547
    android.util.Log.e("D", moves);
693 548
    }
694 549

  
695 550
///////////////////////////////////////////////////////////////////////////////////////////////////
696 551

  
697
  private static long setBit(long id, int bit, long value)
552
  private static String printBits(long id)
698 553
    {
699
    long old = getBit(id,bit);
554
    String ret = "[";
555
    boolean first = true;
700 556

  
701
    if( old!=value )
557
    for(int i=0; i<64; i++)
702 558
      {
703
      long diff = (1L<<bit);
704
      id += (value==0 ? -diff : diff);
559
      if( ( (id>>i)&0x1)==1 )
560
        {
561
        String num = (i<10 ? " "+i : ""+i);
562

  
563
        if( first ) { ret += num; first=false; }
564
        else          ret += (","+num);
565
        }
705 566
      }
706 567

  
707
    return id;
568
    return ret + "]";
708 569
    }
570
*/
709 571
}

Also available in: Unified diff