Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / scrambling / ScrambleStateBandaged3x3.java @ 5f54927b

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2022 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

    
24
///////////////////////////////////////////////////////////////////////////////////////////////////
25
// Producer of the ScrambleStateGraph for any bandaged 3x3x3.
26

    
27
public class ScrambleStateBandaged3x3
28
{
29
  private static final long INVALID_MOVE = -1;
30
  private static final int NUM_MOVES = 27;
31

    
32
  private static final int AXIS_X = 0;
33
  private static final int AXIS_Y = 1;
34
  private static final int AXIS_Z = 2;
35

    
36
  private static final int LAYER_L = 0;
37
  private static final int LAYER_M = 1;
38
  private static final int LAYER_R = 2;
39

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

    
44
///////////////////////////////////////////////////////////////////////////////////////////////////
45

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

    
53
///////////////////////////////////////////////////////////////////////////////////////////////////
54

    
55
  private long getID()
56
    {
57
    return mID;
58
    }
59

    
60
///////////////////////////////////////////////////////////////////////////////////////////////////
61

    
62
  private void setID(long id)
63
    {
64
    mID = id;
65
    }
66

    
67
///////////////////////////////////////////////////////////////////////////////////////////////////
68

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

    
74
///////////////////////////////////////////////////////////////////////////////////////////////////
75

    
76
  private int numAxis()
77
    {
78
    int num = 0;
79

    
80
    if( mMoves[ 0]!=INVALID_MOVE || mMoves[ 1]!=INVALID_MOVE || mMoves[ 2]!=INVALID_MOVE ||
81
        mMoves[ 3]!=INVALID_MOVE || mMoves[ 4]!=INVALID_MOVE || mMoves[ 5]!=INVALID_MOVE ||
82
        mMoves[ 6]!=INVALID_MOVE || mMoves[ 7]!=INVALID_MOVE || mMoves[ 8]!=INVALID_MOVE   ) num++;
83

    
84
    if( mMoves[ 9]!=INVALID_MOVE || mMoves[10]!=INVALID_MOVE || mMoves[11]!=INVALID_MOVE ||
85
        mMoves[12]!=INVALID_MOVE || mMoves[13]!=INVALID_MOVE || mMoves[14]!=INVALID_MOVE ||
86
        mMoves[15]!=INVALID_MOVE || mMoves[16]!=INVALID_MOVE || mMoves[17]!=INVALID_MOVE   ) num++;
87

    
88
    if( mMoves[18]!=INVALID_MOVE || mMoves[19]!=INVALID_MOVE || mMoves[20]!=INVALID_MOVE ||
89
        mMoves[21]!=INVALID_MOVE || mMoves[22]!=INVALID_MOVE || mMoves[23]!=INVALID_MOVE ||
90
        mMoves[24]!=INVALID_MOVE || mMoves[25]!=INVALID_MOVE || mMoves[26]!=INVALID_MOVE   ) num++;
91

    
92
    return num;
93
    }
94

    
95
///////////////////////////////////////////////////////////////////////////////////////////////////
96

    
97
  private void setMove(int index, long newMove)
98
    {
99
    if( index>=0 && index<NUM_MOVES ) mMoves[index] = newMove;
100
    }
101

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

    
104
  private String formatMoves()
105
    {
106
    String x = getTable( 0);
107
    String y = getTable( 9);
108
    String z = getTable(18);
109

    
110
    return "    new ScrambleState( new int[][] { "+x+", "+y+", "+z+" } ),";
111
    }
112

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

    
115
  private String getTable(int index)
116
    {
117
    long m0 = getMove(index  );
118
    long m1 = getMove(index+1);
119
    long m2 = getMove(index+2);
120
    long m3 = getMove(index+3);
121
    long m4 = getMove(index+4);
122
    long m5 = getMove(index+5);
123
    long m6 = getMove(index+6);
124
    long m7 = getMove(index+7);
125
    long m8 = getMove(index+8);
126

    
127
    String ret = "";
128

    
129
    if( m0!=INVALID_MOVE ) ret += formatRet(ret,0,-1,m0);
130
    if( m1!=INVALID_MOVE ) ret += formatRet(ret,0, 2,m1);
131
    if( m2!=INVALID_MOVE ) ret += formatRet(ret,0, 1,m2);
132
    if( m3!=INVALID_MOVE ) ret += formatRet(ret,1,-1,m3);
133
    if( m4!=INVALID_MOVE ) ret += formatRet(ret,1, 2,m4);
134
    if( m5!=INVALID_MOVE ) ret += formatRet(ret,1, 1,m5);
135
    if( m6!=INVALID_MOVE ) ret += formatRet(ret,2,-1,m6);
136
    if( m7!=INVALID_MOVE ) ret += formatRet(ret,2, 2,m7);
137
    if( m8!=INVALID_MOVE ) ret += formatRet(ret,2, 1,m8);
138

    
139
    return formatL("{" + ret + "}");
140
    }
141

    
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143

    
144
  private int[] getMoves(int index)
145
    {
146
    int numValid = 0;
147
    for(int i=index; i<index+9; i++) if( mMoves[i]!=INVALID_MOVE ) numValid++;
148

    
149
    int[] ret = new int[3*numValid];
150

    
151
    long m0 = getMove(index  );
152
    long m1 = getMove(index+1);
153
    long m2 = getMove(index+2);
154
    long m3 = getMove(index+3);
155
    long m4 = getMove(index+4);
156
    long m5 = getMove(index+5);
157
    long m6 = getMove(index+6);
158
    long m7 = getMove(index+7);
159
    long m8 = getMove(index+8);
160

    
161
    int pointer=0;
162

    
163
    if( m0!=INVALID_MOVE ) { ret[pointer]=0; ret[pointer+1]=-1; ret[pointer+2]= (int)m0; pointer+=3; }
164
    if( m1!=INVALID_MOVE ) { ret[pointer]=0; ret[pointer+1]= 2; ret[pointer+2]= (int)m1; pointer+=3; }
165
    if( m2!=INVALID_MOVE ) { ret[pointer]=0; ret[pointer+1]= 1; ret[pointer+2]= (int)m2; pointer+=3; }
166
    if( m3!=INVALID_MOVE ) { ret[pointer]=1; ret[pointer+1]=-1; ret[pointer+2]= (int)m3; pointer+=3; }
167
    if( m4!=INVALID_MOVE ) { ret[pointer]=1; ret[pointer+1]= 2; ret[pointer+2]= (int)m4; pointer+=3; }
168
    if( m5!=INVALID_MOVE ) { ret[pointer]=1; ret[pointer+1]= 1; ret[pointer+2]= (int)m5; pointer+=3; }
169
    if( m6!=INVALID_MOVE ) { ret[pointer]=2; ret[pointer+1]=-1; ret[pointer+2]= (int)m6; pointer+=3; }
170
    if( m7!=INVALID_MOVE ) { ret[pointer]=2; ret[pointer+1]= 2; ret[pointer+2]= (int)m7; pointer+=3; }
171
    if( m8!=INVALID_MOVE ) { ret[pointer]=2; ret[pointer+1]= 1; ret[pointer+2]= (int)m8; pointer+=3; }
172

    
173
    return ret;
174
    }
175

    
176
///////////////////////////////////////////////////////////////////////////////////////////////////
177

    
178
  private ScrambleState produceScrambleState()
179
    {
180
    int[] xMoves = getMoves(0);
181
    int[] yMoves = getMoves(9);
182
    int[] zMoves = getMoves(18);
183

    
184
    int[][] moves = { xMoves,yMoves,zMoves };
185

    
186
    return new ScrambleState( moves );
187
    }
188

    
189
///////////////////////////////////////////////////////////////////////////////////////////////////
190
// STATIC STUFF
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192

    
193
  public static ScrambleState[] computeGraph(long id)
194
    {
195
    ScrambleStateBandaged3x3 bsg = new ScrambleStateBandaged3x3(id);
196
    ArrayList<ScrambleStateBandaged3x3> graph = new ArrayList<>();
197
    graph.add(bsg);
198

    
199
    insertChildren(graph,id);
200
    pruneGraph(graph,id,false);
201
    computeDistance(graph,id,0);
202
    removeDisconnectedParts(graph);
203
    remapGraph(graph);
204

    
205
    int num = graph.size();
206
    ScrambleState[] ret = new ScrambleState[num];
207

    
208
    for(int i=0; i<num; i++)
209
      {
210
      ScrambleStateBandaged3x3 ssb = graph.get(i);
211
      ret[i] = ssb.produceScrambleState();
212
      }
213

    
214
    return ret;
215
    }
216

    
217
///////////////////////////////////////////////////////////////////////////////////////////////////
218

    
219
  private static void insertChildren(ArrayList<ScrambleStateBandaged3x3> list, long id)
220
    {
221
    ScrambleStateBandaged3x3 bsg = findState(list,id);
222

    
223
    if( bsg==null )
224
      {
225
      android.util.Log.e("D", "error: "+id+" doesn't exist");
226
      return;
227
      }
228

    
229
    for(int i=0; i<NUM_MOVES; i++)
230
      {
231
      long move = bsg.getMove(i);
232

    
233
      if( move!=INVALID_MOVE )
234
        {
235
        ScrambleStateBandaged3x3 tmp = findState(list,move);
236

    
237
        if( tmp==null )
238
          {
239
          tmp = new ScrambleStateBandaged3x3(move);
240
          list.add(tmp);
241
          insertChildren(list,move);
242
          }
243
        else if( tmp.mID != move )
244
          {
245
          bsg.setMove(i,tmp.mID);
246
          }
247
        }
248
      }
249
    }
250

    
251
///////////////////////////////////////////////////////////////////////////////////////////////////
252

    
253
  private static void pruneGraph(ArrayList<ScrambleStateBandaged3x3> list, long id, boolean startingPrunedAlready)
254
    {
255
    int num = list.size();
256
    boolean pruned = false;
257
    ScrambleStateBandaged3x3 bsg;
258

    
259
    for(int i=0; i<num; i++)
260
      {
261
      bsg = list.get(i);
262

    
263
      if( bsg.numAxis()<2 )
264
        {
265
        long prunedID = bsg.getID();
266
        if( id!=prunedID || !startingPrunedAlready )
267
          {
268
          startingPrunedAlready = true;
269
          remapID(list,prunedID,INVALID_MOVE);
270
          }
271

    
272
        // do not remove the starting point, even if it does have only 1 axis
273
        if( id!=prunedID )
274
          {
275
          list.remove(i);
276
          pruned = true;
277
          break;
278
          }
279
        }
280
      }
281

    
282
    if( pruned ) pruneGraph(list,id,startingPrunedAlready);
283
    }
284

    
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286

    
287
  private static void remapGraph(ArrayList<ScrambleStateBandaged3x3> list)
288
    {
289
    long id;
290
    int num = list.size();
291
    ScrambleStateBandaged3x3 bsg;
292

    
293
    for(int i=0; i<num; i++ )
294
      {
295
      bsg = list.get(i);
296
      id = bsg.getID();
297
      bsg.setID(i);
298
      remapID(list,id,i);
299
      }
300
    }
301

    
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303

    
304
  private static void remapID(ArrayList<ScrambleStateBandaged3x3> list, long id, long newId)
305
    {
306
    ScrambleStateBandaged3x3 bsg;
307
    int size = list.size();
308

    
309
    for(int i=0; i<size; i++)
310
      {
311
      bsg = list.get(i);
312

    
313
      for(int j=0; j<NUM_MOVES; j++)
314
        {
315
        if( bsg.getMove(j)==id ) bsg.setMove(j,newId);
316
        }
317
      }
318
    }
319

    
320
///////////////////////////////////////////////////////////////////////////////////////////////////
321

    
322
  private static void computeDistance(ArrayList<ScrambleStateBandaged3x3> list, long id, int distance)
323
    {
324
    ScrambleStateBandaged3x3 state = findState(list,id);
325

    
326
    if( state==null )
327
      {
328
      android.util.Log.e("D", "error: "+id+" doesn't exist");
329
      return;
330
      }
331

    
332
    if( state.mDistance<0 )
333
      {
334
      state.mDistance = distance;
335

    
336
      for(int i=0; i<NUM_MOVES; i++)
337
        {
338
        long move = state.getMove(i);
339

    
340
        if( move!=INVALID_MOVE )
341
          {
342
          computeDistance(list,move,distance+1);
343
          }
344
        }
345
      }
346
    }
347

    
348
///////////////////////////////////////////////////////////////////////////////////////////////////
349

    
350
  private static void removeDisconnectedParts(ArrayList<ScrambleStateBandaged3x3> list)
351
    {
352
    int num = list.size();
353
    ScrambleStateBandaged3x3 bsg;
354

    
355
    for(int i=0; i<num; i++)
356
      {
357
      bsg = list.get(i);
358

    
359
      if( bsg.mDistance<0 )
360
        {
361
        list.remove(i);
362
        i--;
363
        num--;
364
        }
365
      }
366
    }
367

    
368
///////////////////////////////////////////////////////////////////////////////////////////////////
369

    
370
  private static ScrambleStateBandaged3x3 findState(ArrayList<ScrambleStateBandaged3x3> list, long id)
371
    {
372
    ScrambleStateBandaged3x3 bsg;
373
    int num = list.size();
374

    
375
    for(int i=0; i<num; i++)
376
      {
377
      bsg= list.get(i);
378
      if( bsg.mID==id ) return bsg;
379
      }
380

    
381
    return null;
382
    }
383

    
384
///////////////////////////////////////////////////////////////////////////////////////////////////
385

    
386
  private static String formatRet(String str, int row, int angle, long id)
387
    {
388
    String ret = str.length()!=0 ? ",":"";
389

    
390
    ret += row;
391
    ret += angle<0 ? "," : ", ";
392
    ret += angle;
393

    
394
         if( id< 10 ) ret += (",  "+id);
395
    else if( id<100 ) ret += (", " +id);
396
    else              ret += (","  +id);
397

    
398
    return ret;
399
    }
400

    
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402

    
403
  private static final int LENGTH = 28;
404

    
405
  private static String formatL(String input)
406
    {
407
    int len = input.length();
408
    String ret = input;
409
    for(int i=0 ;i<LENGTH-len; i++) ret += " ";
410
    return ret;
411
    }
412

    
413
///////////////////////////////////////////////////////////////////////////////////////////////////
414

    
415
  private static long[] createMoves(long id)
416
    {
417
    long[] ret = new long[NUM_MOVES];
418
    int index = 0;
419

    
420
    for(int axis=0; axis<3; axis++)
421
      for(int layer=0; layer<3; layer++)
422
        {
423
        long x1 = turn(id,axis,layer);
424

    
425
        if( x1!=INVALID_MOVE )
426
          {
427
          long x2 = turn(x1,axis,layer);
428
          long x3 = turn(x2,axis,layer);
429

    
430
          ret[index  ] = x1;
431
          ret[index+1] = x2;
432
          ret[index+2] = x3;
433
          }
434
        else
435
          {
436
          ret[index  ] = INVALID_MOVE;
437
          ret[index+1] = INVALID_MOVE;
438
          ret[index+2] = INVALID_MOVE;
439
          }
440

    
441
        index+=3;
442
        }
443

    
444
    return ret;
445
    }
446

    
447
///////////////////////////////////////////////////////////////////////////////////////////////////
448
// Definition of the id: it's an 'Andreas signature' of a bandaged cube.
449
// https://twistypuzzles.com/forum/viewtopic.php?t=24452&sid=f3b4ac0c611c4713e4d7840f1aabbb0b&start=350
450

    
451
  private static long turn(long id, int axis, int layer)
452
    {
453
    switch(axis)
454
      {
455
      case AXIS_X: switch(layer)
456
                     {
457
                     case LAYER_L: if( getBit(id, 1)==1 || getBit(id, 6)==1 || getBit(id,11)==1 ||
458
                                       getBit(id,22)==1 || getBit(id,27)==1 || getBit(id,32)==1 ||
459
                                       getBit(id,43)==1 || getBit(id,48)==1 || getBit(id,53)==1  ) return INVALID_MOVE;
460

    
461
                                   long x1 = cycle(id,9,14,46,41);
462
                                   long x2 = cycle(x1,4,35,51,20);
463
                                   return    cycle(x2,17,25,38,30);
464

    
465
                     case LAYER_M: if( getBit(id, 1)==1 || getBit(id, 6)==1 || getBit(id,11)==1 ||
466
                                       getBit(id,22)==1 || getBit(id,27)==1 || getBit(id,32)==1 ||
467
                                       getBit(id,43)==1 || getBit(id,48)==1 || getBit(id,53)==1 ||
468
                                       getBit(id, 0)==1 || getBit(id, 5)==1 || getBit(id,10)==1 ||
469
                                       getBit(id,21)==1 || getBit(id,26)==1 || getBit(id,31)==1 ||
470
                                       getBit(id,42)==1 || getBit(id,47)==1 || getBit(id,52)==1  ) return INVALID_MOVE;
471

    
472
                                   long x4 = cycle(id,8,13,45,40);
473
                                   long x5 = cycle(x4,3,34,50,19);
474
                                   return    cycle(x5,16,24,37,29);
475

    
476
                     case LAYER_R: if( getBit(id, 0)==1 || getBit(id, 5)==1 || getBit(id,10)==1 ||
477
                                       getBit(id,21)==1 || getBit(id,26)==1 || getBit(id,31)==1 ||
478
                                       getBit(id,42)==1 || getBit(id,47)==1 || getBit(id,52)==1  ) return INVALID_MOVE;
479

    
480
                                   long x7 = cycle(id,7,12,44,39);
481
                                   long x8 = cycle(x7,2,33,49,18);
482
                                   return    cycle(x8,15,23,36,28);
483
                     }
484

    
485
      case AXIS_Y: switch(layer)
486
                     {
487
                     case LAYER_L: if( getBit(id,12)==1 || getBit(id,13)==1 || getBit(id,14)==1 ||
488
                                       getBit(id,15)==1 || getBit(id,16)==1 || getBit(id,17)==1 ||
489
                                       getBit(id,18)==1 || getBit(id,19)==1 || getBit(id,20)==1  ) return INVALID_MOVE;
490

    
491
                                   long y1 = cycle(id,1,9,10,2);
492
                                   long y2 = cycle(y1,0,4,11,7);
493
                                   return    cycle(y2,3,6,8,5);
494

    
495
                     case LAYER_M: if( getBit(id,12)==1 || getBit(id,13)==1 || getBit(id,14)==1 ||
496
                                       getBit(id,15)==1 || getBit(id,16)==1 || getBit(id,17)==1 ||
497
                                       getBit(id,18)==1 || getBit(id,19)==1 || getBit(id,20)==1 ||
498
                                       getBit(id,33)==1 || getBit(id,34)==1 || getBit(id,35)==1 ||
499
                                       getBit(id,36)==1 || getBit(id,37)==1 || getBit(id,38)==1 ||
500
                                       getBit(id,39)==1 || getBit(id,40)==1 || getBit(id,41)==1  ) return INVALID_MOVE;
501

    
502
                                   long y4 = cycle(id,21,25,32,28);
503
                                   long y5 = cycle(y4,22,30,31,23);
504
                                   return    cycle(y5,24,27,29,26);
505

    
506
                     case LAYER_R: if( getBit(id,33)==1 || getBit(id,34)==1 || getBit(id,35)==1 ||
507
                                       getBit(id,36)==1 || getBit(id,37)==1 || getBit(id,38)==1 ||
508
                                       getBit(id,39)==1 || getBit(id,40)==1 || getBit(id,41)==1  ) return INVALID_MOVE;
509

    
510
                                   long y7 = cycle(id,42,46,53,49);
511
                                   long y8 = cycle(y7,43,51,52,44);
512
                                   return    cycle(y8,45,48,50,47);
513
                     }
514

    
515
      case AXIS_Z: switch(layer)
516
                     {
517
                     case LAYER_L: if( getBit(id, 7)==1 || getBit(id, 8)==1 || getBit(id, 9)==1 ||
518
                                       getBit(id,28)==1 || getBit(id,29)==1 || getBit(id,30)==1 ||
519
                                       getBit(id,49)==1 || getBit(id,50)==1 || getBit(id,51)==1  ) return INVALID_MOVE;
520

    
521
                                   long z1 = cycle(id,10,20,53,39);
522
                                   long z2 = cycle(z1,11,41,52,18);
523
                                   return    cycle(z2,19,32,40,31);
524

    
525
                     case LAYER_M: if( getBit(id, 7)==1 || getBit(id, 8)==1 || getBit(id, 9)==1 ||
526
                                       getBit(id,28)==1 || getBit(id,29)==1 || getBit(id,30)==1 ||
527
                                       getBit(id,49)==1 || getBit(id,50)==1 || getBit(id,51)==1 ||
528
                                       getBit(id, 2)==1 || getBit(id, 3)==1 || getBit(id, 4)==1 ||
529
                                       getBit(id,23)==1 || getBit(id,24)==1 || getBit(id,25)==1 ||
530
                                       getBit(id,44)==1 || getBit(id,45)==1 || getBit(id,46)==1  ) return INVALID_MOVE;
531

    
532
                                   long z4 = cycle(id,5,17,48,36);
533
                                   long z5 = cycle(z4,6,38,47,15);
534
                                   return    cycle(z5,16,27,37,26);
535

    
536
                     case LAYER_R: if( getBit(id, 2)==1 || getBit(id, 3)==1 || getBit(id, 4)==1 ||
537
                                       getBit(id,23)==1 || getBit(id,24)==1 || getBit(id,25)==1 ||
538
                                       getBit(id,44)==1 || getBit(id,45)==1 || getBit(id,46)==1  ) return INVALID_MOVE;
539

    
540
                                   long z7 = cycle(id,0,14,43,33);
541
                                   long z8 = cycle(z7,1,35,42,12);
542
                                   return    cycle(z8,13,22,34,21);
543
                     }
544
      }
545

    
546
    return 0;
547
    }
548

    
549
///////////////////////////////////////////////////////////////////////////////////////////////////
550
// bit b1 in place of b2 etc.
551

    
552
  private static long cycle(long id, int b1, int b2, int b3, int b4)
553
    {
554
    long bit1 = getBit(id,b1);
555
    long bit2 = getBit(id,b2);
556
    long bit3 = getBit(id,b3);
557
    long bit4 = getBit(id,b4);
558

    
559
    long i1 = setBit(id,b2,bit1);
560
    long i2 = setBit(i1,b3,bit2);
561
    long i3 = setBit(i2,b4,bit3);
562
    return    setBit(i3,b1,bit4);
563
    }
564

    
565
///////////////////////////////////////////////////////////////////////////////////////////////////
566

    
567
  private static long getBit(long id, int bit)
568
    {
569
    return (id>>bit)&0x1;
570
    }
571

    
572
///////////////////////////////////////////////////////////////////////////////////////////////////
573

    
574
  private static long setBit(long id, int bit, long value)
575
    {
576
    long old = getBit(id,bit);
577

    
578
    if( old!=value )
579
      {
580
      long diff = (1L<<bit);
581
      id += (value==0 ? -diff : diff);
582
      }
583

    
584
    return id;
585
    }
586
/*
587
///////////////////////////////////////////////////////////////////////////////////////////////////
588

    
589
  private void printMoves()
590
    {
591
    String moves = "";
592

    
593
    for(int i=0; i<NUM_MOVES; i++)
594
      {
595
      moves += (" " + mMoves[i]);
596
      }
597

    
598
    android.util.Log.e("D", moves);
599
    }
600

    
601
///////////////////////////////////////////////////////////////////////////////////////////////////
602

    
603
  private static String printBits(long id)
604
    {
605
    String ret = "[";
606
    boolean first = true;
607

    
608
    for(int i=0; i<64; i++)
609
      {
610
      if( ( (id>>i)&0x1)==1 )
611
        {
612
        String num = (i<10 ? " "+i : ""+i);
613

    
614
        if( first ) { ret += num; first=false; }
615
        else          ret += (","+num);
616
        }
617
      }
618

    
619
    return ret + "]";
620
    }
621

    
622
///////////////////////////////////////////////////////////////////////////////////////////////////
623

    
624
  private static void printGraph(ArrayList<ScrambleStateBandaged3x3> graph)
625
    {
626
    int num = graph.size();
627
    android.util.Log.e("D", "\n"+num+" states\n");
628

    
629
    for(int i=0; i<num; i++)
630
      {
631
      bsg = graph.get(i);
632
      android.util.Log.e("D", bsg.formatMoves());
633
      }
634
    }
635
*/
636
}
(3-3/4)