Project

General

Profile

Download (15.4 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / solvers / cube3 / CoordCube.java @ 1f9772f3

1
package org.distorted.solvers.cube3;
2

    
3
import android.content.res.Resources;
4
import java.io.InputStream;
5

    
6
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7
// Representation of the cube on the coordinate level
8
class CoordCube {
9

    
10
	static final short N_TWIST = 2187;// 3^7 possible corner orientations
11
	static final short N_FLIP = 2048;// 2^11 possible edge flips
12
	static final short N_SLICE1 = 495;// 12 choose 4 possible positions of FR,FL,BL,BR edges
13
	static final short N_SLICE2 = 24;// 4! permutations of FR,FL,BL,BR edges in phase2
14
	static final short N_PARITY = 2; // 2 possible corner parities
15
	static final short N_URFtoDLF = 20160;// 8!/(8-6)! permutation of URF,UFL,ULB,UBR,DFR,DLF corners
16
	static final short N_FRtoBR = 11880; // 12!/(12-4)! permutation of FR,FL,BL,BR edges
17
	static final short N_URtoUL = 1320; // 12!/(12-3)! permutation of UR,UF,UL edges
18
	static final short N_UBtoDF = 1320; // 12!/(12-3)! permutation of UB,DR,DF edges
19
	static final short N_URtoDF = 20160; // 8!/(8-6)! permutation of UR,UF,UL,UB,DR,DF edges in phase2
20
	
21
	static final int N_URFtoDLB = 40320;// 8! permutations of the corners
22
	static final int N_URtoBR = 479001600;// 8! permutations of the corners
23
	
24
	static final short N_MOVE = 18;
25

    
26
	// All coordinates are 0 for a solved cube except for UBtoDF, which is 114
27
	short twist;
28
	short flip;
29
	short parity;
30
	short FRtoBR;
31
	short URFtoDLF;
32
	short URtoUL;
33
	short UBtoDF;
34
	int URtoDF;
35

    
36
	private static boolean[] init = new boolean[12];
37
	
38
	static 
39
	  {
40
	  for(int i=0; i<12; i++ ) init[i] = false;	
41
	  }
42
	
43
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
44
	// Generate a CoordCube from a CubieCube
45
	CoordCube(CubieCube c) {
46
		twist = c.getTwist();
47
		flip = c.getFlip();
48
		parity = c.cornerParity();
49
		FRtoBR = c.getFRtoBR();
50
		URFtoDLF = c.getURFtoDLF();
51
		URtoUL = c.getURtoUL();
52
		UBtoDF = c.getUBtoDF();
53
		URtoDF = c.getURtoDF();// only needed in phase2
54
	}
55

    
56
	// A move on the coordinate level
57
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
58
	void move(int m) {
59
		twist = getTwistMove(twist,m);
60
		flip = getFlipMove(flip,m);
61
		parity = parityMove[parity][m];
62
		FRtoBR = getFRtoBR_Move(FRtoBR,m);
63
		URFtoDLF = getURFtoDLF_Move(URFtoDLF,m);
64
		URtoUL = getURtoUL_Move(URtoUL,m);
65
		UBtoDF = getUBtoDF_Move(UBtoDF,m);
66
		if (URtoUL < 336 && UBtoDF < 336)// updated only if UR,UF,UL,UB,DR,DF
67
			// are not in UD-slice
68
			URtoDF = getMergeURtoULandUBtoDF(URtoUL,UBtoDF);
69
	}
70

    
71
	// ******************************************Phase 1 move tables*****************************************************
72

    
73
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
74
	// Move table for the twists of the corners
75
	// twist < 2187 in phase 2.
76
	// twist = 0 in phase 2.
77
	private static byte[] twistMove = new byte[2*N_TWIST*N_MOVE];
78
	
79
	public static boolean initialize1(Resources res)
80
	{
81
		if( !init[0] )
82
		  {
83
          try
84
		    {
85
        	InputStream is = res.openRawResource(org.distorted.main.R.raw.cube3solver_table1);
86
		    is.read( twistMove, 0, 2*N_TWIST*N_MOVE);
87
		    }
88
		  catch(Exception ioe)
89
		    {
90
		    System.out.println("error reading table1");
91
                    return false;
92
		    }
93
		
94
		  init[0]=true;
95
		  }
96

    
97
                return true;
98
	}
99

    
100
	public static short getTwistMove(int a,int b)
101
	{
102
		short upperS = twistMove[2*(a*N_MOVE+b)];
103
		short lowerS = twistMove[2*(a*N_MOVE+b)+1];
104
		
105
		if( upperS<0 ) upperS+=256;
106
		if( lowerS<0 ) lowerS+=256;
107
		
108
		return  (short)( (upperS<<8) + lowerS );
109
	}
110
	
111
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
112
	// Move table for the flips of the edges
113
	// flip < 2048 in phase 1
114
	// flip = 0 in phase 2.
115
	private static byte[] flipMove = new byte[2*N_FLIP*N_MOVE];
116
	
117
	public static boolean initialize2(Resources res)
118
	{
119
		if( !init[1] )
120
		  {
121
		  try
122
		    {
123
			InputStream is = res.openRawResource(org.distorted.main.R.raw.cube3solver_table2);
124
		    is.read( flipMove, 0, 2*N_FLIP*N_MOVE);
125
		    }
126
		  catch(Exception ioe)
127
		    {
128
		    System.out.println("error reading table2");
129
                    return false;
130
		    }
131
		
132
		  init[1]=true;
133
		  }
134

    
135
                return true;
136
	}
137
	
138
	public static short getFlipMove(int a,int b)
139
	{
140
		short upperS = flipMove[2*(a*N_MOVE+b)];
141
		short lowerS = flipMove[2*(a*N_MOVE+b)+1];
142
		
143
		if( upperS<0 ) upperS+=256;
144
		if( lowerS<0 ) lowerS+=256;
145
		
146
		return  (short)( (upperS<<8) + lowerS );
147
	}
148
	
149
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
150
	// Parity of the corner permutation. This is the same as the parity for the edge permutation of a valid cube.
151
	// parity has values 0 and 1
152
	static short[][] parityMove = { { 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
153
			{ 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0 } };
154

    
155
	// ***********************************Phase 1 and 2 movetable********************************************************
156

    
157
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
158
	// Move table for the four UD-slice edges FR, FL, Bl and BR
159
	// FRtoBRMove < 11880 in phase 1
160
	// FRtoBRMove < 24 in phase 2
161
	// FRtoBRMove = 0 for solved cube
162
	private static byte[] FRtoBR_Move = new byte[2*N_FRtoBR*N_MOVE];
163
	
164
	public static boolean initialize3(Resources res)
165
	{
166
		if( !init[2] )
167
		  {
168
		  try
169
		    {
170
			InputStream is = res.openRawResource(org.distorted.main.R.raw.cube3solver_table3);
171
		    is.read( FRtoBR_Move, 0, 2*N_FRtoBR*N_MOVE);
172
		    }
173
		  catch(Exception ioe)
174
		    {
175
		    System.out.println("error reading table3");
176
                    return true;
177
		    }
178
		
179
		  init[2]=true;
180
		  }
181

    
182
                return false;
183
	}
184

    
185
	public static short getFRtoBR_Move(int a,int b)
186
	{
187
		short upperS = FRtoBR_Move[2*(a*N_MOVE+b)];
188
		short lowerS = FRtoBR_Move[2*(a*N_MOVE+b)+1];
189
		
190
		if( upperS<0 ) upperS+=256;
191
		if( lowerS<0 ) lowerS+=256;
192
		
193
		return  (short)( (upperS<<8) + lowerS );
194
	}
195
	
196
	// *******************************************Phase 1 and 2 movetable************************************************
197

    
198
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
199
	// Move table for permutation of six corners. The positions of the DBL and DRB corners are determined by the parity.
200
	// URFtoDLF < 20160 in phase 1
201
	// URFtoDLF < 20160 in phase 2
202
	// URFtoDLF = 0 for solved cube.
203
	private static byte[] URFtoDLF_Move = new byte[2*N_URFtoDLF*N_MOVE];
204
	
205
	public static boolean initialize4(Resources res)
206
	{
207
		if( !init[3] )
208
		  {
209
		  try
210
		    {
211
			InputStream is = res.openRawResource(org.distorted.main.R.raw.cube3solver_table4);
212
		    is.read( URFtoDLF_Move, 0, 2*N_URFtoDLF*N_MOVE);
213
		    }
214
		  catch(Exception ioe)
215
		    {
216
		    System.out.println("error reading table4");
217
                    return false;
218
		    }
219
		
220
		  init[3]=true;
221
		  }
222

    
223
                return true;
224
	}
225
	
226
	public static short getURFtoDLF_Move(int a,int b)
227
	{
228
		short upperS = URFtoDLF_Move[2*(a*N_MOVE+b)];
229
		short lowerS = URFtoDLF_Move[2*(a*N_MOVE+b)+1];
230
		
231
		if( upperS<0 ) upperS+=256;
232
		if( lowerS<0 ) lowerS+=256;
233
		
234
		return  (short)( (upperS<<8) + lowerS );
235
	}
236
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
237
	// Move table for the permutation of six U-face and D-face edges in phase2. The positions of the DL and DB edges are
238
	// determined by the parity.
239
	// URtoDF < 665280 in phase 1
240
	// URtoDF < 20160 in phase 2
241
	// URtoDF = 0 for solved cube.
242
	private static byte[] URtoDF_Move = new byte[2*N_URtoDF*N_MOVE];
243
	
244
	public static boolean initialize5(Resources res)
245
	{
246
		if( !init[4] )
247
		  {
248
		  try
249
		    {
250
			InputStream is = res.openRawResource(org.distorted.main.R.raw.cube3solver_table5);
251
		    is.read( URtoDF_Move, 0, 2*N_URtoDF*N_MOVE);
252
		    }
253
		  catch(Exception ioe)
254
		    {
255
		    System.out.println("error reading table5");
256
                    return false;
257
		    }
258
		
259
		  init[4]=true;
260
		  }
261

    
262
                return true;
263
	}
264
	
265
	public static short getURtoDF_Move(int a,int b)
266
	{
267
		short upperS = URtoDF_Move[2*(a*N_MOVE+b)];
268
		short lowerS = URtoDF_Move[2*(a*N_MOVE+b)+1];
269
		
270
		if( upperS<0 ) upperS+=256;
271
		if( lowerS<0 ) lowerS+=256;
272
		
273
		return  (short)( (upperS<<8) + lowerS );
274
	}
275
	// **************************helper move tables to compute URtoDF for the beginning of phase2************************
276

    
277
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
278
	// Move table for the three edges UR,UF and UL in phase1.
279
	private static byte[] URtoUL_Move = new byte[2*N_URtoUL*N_MOVE];
280
	
281
	public static boolean initialize6(Resources res)
282
	{
283
		if( !init[5] )
284
		  {
285
		  try
286
		    {
287
			InputStream is = res.openRawResource(org.distorted.main.R.raw.cube3solver_table6);
288
		    is.read( URtoUL_Move, 0, 2*N_URtoUL*N_MOVE);
289
		    }
290
		  catch(Exception ioe)
291
		    {
292
		    System.out.println("error reading table6");
293
                    return false;
294
		    }
295
		
296
		  init[5]=true;
297
		  }
298

    
299
                return true;
300
	}
301

    
302
	public static short getURtoUL_Move(int a,int b)
303
	{
304
		short upperS = URtoUL_Move[2*(a*N_MOVE+b)];
305
		short lowerS = URtoUL_Move[2*(a*N_MOVE+b)+1];
306
		
307
		if( upperS<0 ) upperS+=256;
308
		if( lowerS<0 ) lowerS+=256;
309
		
310
		return  (short)( (upperS<<8) + lowerS );
311
	}
312
	
313
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
314
	// Move table for the three edges UB,DR and DF in phase1.
315
	private static byte[] UBtoDF_Move = new byte[2*N_UBtoDF*N_MOVE];
316
	
317
	public static boolean initialize7(Resources res)
318
	{
319
		if( !init[6] )
320
		  {
321
		  try
322
		    {
323
			InputStream is = res.openRawResource(org.distorted.main.R.raw.cube3solver_table7);
324
		    is.read( UBtoDF_Move, 0, 2*N_UBtoDF*N_MOVE);
325
		    }
326
		  catch(Exception ioe)
327
		    {
328
		    System.out.println("error reading table7");
329
                    return false;
330
		    }
331
		
332
		  init[6]=true;
333
		  }
334

    
335
                return true;
336
	}
337
	
338
	public static short getUBtoDF_Move(int a,int b)
339
	{
340
		short upperS = UBtoDF_Move[2*(a*N_MOVE+b)];
341
		short lowerS = UBtoDF_Move[2*(a*N_MOVE+b)+1];
342
		
343
		if( upperS<0 ) upperS+=256;
344
		if( lowerS<0 ) lowerS+=256;
345
		
346
		return  (short)( (upperS<<8) + lowerS );
347
	}
348
	
349
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
350
	// Table to merge the coordinates of the UR,UF,UL and UB,DR,DF edges at the beginning of phase2
351
	private static byte[] MergeURtoULandUBtoDF = new byte[2*336*336];
352
	
353
	public static boolean initialize8(Resources res)
354
	{
355
		if( !init[7] )
356
		  {
357
		  try
358
		    {
359
			InputStream is = res.openRawResource(org.distorted.main.R.raw.cube3solver_table8);
360
		    is.read( MergeURtoULandUBtoDF, 0, 2*336*336);
361
		    }
362
		  catch(Exception ioe)
363
		    {
364
		    System.out.println("error reading table8");
365
                    return false;
366
		    }
367
		
368
		  init[7]=true;
369
		  }
370

    
371
                return true;
372
	}
373
	
374
	public static short getMergeURtoULandUBtoDF(int a,int b)
375
	{
376
		short upperS = MergeURtoULandUBtoDF[2*(a*336+b)];
377
		short lowerS = MergeURtoULandUBtoDF[2*(a*336+b)+1];
378
		
379
		if( upperS<0 ) upperS+=256;
380
		if( lowerS<0 ) lowerS+=256;
381
		
382
		return  (short)( (upperS<<8) + lowerS );
383
	}
384
	// ****************************************Pruning tables for the search*********************************************
385

    
386
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
387
	// Pruning table for the permutation of the corners and the UD-slice edges in phase2.
388
	// The pruning table entries give a lower estimation for the number of moves to reach the solved cube.
389
	public static byte[] Slice_URFtoDLF_Parity_Prun = new byte[N_SLICE2 * N_URFtoDLF * N_PARITY / 2];
390
	
391
	public static boolean initialize9(Resources res)
392
	{
393
		if( !init[8] )
394
		  {
395
		  try
396
		    {
397
			  InputStream is = res.openRawResource(org.distorted.main.R.raw.cube3solver_table9);
398
		    is.read( Slice_URFtoDLF_Parity_Prun, 0, N_SLICE2 * N_URFtoDLF * N_PARITY / 2);
399
		    }
400
		  catch(Exception ioe)
401
		    {
402
		    System.out.println("error reading table9");
403
                    return false;
404
		    }
405
		
406
		  init[8]=true;
407
		  }
408

    
409
    return true;
410
	}
411

    
412
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
413
	// Pruning table for the permutation of the edges in phase2.
414
	// The pruning table entries give a lower estimation for the number of moves to reach the solved cube.
415
	public static byte[] Slice_URtoDF_Parity_Prun = new byte[N_SLICE2 * N_URtoDF * N_PARITY / 2];
416
	
417
	public static boolean initialize10(Resources res)
418
	{
419
		if( !init[9] )
420
		  {
421
		  try
422
		    {
423
			InputStream is = res.openRawResource(org.distorted.main.R.raw.cube3solver_table10);
424
		    is.read( Slice_URtoDF_Parity_Prun, 0, N_SLICE2 * N_URtoDF * N_PARITY / 2);
425
		    }
426
		  catch(Exception ioe)
427
		    {
428
		    System.out.println("error reading table10");
429
                    return false;
430
		    }
431
		
432
		  init[9]=true;
433
		  }
434

    
435
                return true;
436
	}
437

    
438
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
439
	// Pruning table for the twist of the corners and the position (not permutation) of the UD-slice edges in phase1
440
	// The pruning table entries give a lower estimation for the number of moves to reach the H-subgroup.
441
	public static byte[] Slice_Twist_Prun = new byte[N_SLICE1 * N_TWIST / 2 + 1];
442
	
443
	public static boolean initialize11(Resources res)
444
	{
445
		if( !init[10] )
446
		  {
447
		  try
448
		    {
449
			InputStream is = res.openRawResource(org.distorted.main.R.raw.cube3solver_table11);
450
		    is.read( Slice_Twist_Prun, 0, N_SLICE1 * N_TWIST / 2 + 1);
451
		    }
452
		  catch(Exception ioe)
453
		    {
454
		    System.out.println("error reading table11");
455
                    return false;
456
		    }
457
		
458
		  init[10]=true;
459
		  }
460

    
461
                return true;
462
	}
463

    
464
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
465
	// Pruning table for the flip of the edges and the position (not permutation) of the UD-slice edges in phase1
466
	// The pruning table entries give a lower estimation for the number of moves to reach the H-subgroup.
467
	public static byte[] Slice_Flip_Prun = new byte[N_SLICE1 * N_FLIP / 2];
468
	
469
	public static boolean initialize12(Resources res)
470
	{
471
		if( !init[11] )
472
		  {
473
		  try
474
		    {
475
			InputStream is = res.openRawResource(org.distorted.main.R.raw.cube3solver_table12);
476
		    is.read( Slice_Flip_Prun, 0, N_SLICE1 * N_FLIP / 2);
477
		    }
478
		  catch(Exception ioe)
479
		    {
480
		    System.out.println("error reading table12");
481
                    return false;
482
		    }
483
		
484
		  init[11]=true;
485
		  }
486

    
487
                return true;
488
	}
489

    
490
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
491
	// Set pruning value in table. Two values are stored in one byte.
492
	static void setPruning(byte[] table, int index, byte value) {
493
		if ((index & 1) == 0)
494
			table[index / 2] &= 0xf0 | value;
495
		else
496
			table[index / 2] &= 0x0f | (value << 4);
497
	}
498

    
499
	// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
500
	// Extract pruning value
501
	static byte getPruning(byte[] table, int index) {
502
		if ((index & 1) == 0)
503
			return (byte) (table[index / 2] & 0x0f);
504
		else
505
			return (byte) ((table[index / 2] & 0xf0) >>> 4);
506
	}
507
}
(2-2/9)