Project

General

Profile

« Previous | Next » 

Revision dfae472b

Added by Leszek Koltunski over 2 years ago

Rename solver files.

View differences:

src/main/java/org/distorted/solvers/SolverMain.java
27 27
import org.distorted.main.R;
28 28
import org.distorted.screens.ScreenList;
29 29
import org.distorted.screens.RubikScreenSolver;
30
import org.distorted.solvers.cube3.RubikSolverSearch;
30
import org.distorted.solvers.cube3.SolverSearch;
31 31

  
32 32
///////////////////////////////////////////////////////////////////////////////////////////////////
33 33

  
......
73 73
    {
74 74
    String result;
75 75

  
76
    RubikSolverSearch.prepare(mRes);
76
    SolverSearch.prepare(mRes);
77 77
    String objectPosition = prepareCube3position();
78
    result = RubikSolverSearch.solution(objectPosition, 24, 20);
78
    result = SolverSearch.solution(objectPosition, 24, 20);
79 79

  
80 80
    if (result.contains("Error"))
81 81
      {
src/main/java/org/distorted/solvers/cube3/RubikSolverColor.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2008 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.solvers.cube3;
21

  
22
///////////////////////////////////////////////////////////////////////////////////////////////////
23
// Names the colors of the cube facelets
24

  
25
class RubikSolverColor
26
  {
27
  public static final int U=0;
28
  public static final int R=1;
29
  public static final int F=2;
30
  public static final int D=3;
31
  public static final int L=4;
32
  public static final int B=5;
33

  
34
///////////////////////////////////////////////////////////////////////////////////////////////////
35

  
36
  public static String toString(int i)
37
    {
38
    switch(i)
39
      {
40
      case U: return "U";
41
      case R: return "R";
42
      case F: return "F";
43
      case D: return "D";
44
      case L: return "L";
45
      case B: return "B";
46
      default: return "?";
47
      }
48
    }
49

  
50
///////////////////////////////////////////////////////////////////////////////////////////////////
51

  
52
  public static int toInt(String s)
53
    {
54
	  switch(s.charAt(0))
55
      {
56
      case 'U': return U;
57
      case 'R': return R;
58
      case 'F': return F;
59
      case 'D': return D;
60
      case 'L': return L;
61
      case 'B': return B;
62
      default: return -1;
63
      }  
64
    }
65
  }
src/main/java/org/distorted/solvers/cube3/RubikSolverCoordCube.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2008 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.solvers.cube3;
21

  
22
import java.io.InputStream;
23
import android.content.res.Resources;
24

  
25
///////////////////////////////////////////////////////////////////////////////////////////////////
26

  
27
class RubikSolverCoordCube
28
{
29
	static final short N_TWIST    = 2187;  // 3^7 possible corner orientations
30
	static final short N_FLIP     = 2048;  // 2^11 possible edge flips
31
	static final short N_SLICE1   = 495;   // 12 choose 4 possible positions of FR,FL,BL,BR edges
32
	static final short N_SLICE2   = 24;    // 4! permutations of FR,FL,BL,BR edges in phase2
33
	static final short N_PARITY   = 2;     // 2 possible corner parities
34
	static final short N_URFtoDLF = 20160; // 8!/(8-6)! permutation of URF,UFL,ULB,UBR,DFR,DLF corners
35
	static final short N_FRtoBR   = 11880; // 12!/(12-4)! permutation of FR,FL,BL,BR edges
36
	static final short N_URtoUL   = 1320;  // 12!/(12-3)! permutation of UR,UF,UL edges
37
	static final short N_UBtoDF   = 1320;  // 12!/(12-3)! permutation of UB,DR,DF edges
38
	static final short N_URtoDF   = 20160; // 8!/(8-6)! permutation of UR,UF,UL,UB,DR,DF edges in phase2
39
	static final int N_URFtoDLB   = 40320; // 8! permutations of the corners
40
	static final int N_URtoBR     = 479001600;// 8! permutations of the corners
41
	static final short N_MOVE     = 18;
42

  
43
	// All coordinates are 0 for a solved cube except for UBtoDF, which is 114
44
	short twist;
45
	short flip;
46
	short parity;
47
	short FRtoBR;
48
	short URFtoDLF;
49
	short URtoUL;
50
	short UBtoDF;
51
	int URtoDF;
52

  
53
	private static final boolean[] init = new boolean[12];
54
	
55
	static 
56
	  {
57
	  for(int i=0; i<12; i++ ) init[i] = false;	
58
	  }
59

  
60
  // Phase 1 move tables
61
  // Move table for the twists of the corners. twist < 2187 in phase 2; twist = 0 in phase 2.
62
	private static final byte[] twistMove = new byte[2*N_TWIST*N_MOVE];
63

  
64
	// Move table for the flips of the edges. flip < 2048 in phase 1; flip = 0 in phase 2.
65
	private static final byte[] flipMove  = new byte[2*N_FLIP*N_MOVE];
66

  
67
  // Parity of the corner permutation. This is the same as the parity for the edge permutation of a valid cube.
68
  // parity has values 0 and 1
69
	static short[][] parityMove = {
70
	                                { 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
71
			                            { 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0 }
72
			                          };
73

  
74
  // Phase 1 and 2 movetable
75
  // Move table for the four UD-slice edges FR, FL, Bl and BR
76
  // FRtoBRMove < 11880 in phase 1; FRtoBRMove < 24 in phase 2; FRtoBRMove = 0 for solved cube
77
	private static final byte[] FRtoBR_Move = new byte[2*N_FRtoBR*N_MOVE];
78

  
79
	// Phase 1 and 2 movetable
80
	// Move table for permutation of six corners. The positions of the DBL and DRB corners are determined by the parity.
81
	// URFtoDLF < 20160 in phase 1; URFtoDLF < 20160 in phase 2; URFtoDLF = 0 for solved cube.
82
	private static final byte[] URFtoDLF_Move = new byte[2*N_URFtoDLF*N_MOVE];
83

  
84
	// Move table for the permutation of six U-face and D-face edges in phase2. The positions of the DL and DB edges are
85
	// determined by the parity.
86
	// URtoDF < 665280 in phase 1; URtoDF < 20160 in phase 2; URtoDF = 0 for solved cube.
87
	private static final byte[] URtoDF_Move = new byte[2*N_URtoDF*N_MOVE];
88

  
89
	// Helper move tables to compute URtoDF for the beginning of phase2
90
	// Move table for the three edges UR,UF and UL in phase1.
91
	private static final byte[] URtoUL_Move = new byte[2*N_URtoUL*N_MOVE];
92

  
93
	// Move table for the three edges UB,DR and DF in phase1.
94
	private static final byte[] UBtoDF_Move = new byte[2*N_UBtoDF*N_MOVE];
95

  
96
	// Table to merge the coordinates of the UR,UF,UL and UB,DR,DF edges at the beginning of phase2
97
	private static final byte[] MergeURtoULandUBtoDF = new byte[2*336*336];
98

  
99
	// Pruning tables for the search
100
	// Pruning table for the permutation of the corners and the UD-slice edges in phase2.
101
	// The pruning table entries give a lower estimation for the number of moves to reach the solved cube.
102
	public static byte[] Slice_URFtoDLF_Parity_Prun = new byte[N_SLICE2*N_URFtoDLF*N_PARITY / 2];
103

  
104
	// Pruning table for the permutation of the edges in phase2.
105
	// The pruning table entries give a lower estimation for the number of moves to reach the solved cube.
106
	public static byte[] Slice_URtoDF_Parity_Prun = new byte[N_SLICE2*N_URtoDF*N_PARITY / 2];
107

  
108
	// Pruning table for the twist of the corners and the position (not permutation) of the UD-slice edges in phase1
109
	// The pruning table entries give a lower estimation for the number of moves to reach the H-subgroup.
110
	public static byte[] Slice_Twist_Prun = new byte[N_SLICE1*N_TWIST / 2 + 1];
111

  
112
	// Pruning table for the flip of the edges and the position (not permutation) of the UD-slice edges in phase1
113
	// The pruning table entries give a lower estimation for the number of moves to reach the H-subgroup.
114
	public static byte[] Slice_Flip_Prun = new byte[N_SLICE1*N_FLIP / 2];
115

  
116
  private static final int[] resourceTable = new int[]
117
			{
118
			org.distorted.main.R.raw.cube3solver_table1,
119
			org.distorted.main.R.raw.cube3solver_table2,
120
			org.distorted.main.R.raw.cube3solver_table3,
121
			org.distorted.main.R.raw.cube3solver_table4,
122
			org.distorted.main.R.raw.cube3solver_table5,
123
			org.distorted.main.R.raw.cube3solver_table6,
124
			org.distorted.main.R.raw.cube3solver_table7,
125
			org.distorted.main.R.raw.cube3solver_table8,
126
			org.distorted.main.R.raw.cube3solver_table9,
127
			org.distorted.main.R.raw.cube3solver_table10,
128
			org.distorted.main.R.raw.cube3solver_table11,
129
			org.distorted.main.R.raw.cube3solver_table12
130
			};
131

  
132
  private static final byte[][] tableOfTables = new byte[][]
133
			{
134
			twistMove,
135
			flipMove,
136
			FRtoBR_Move,
137
			URFtoDLF_Move,
138
			URtoDF_Move,
139
			URtoUL_Move,
140
			UBtoDF_Move,
141
			MergeURtoULandUBtoDF,
142
			Slice_URFtoDLF_Parity_Prun,
143
			Slice_URtoDF_Parity_Prun,
144
			Slice_Twist_Prun,
145
			Slice_Flip_Prun
146
			};
147

  
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149
// Generate a CoordCube from a CubieCube
150

  
151
	RubikSolverCoordCube(RubikSolverCubieCube c)
152
	  {
153
		twist    = c.getTwist();
154
		flip     = c.getFlip();
155
		parity   = c.cornerParity();
156
		FRtoBR   = c.getFRtoBR();
157
		URFtoDLF = c.getURFtoDLF();
158
		URtoUL   = c.getURtoUL();
159
		UBtoDF   = c.getUBtoDF();
160
		URtoDF   = c.getURtoDF();// only needed in phase2
161
	  }
162

  
163
///////////////////////////////////////////////////////////////////////////////////////////////////
164

  
165
	static byte getPruning(byte[] table, int index)
166
	  {
167
	  byte ret = table[index/2];
168
	  return (byte) ( ((index&1)==0) ? (ret&0x0f) : ((ret&0xf0)>>>4) );
169
	  }
170

  
171
///////////////////////////////////////////////////////////////////////////////////////////////////
172

  
173
	public static short getTwistMove(int a,int b)
174
	  {
175
	  return getTable(a,b,twistMove,N_MOVE);
176
	  }
177

  
178
///////////////////////////////////////////////////////////////////////////////////////////////////
179

  
180
	public static short getFlipMove(int a,int b)
181
	  {
182
	  return getTable(a,b,flipMove,N_MOVE);
183
	  }
184

  
185
///////////////////////////////////////////////////////////////////////////////////////////////////
186

  
187
	public static short getFRtoBR_Move(int a,int b)
188
	  {
189
	  return getTable(a,b,FRtoBR_Move,N_MOVE);
190
	  }
191

  
192
///////////////////////////////////////////////////////////////////////////////////////////////////
193

  
194
	public static short getURFtoDLF_Move(int a,int b)
195
	  {
196
	  return getTable(a,b,URFtoDLF_Move,N_MOVE);
197
	  }
198

  
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200

  
201
	public static short getURtoDF_Move(int a,int b)
202
	  {
203
	  return getTable(a,b,URtoDF_Move,N_MOVE);
204
	  }
205

  
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207

  
208
	public static short getURtoUL_Move(int a,int b)
209
	  {
210
	  return getTable(a,b,URtoUL_Move,N_MOVE);
211
	  }
212

  
213
///////////////////////////////////////////////////////////////////////////////////////////////////
214

  
215
	public static short getUBtoDF_Move(int a,int b)
216
	  {
217
	  return getTable(a,b,UBtoDF_Move,N_MOVE);
218
	  }
219

  
220
///////////////////////////////////////////////////////////////////////////////////////////////////
221

  
222
	public static short getMergeURtoULandUBtoDF(int a,int b)
223
	  {
224
	  return getTable(a,b,MergeURtoULandUBtoDF,336);
225
	  }
226

  
227
///////////////////////////////////////////////////////////////////////////////////////////////////
228

  
229
	private static short getTable(int a,int b, byte[] table, int size)
230
	  {
231
		short upperS = table[2*(a*size+b)];
232
		short lowerS = table[2*(a*size+b)+1];
233

  
234
		if( upperS<0 ) upperS+=256;
235
		if( lowerS<0 ) lowerS+=256;
236

  
237
		return  (short)( (upperS<<8) + lowerS );
238
	  }
239

  
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241

  
242
	public static void initialize(Resources res, int index)
243
		{
244
		if( !init[index] )
245
		  {
246
		  try
247
		    {
248
		    byte[] table = tableOfTables[index];
249
			  InputStream is = res.openRawResource(resourceTable[index]);
250
		    is.read( table, 0, table.length);
251
		    }
252
		  catch(Exception ioe)
253
		    {
254
		    System.out.println("error reading table"+index);
255
		    }
256

  
257
		  init[index]=true;
258
		  }
259
		}
260
}
src/main/java/org/distorted/solvers/cube3/RubikSolverCorner.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2008 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.solvers.cube3;
21

  
22
///////////////////////////////////////////////////////////////////////////////////////////////////
23
//The names of the corner positions of the cube. Corner URF e.g., has an U(p), a R(ight) and a F(ront) facelet
24

  
25
class RubikSolverCorner
26
  {
27
  public static final int URF =0;
28
  public static final int UFL =1;
29
  public static final int ULB =2;
30
  public static final int UBR =3;
31
  public static final int DFR =4;
32
  public static final int DLF =5;
33
  public static final int DBL =6;
34
  public static final int DRB =7;
35
  }
src/main/java/org/distorted/solvers/cube3/RubikSolverCubieCube.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2008 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.solvers.cube3;
21

  
22
///////////////////////////////////////////////////////////////////////////////////////////////////
23

  
24
class RubikSolverCubieCube
25
  {
26
  private static final int[][] cnk     = new int[12][7];
27
  private static final int[] tmpEdge6  = new int[6];
28
  private static final int[] tmpEdge4  = new int[4];
29
  private static final int[] tmpEdge3  = new int[3];
30
  private static final int[] tmpCorner6= new int[6];
31

  
32
  // corner permutation
33
  int[] cp = { RubikSolverCorner.URF, RubikSolverCorner.UFL, RubikSolverCorner.ULB, RubikSolverCorner.UBR, RubikSolverCorner.DFR, RubikSolverCorner.DLF, RubikSolverCorner.DBL, RubikSolverCorner.DRB };
34

  
35
  // corner orientation
36
  byte[] co = { 0, 0, 0, 0, 0, 0, 0, 0 };
37

  
38
  // edge permutation
39
  int[] ep = { RubikSolverEdge.UR, RubikSolverEdge.UF, RubikSolverEdge.UL, RubikSolverEdge.UB, RubikSolverEdge.DR, RubikSolverEdge.DF, RubikSolverEdge.DL, RubikSolverEdge.DB, RubikSolverEdge.FR, RubikSolverEdge.FL, RubikSolverEdge.BL, RubikSolverEdge.BR };
40

  
41
  // edge orientation
42
  byte[] eo = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
43

  
44
  // Moves on the cubie level
45
  private static final int[]  cpU = { RubikSolverCorner.UBR, RubikSolverCorner.URF, RubikSolverCorner.UFL, RubikSolverCorner.ULB, RubikSolverCorner.DFR, RubikSolverCorner.DLF, RubikSolverCorner.DBL, RubikSolverCorner.DRB };
46
  private static final byte[] coU = { 0, 0, 0, 0, 0, 0, 0, 0 };
47
  private static final int[]  epU = { RubikSolverEdge.UB, RubikSolverEdge.UR, RubikSolverEdge.UF, RubikSolverEdge.UL, RubikSolverEdge.DR, RubikSolverEdge.DF, RubikSolverEdge.DL, RubikSolverEdge.DB, RubikSolverEdge.FR, RubikSolverEdge.FL, RubikSolverEdge.BL, RubikSolverEdge.BR };
48
  private static final byte[] eoU = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
49

  
50
  private static final int[]  cpR = { RubikSolverCorner.DFR, RubikSolverCorner.UFL, RubikSolverCorner.ULB, RubikSolverCorner.URF, RubikSolverCorner.DRB, RubikSolverCorner.DLF, RubikSolverCorner.DBL, RubikSolverCorner.UBR };
51
  private static final byte[] coR = { 2, 0, 0, 1, 1, 0, 0, 2 };
52
  private static final int[]  epR = { RubikSolverEdge.FR, RubikSolverEdge.UF, RubikSolverEdge.UL, RubikSolverEdge.UB, RubikSolverEdge.BR, RubikSolverEdge.DF, RubikSolverEdge.DL, RubikSolverEdge.DB, RubikSolverEdge.DR, RubikSolverEdge.FL, RubikSolverEdge.BL, RubikSolverEdge.UR };
53
  private static final byte[] eoR = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
54

  
55
  private static final int[]  cpF = { RubikSolverCorner.UFL, RubikSolverCorner.DLF, RubikSolverCorner.ULB, RubikSolverCorner.UBR, RubikSolverCorner.URF, RubikSolverCorner.DFR, RubikSolverCorner.DBL, RubikSolverCorner.DRB };
56
  private static final byte[] coF = { 1, 2, 0, 0, 2, 1, 0, 0 };
57
  private static final int[]  epF = { RubikSolverEdge.UR, RubikSolverEdge.FL, RubikSolverEdge.UL, RubikSolverEdge.UB, RubikSolverEdge.DR, RubikSolverEdge.FR, RubikSolverEdge.DL, RubikSolverEdge.DB, RubikSolverEdge.UF, RubikSolverEdge.DF, RubikSolverEdge.BL, RubikSolverEdge.BR };
58
  private static final byte[] eoF = { 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0 };
59

  
60
  private static final int[]  cpD = { RubikSolverCorner.URF, RubikSolverCorner.UFL, RubikSolverCorner.ULB, RubikSolverCorner.UBR, RubikSolverCorner.DLF, RubikSolverCorner.DBL, RubikSolverCorner.DRB, RubikSolverCorner.DFR };
61
  private static final byte[] coD = { 0, 0, 0, 0, 0, 0, 0, 0 };
62
  private static final int[]  epD = { RubikSolverEdge.UR, RubikSolverEdge.UF, RubikSolverEdge.UL, RubikSolverEdge.UB, RubikSolverEdge.DF, RubikSolverEdge.DL, RubikSolverEdge.DB, RubikSolverEdge.DR, RubikSolverEdge.FR, RubikSolverEdge.FL, RubikSolverEdge.BL, RubikSolverEdge.BR };
63
  private static final byte[] eoD = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
64

  
65
  private static final int[]  cpL = { RubikSolverCorner.URF, RubikSolverCorner.ULB, RubikSolverCorner.DBL, RubikSolverCorner.UBR, RubikSolverCorner.DFR, RubikSolverCorner.UFL, RubikSolverCorner.DLF, RubikSolverCorner.DRB };
66
  private static final byte[] coL = { 0, 1, 2, 0, 0, 2, 1, 0 };
67
  private static final int[]  epL = { RubikSolverEdge.UR, RubikSolverEdge.UF, RubikSolverEdge.BL, RubikSolverEdge.UB, RubikSolverEdge.DR, RubikSolverEdge.DF, RubikSolverEdge.FL, RubikSolverEdge.DB, RubikSolverEdge.FR, RubikSolverEdge.UL, RubikSolverEdge.DL, RubikSolverEdge.BR };
68
  private static final byte[] eoL = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
69

  
70
  private static final int[]  cpB = { RubikSolverCorner.URF, RubikSolverCorner.UFL, RubikSolverCorner.UBR, RubikSolverCorner.DRB, RubikSolverCorner.DFR, RubikSolverCorner.DLF, RubikSolverCorner.ULB, RubikSolverCorner.DBL };
71
  private static final byte[] coB = { 0, 0, 1, 2, 0, 0, 2, 1 };
72
  private static final int[]  epB = { RubikSolverEdge.UR, RubikSolverEdge.UF, RubikSolverEdge.UL, RubikSolverEdge.BR, RubikSolverEdge.DR, RubikSolverEdge.DF, RubikSolverEdge.DL, RubikSolverEdge.BL, RubikSolverEdge.FR, RubikSolverEdge.FL, RubikSolverEdge.UB, RubikSolverEdge.DB };
73
  private static final byte[] eoB = { 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1 };
74

  
75
  // this CubieCube array represents the 6 basic cube moves
76
  static RubikSolverCubieCube[] moveCube = new RubikSolverCubieCube[6];
77

  
78
  static
79
    {
80
    moveCube[0] = new RubikSolverCubieCube();
81
    moveCube[0].cp = cpU;
82
    moveCube[0].co = coU;
83
    moveCube[0].ep = epU;
84
    moveCube[0].eo = eoU;
85

  
86
    moveCube[1] = new RubikSolverCubieCube();
87
    moveCube[1].cp = cpR;
88
    moveCube[1].co = coR;
89
    moveCube[1].ep = epR;
90
    moveCube[1].eo = eoR;
91

  
92
    moveCube[2] = new RubikSolverCubieCube();
93
    moveCube[2].cp = cpF;
94
    moveCube[2].co = coF;
95
    moveCube[2].ep = epF;
96
    moveCube[2].eo = eoF;
97

  
98
    moveCube[3] = new RubikSolverCubieCube();
99
    moveCube[3].cp = cpD;
100
    moveCube[3].co = coD;
101
    moveCube[3].ep = epD;
102
    moveCube[3].eo = eoD;
103

  
104
    moveCube[4] = new RubikSolverCubieCube();
105
    moveCube[4].cp = cpL;
106
    moveCube[4].co = coL;
107
    moveCube[4].ep = epL;
108
    moveCube[4].eo = eoL;
109

  
110
    moveCube[5] = new RubikSolverCubieCube();
111
    moveCube[5].cp = cpB;
112
    moveCube[5].co = coB;
113
    moveCube[5].ep = epB;
114
    moveCube[5].eo = eoB;
115
    }
116

  
117
  static
118
    {
119
    for(int n=0; n<12; n++)
120
      for(int k=0; k<7; k++)
121
	      cnk[n][k] = -1;
122
    }
123

  
124
///////////////////////////////////////////////////////////////////////////////////////////////////
125

  
126
  RubikSolverCubieCube()
127
    {
128
    }
129

  
130
///////////////////////////////////////////////////////////////////////////////////////////////////
131
// n choose k
132

  
133
  static int Cnk(int n, int k)
134
    {
135
    if( cnk[n][k]<0 )
136
      {
137
      int i, j, s;
138

  
139
      if (k > n  ) { cnk[n][k]=0; return 0; }
140
      if (k > n/2) k = n-k;
141
		  
142
      for(s=1, i=n, j=1; i!=n-k; i--, j++)
143
        {
144
	      s *= i;
145
	      s /= j;
146
        }
147
      cnk[n][k]= s;
148
      }
149
		
150
    return cnk[n][k];
151
    }
152

  
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154
// Left rotation of all array elements between 0 and r
155

  
156
  static void rotateLeft(int[] arr, int r)
157
    {
158
    int tmp = arr[0];
159
    for (int i=0; i<r; i++) arr[i] = arr[i + 1];
160
    arr[r] = tmp;
161
    }
162

  
163
///////////////////////////////////////////////////////////////////////////////////////////////////
164
// Right rotation of all array elements between l and r
165

  
166
  static void rotateRight(int[] arr, int r)
167
    {
168
    int tmp = arr[r];
169
    for (int i = r; i > 0; i--) arr[i] = arr[i - 1];
170
    arr[0] = tmp;
171
    }
172

  
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174
// return cube in facelet representation
175

  
176
  RubikSolverFaceCube toFaceCube()
177
    {
178
    RubikSolverFaceCube fcRet = new RubikSolverFaceCube();
179

  
180
    for(int c = RubikSolverCorner.URF; c<= RubikSolverCorner.DRB; c++)
181
      {
182
      int j = cp[c];   // corner cubie with index j is at corner position with index i
183
      byte ori = co[c];// orientation of this cubie
184

  
185
      for( int n=0; n<3; n++)
186
        fcRet.f[RubikSolverFaceCube.cornerFacelet[c][(n + ori) % 3]] = RubikSolverFaceCube.cornerColor[j][n];
187
      }
188

  
189
    for(int e = RubikSolverEdge.UR; e<= RubikSolverEdge.BR; e++)
190
      {
191
      int j = ep[e];   // edge cubie with index j is at edge position with index i
192
      byte ori = eo[e];// orientation of this cubie
193

  
194
      for( int n=0; n<2; n++)
195
	      fcRet.f[RubikSolverFaceCube.edgeFacelet[e][(n + ori) % 2]] = RubikSolverFaceCube.edgeColor[j][n];
196
      }
197

  
198
    return fcRet;
199
    }
200

  
201
///////////////////////////////////////////////////////////////////////////////////////////////////
202
// return the twist of the 8 corners. 0 <= twist < 3^7
203

  
204
  short getTwist()
205
    {
206
    short ret = 0;
207

  
208
    for(int i = RubikSolverCorner.URF; i< RubikSolverCorner.DRB; i++)
209
      ret = (short) (3*ret+co[i]);
210

  
211
    return ret;
212
    }
213

  
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215

  
216
  void setTwist(short twist)
217
    {
218
    int twistParity = 0;
219

  
220
    for (int i = RubikSolverCorner.DRB-1; i>= RubikSolverCorner.URF; i--)
221
      {
222
      twistParity += co[i] = (byte) (twist%3);
223
      twist /= 3;
224
      }
225
    co[RubikSolverCorner.DRB] = (byte) ((3 - twistParity % 3) % 3);
226
    }
227

  
228
///////////////////////////////////////////////////////////////////////////////////////////////////
229
// return the flip of the 12 edges. 0<= flip < 2^11
230

  
231
  short getFlip()
232
    {
233
    short ret = 0;
234

  
235
    for (int i = RubikSolverEdge.UR; i< RubikSolverEdge.BR; i++)
236
      ret = (short) (2 * ret + eo[i]);
237

  
238
    return ret;
239
    }
240

  
241
///////////////////////////////////////////////////////////////////////////////////////////////////
242

  
243
  void setFlip(short flip)
244
    {
245
    int flipParity = 0;
246

  
247
    for (int i = RubikSolverEdge.BR-1; i>= RubikSolverEdge.UR; i--)
248
      {
249
      flipParity += eo[i] = (byte) (flip % 2);
250
      flip /= 2;
251
      }
252
    eo[RubikSolverEdge.BR] = (byte) ((2 - flipParity % 2) % 2);
253
    }
254

  
255
///////////////////////////////////////////////////////////////////////////////////////////////////
256
// Parity of the corner permutation
257

  
258
  short cornerParity()
259
    {
260
    int s = 0;
261

  
262
    for (int i = RubikSolverCorner.DRB; i>= RubikSolverCorner.URF+1; i--)
263
      for (int j = i - 1; j >= RubikSolverCorner.URF; j--)
264
        if (cp[j] > cp[i]) s++;
265

  
266
    return (short) (s%2);
267
    }
268

  
269
///////////////////////////////////////////////////////////////////////////////////////////////////
270
// Parity of the edges permutation. Parity of corners and edges are the same if the cube is solvable.
271

  
272
  short edgeParity()
273
    {
274
    int s = 0;
275

  
276
    for (int i = RubikSolverEdge.BR; i >= RubikSolverEdge.UR+1; i--)
277
      for (int j = i - 1; j >= RubikSolverEdge.UR; j--)
278
        if (ep[j] > ep[i]) s++;
279

  
280
    return (short) (s%2);
281
    }
282

  
283
///////////////////////////////////////////////////////////////////////////////////////////////////
284
// permutation of the UD-slice edges FR,FL,BL and BR
285

  
286
  short getFRtoBR()
287
    {
288
    int a = 0, x = 0;
289

  
290
    // compute the index a < (12 choose 4) and the permutation array perm.
291
    for(int j = RubikSolverEdge.BR; j >= RubikSolverEdge.UR; j--)
292
      if (RubikSolverEdge.FR <= ep[j] && ep[j] <= RubikSolverEdge.BR)
293
        {
294
        a += Cnk(11-j, x+1);
295
	      tmpEdge4[3-x++] = ep[j];
296
	      }
297

  
298
    int b = 0;
299
    for( int j=3; j>0; j--) // compute the index b < 4! for the permutation in perm
300
      {
301
      int k = 0;
302
      while (tmpEdge4[j] != j+8)
303
        {
304
	      rotateLeft(tmpEdge4,j);
305
	      k++;
306
        }
307
      b = (j+1)*b + k;
308
      }
309

  
310
    return (short) (24*a+b);
311
    }
312

  
313
///////////////////////////////////////////////////////////////////////////////////////////////////
314
// Permutation of all corners except DBL and DRB
315

  
316
  short getURFtoDLF()
317
    {
318
    int a = 0, x = 0;
319

  
320
    // compute the index a < (8 choose 6) and the corner permutation.
321
    for(int j = RubikSolverCorner.URF; j<= RubikSolverCorner.DRB; j++)
322
      if( cp[j] <= RubikSolverCorner.DLF )
323
        {
324
	      a += Cnk(j, x+1);
325
	      tmpCorner6[x++] = cp[j];
326
	      }
327

  
328
    int b = 0;
329

  
330
    for( int j=5; j>0; j--) // compute the index b < 6! for the permutation in corner6
331
      {
332
      int k = 0;
333

  
334
      while (tmpCorner6[j] != j)
335
        {
336
	      rotateLeft(tmpCorner6,j);
337
	      k++;
338
	      }
339
      b = (j+1)*b + k;
340
      }
341

  
342
    return (short) (720*a+b);
343
    }
344

  
345
///////////////////////////////////////////////////////////////////////////////////////////////////
346
// Permutation of the six edges UR,UF,UL,UB,DR,DF.
347

  
348
  int getURtoDF()
349
    {
350
    int a = 0, x = 0;
351
    // compute the index a < (12 choose 6) and the edge permutation.
352

  
353
    for(int j = RubikSolverEdge.UR; j<= RubikSolverEdge.BR; j++)
354
      if (ep[j] <= RubikSolverEdge.DF)
355
        {
356
	      a += Cnk(j, x+1);
357
	      tmpEdge6[x++] = ep[j];
358
	      }
359

  
360
    int b = 0;
361

  
362
    for (int j=5; j>0; j--)// compute the index b < 6! for the permutation in edge6
363
      {
364
      int k = 0;
365

  
366
      while (tmpEdge6[j] != j)
367
        {
368
	      rotateLeft(tmpEdge6,j);
369
	      k++;
370
	      }
371
      b = (j+1)*b + k;
372
      }
373
    return 720*a+b;
374
    }
375

  
376
///////////////////////////////////////////////////////////////////////////////////////////////////
377
// Permutation of the three edges UR,UF,UL
378

  
379
  short getURtoUL()
380
    {
381
    int a=0, x=0;
382

  
383
    // compute the index a < (12 choose 3) and the edge permutation.
384
    for(int j = RubikSolverEdge.UR; j<= RubikSolverEdge.BR; j++)
385
      if (ep[j] <= RubikSolverEdge.UL)
386
        {
387
	      a += Cnk(j, x + 1);
388
	      tmpEdge3[x++] = ep[j];
389
	      }
390

  
391
    int b=0;
392

  
393
    for( int j=2; j>0; j--)// compute the index b < 3! for the permutation in edge3
394
      {
395
      int k = 0;
396
      while (tmpEdge3[j] != j)
397
        {
398
	      rotateLeft(tmpEdge3,j);
399
	      k++;
400
	      }
401
      b = (j+1)*b+k;
402
      }
403
	
404
    return (short) (6*a+b);
405
    }
406

  
407
///////////////////////////////////////////////////////////////////////////////////////////////////
408
// Permutation of the three edges UB,DR,DF
409

  
410
  short getUBtoDF()
411
    {
412
    int a=0, x=0;
413
    // compute the index a < (12 choose 3) and the edge permutation.
414

  
415
    for(int j = RubikSolverEdge.UR; j<= RubikSolverEdge.BR; j++)
416
      if (RubikSolverEdge.UB <= ep[j] && ep[j] <= RubikSolverEdge.DF)
417
        {
418
	      a += Cnk(j, x+1);
419
	      tmpEdge3[x++] = ep[j];
420
	      }
421

  
422
    int b=0;
423

  
424
    for (int j=2; j>0; j--) // compute the index b < 3! for the permutation in edge3
425
      {
426
      int k=0;
427

  
428
      while (tmpEdge3[j] != RubikSolverEdge.UB + j)
429
        {
430
	      rotateLeft(tmpEdge3,j);
431
	      k++;
432
	      }
433
      b = (j+1)*b+k;
434
      }
435

  
436
    return (short) (6*a+b);
437
    }
438

  
439
///////////////////////////////////////////////////////////////////////////////////////////////////
440

  
441
  void setURFtoDLB(int idx)
442
    {
443
    int[] perm = { RubikSolverCorner.URF, RubikSolverCorner.UFL, RubikSolverCorner.ULB, RubikSolverCorner.UBR, RubikSolverCorner.DFR, RubikSolverCorner.DLF, RubikSolverCorner.DBL, RubikSolverCorner.DRB };
444
    int k;
445

  
446
    for( int j=1; j<8; j++)
447
      {
448
      k = idx % (j+1);
449
      idx /= j+1;
450
      while (k-- > 0) rotateRight(perm,j);
451
      }
452

  
453
    int x=7;// set corners
454

  
455
    for( int j=7; j>=0; j--) cp[j] = perm[x--];
456
    }
457

  
458
///////////////////////////////////////////////////////////////////////////////////////////////////
459

  
460
  void setURtoBR(int idx)
461
    {
462
    int[] perm = { RubikSolverEdge.UR, RubikSolverEdge.UF, RubikSolverEdge.UL, RubikSolverEdge.UB, RubikSolverEdge.DR, RubikSolverEdge.DF, RubikSolverEdge.DL, RubikSolverEdge.DB, RubikSolverEdge.FR, RubikSolverEdge.FL, RubikSolverEdge.BL, RubikSolverEdge.BR };
463
    int k;
464

  
465
    for( int j=1; j<12; j++)
466
      {
467
      k = idx % (j+1);
468
      idx /= j+1;
469

  
470
      while (k-- > 0) rotateRight(perm,j);
471
      }
472

  
473
    int x=11;// set edges
474

  
475
    for( int j=11; j>=0; j--) ep[j] = perm[x--];
476
    }
477

  
478
///////////////////////////////////////////////////////////////////////////////////////////////////
479
// Check a cubie cube for solvability. Return the error code.
480
// 0: Cube is solvable
481
// -2: Not all 12 edges exist exactly once
482
// -3: Flip error: One edge has to be flipped
483
// -4: Not all corners exist exactly once
484
// -5: Twist error: One corner has to be twisted
485
// -6: Parity error: Two corners ore two edges have to be exchanged
486

  
487
  int verify()
488
    {
489
    int sum = 0;
490
    int[] edgeCount = new int[12];
491

  
492
    for (int e = RubikSolverEdge.UR; e <= RubikSolverEdge.BR; e++) edgeCount[ep[e]]++;
493

  
494
    for( int i=0; i<12; i++)
495
      if (edgeCount[i] != 1) return -2;
496

  
497
    for( int i=0; i<12; i++) sum += eo[i];
498

  
499
    if( (sum%2) != 0) return -3;
500

  
501
    int[] cornerCount = new int[8];
502

  
503
    for(int c = RubikSolverCorner.URF; c<= RubikSolverCorner.DRB; c++) cornerCount[cp[c]]++;
504

  
505
    for (int i = 0; i < 8; i++)
506
      if (cornerCount[i] != 1) return -4;// missing corners
507

  
508
    sum = 0;
509

  
510
    for( int i=0; i<8; i++) sum += co[i];
511

  
512
    if( (sum%3) != 0) return -5;// twisted corner
513

  
514
    if( (edgeParity()^cornerParity()) != 0) return -6;// parity error
515

  
516
    return 0;// cube ok
517
    }
518
}
src/main/java/org/distorted/solvers/cube3/RubikSolverEdge.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2008 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.solvers.cube3;
21

  
22
///////////////////////////////////////////////////////////////////////////////////////////////////
23

  
24
class RubikSolverEdge
25
  {
26
  public static final int UR=0;
27
  public static final int UF=1;
28
  public static final int UL=2;
29
  public static final int UB=3;
30
  public static final int DR=4;
31
  public static final int DF=5;
32
  public static final int DL=6;
33
  public static final int DB=7;
34
  public static final int FR=8;
35
  public static final int FL=9;
36
  public static final int BL=10;
37
  public static final int BR=11;
38
  }
src/main/java/org/distorted/solvers/cube3/RubikSolverFaceCube.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2008 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.solvers.cube3;
21

  
22
///////////////////////////////////////////////////////////////////////////////////////////////////
23

  
24
class RubikSolverFaceCube
25
{
26
	public int[] f = new int[54];
27

  
28
	// Map the corner positions to facelet positions. cornerFacelet[URF.ordinal()][0] e.g. gives the position of the
29
	// facelet in the URF corner position, which defines the orientation.
30
	// cornerFacelet[URF.ordinal()][1] and cornerFacelet[URF.ordinal()][2] give the position of the other two facelets
31
	// of the URF corner (clockwise).
32
	final static int[][] cornerFacelet =
33
          { { RubikSolverFacelet.U9, RubikSolverFacelet.R1, RubikSolverFacelet.F3 }, { RubikSolverFacelet.U7, RubikSolverFacelet.F1, RubikSolverFacelet.L3 },
34
            { RubikSolverFacelet.U1, RubikSolverFacelet.L1, RubikSolverFacelet.B3 }, { RubikSolverFacelet.U3, RubikSolverFacelet.B1, RubikSolverFacelet.R3 },
35
	          { RubikSolverFacelet.D3, RubikSolverFacelet.F9, RubikSolverFacelet.R7 }, { RubikSolverFacelet.D1, RubikSolverFacelet.L9, RubikSolverFacelet.F7 },
36
            { RubikSolverFacelet.D7, RubikSolverFacelet.B9, RubikSolverFacelet.L7 }, { RubikSolverFacelet.D9, RubikSolverFacelet.R9, RubikSolverFacelet.B7 } };
37

  
38
	// Map the edge positions to facelet positions. edgeFacelet[UR.ordinal()][0] e.g. gives the position of the facelet in
39
	// the UR edge position, which defines the orientation.
40
	// edgeFacelet[UR.ordinal()][1] gives the position of the other facelet
41
	final static int[][] edgeFacelet =
42
          { { RubikSolverFacelet.U6, RubikSolverFacelet.R2 }, { RubikSolverFacelet.U8, RubikSolverFacelet.F2 }, { RubikSolverFacelet.U4, RubikSolverFacelet.L2 },
43
            { RubikSolverFacelet.U2, RubikSolverFacelet.B2 }, { RubikSolverFacelet.D6, RubikSolverFacelet.R8 }, { RubikSolverFacelet.D2, RubikSolverFacelet.F8 },
44
	          { RubikSolverFacelet.D4, RubikSolverFacelet.L8 }, { RubikSolverFacelet.D8, RubikSolverFacelet.B8 }, { RubikSolverFacelet.F6, RubikSolverFacelet.R4 },
45
            { RubikSolverFacelet.F4, RubikSolverFacelet.L6 }, { RubikSolverFacelet.B6, RubikSolverFacelet.L4 }, { RubikSolverFacelet.B4, RubikSolverFacelet.R6 } };
46

  
47
	// Map the corner positions to facelet colors.
48
	final static int[][] cornerColor =
49
          { { RubikSolverColor.U, RubikSolverColor.R, RubikSolverColor.F }, { RubikSolverColor.U, RubikSolverColor.F, RubikSolverColor.L },
50
            { RubikSolverColor.U, RubikSolverColor.L, RubikSolverColor.B }, { RubikSolverColor.U, RubikSolverColor.B, RubikSolverColor.R },
51
            { RubikSolverColor.D, RubikSolverColor.F, RubikSolverColor.R }, { RubikSolverColor.D, RubikSolverColor.L, RubikSolverColor.F },
52
	          { RubikSolverColor.D, RubikSolverColor.B, RubikSolverColor.L }, { RubikSolverColor.D, RubikSolverColor.R, RubikSolverColor.B } };
53

  
54
	// Map the edge positions to facelet colors.
55
	final static int[][] edgeColor =
56
          { { RubikSolverColor.U, RubikSolverColor.R }, { RubikSolverColor.U, RubikSolverColor.F }, { RubikSolverColor.U, RubikSolverColor.L },
57
            { RubikSolverColor.U, RubikSolverColor.B }, { RubikSolverColor.D, RubikSolverColor.R }, { RubikSolverColor.D, RubikSolverColor.F },
58
            { RubikSolverColor.D, RubikSolverColor.L }, { RubikSolverColor.D, RubikSolverColor.B }, { RubikSolverColor.F, RubikSolverColor.R },
59
            { RubikSolverColor.F, RubikSolverColor.L }, { RubikSolverColor.B, RubikSolverColor.L }, { RubikSolverColor.B, RubikSolverColor.R } };
60

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

  
63
	RubikSolverFaceCube()
64
    {
65
	  String s = "UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB";
66

  
67
    for( int i=0; i<54; i++)
68
	    f[i] = RubikSolverColor.toInt(s.substring(i, i + 1));
69
	  }
70

  
71
///////////////////////////////////////////////////////////////////////////////////////////////////
72
// Construct a facelet cube from a string
73

  
74
	RubikSolverFaceCube(String cubeString)
75
    {
76
	  for( int i=0; i<cubeString.length(); i++)
77
	    f[i] = RubikSolverColor.toInt(cubeString.substring(i, i + 1));
78
	  }
79

  
80
///////////////////////////////////////////////////////////////////////////////////////////////////
81
// Gives string representation of a facelet cube
82

  
83
	String to_String()
84
    {
85
	  String s = "";
86

  
87
	  for (int i = 0; i < 54; i++)
88
	    s += RubikSolverColor.toString(f[i]);
89

  
90
    return s;
91
	  }
92

  
93
///////////////////////////////////////////////////////////////////////////////////////////////////
94
// Gives CubieCube representation of a faceletcube
95

  
96
	RubikSolverCubieCube toCubieCube()
97
    {
98
	  byte ori;
99
	  RubikSolverCubieCube ccRet = new RubikSolverCubieCube();
100
		
101
    for( int i=0; i< 8; i++) ccRet.cp[i] = RubikSolverCorner.URF; // invalidate corners
102
	  for( int i=0; i<12; i++) ccRet.ep[i] = RubikSolverEdge.UR;    // and edges
103

  
104
	  int col1, col2;
105

  
106
	  for(int i = RubikSolverCorner.URF; i<= RubikSolverCorner.DRB; i++)
107
      {
108
	    // get the colors of the cubie at corner i, starting with U/D
109
	    for (ori = 0; ori < 3; ori++)
110
	      if (f[cornerFacelet[i][ori]] == RubikSolverColor.U || f[cornerFacelet[i][ori]] == RubikSolverColor.D)
111
		      break;
112

  
113
	    col1 = f[cornerFacelet[i][(ori+1)%3]];
114
	    col2 = f[cornerFacelet[i][(ori+2)%3]];
115

  
116
	    for(int j = RubikSolverCorner.URF; j<= RubikSolverCorner.DRB; j++)
117
        {
118
	      if( col1==cornerColor[j][1] && col2==cornerColor[j][2])
119
          {
120
		      // in cornerposition i we have cornercubie j
121
		      ccRet.cp[i] = j;
122
		      ccRet.co[i] = (byte) (ori % 3);
123
		      break;
124
		      }
125
	      }
126
	    }
127

  
128
    for(int i = RubikSolverEdge.UR; i<= RubikSolverEdge.BR; i++)
129
      {
130
	    for(int j = RubikSolverEdge.UR; j<= RubikSolverEdge.BR; j++)
131
        {
132
        if( f[edgeFacelet[i][0]]==edgeColor[j][0] && f[edgeFacelet[i][1]]==edgeColor[j][1])
133
          {
134
		      ccRet.ep[i] = j;
135
		      ccRet.eo[i] = 0;
136
		      break;
137
		      }
138
        if( f[edgeFacelet[i][0]]==edgeColor[j][1] && f[edgeFacelet[i][1]]==edgeColor[j][0])
139
          {
140
		      ccRet.ep[i] = j;
141
		      ccRet.eo[i] = 1;
142
		      break;
143
          }
144
	      }
145
	    }
146

  
147
	return ccRet;
148
	}
149
}
src/main/java/org/distorted/solvers/cube3/RubikSolverFacelet.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2008 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.solvers.cube3;
21

  
22
/**
23
 * <pre>
24
 * The names of the facelet positions of the cube
25
 *             |************|
26
 *             |*U1**U2**U3*|
27
 *             |************|
28
 *             |*U4**U5**U6*|
29
 *             |************|
30
 *             |*U7**U8**U9*|
31
 *             |************|
32
 * ************|************|************|************|
33
 * *L1**L2**L3*|*F1**F2**F3*|*R1**R2**F3*|*B1**B2**B3*|
34
 * ************|************|************|************|
35
 * *L4**L5**L6*|*F4**F5**F6*|*R4**R5**R6*|*B4**B5**B6*|
36
 * ************|************|************|************|
37
 * *L7**L8**L9*|*F7**F8**F9*|*R7**R8**R9*|*B7**B8**B9*|
38
 * ************|************|************|************|
39
 *             |************|
40
 *             |*D1**D2**D3*|
41
 *             |************|
42
 *             |*D4**D5**D6*|
43
 *             |************|
44
 *             |*D7**D8**D9*|
45
 *             |************|
46
 * </pre>
47
 * 
48
 *A cube definition string "UBL..." means for example: In position U1 we have the U-color, in position U2 we have the
49
 * B-color, in position U3 we have the L color etc. according to the order U1, U2, U3, U4, U5, U6, U7, U8, U9, R1, R2,
50
 * R3, R4, R5, R6, R7, R8, R9, F1, F2, F3, F4, F5, F6, F7, F8, F9, D1, D2, D3, D4, D5, D6, D7, D8, D9, L1, L2, L3, L4,
51
 * L5, L6, L7, L8, L9, B1, B2, B3, B4, B5, B6, B7, B8, B9 of the enum constants.
52
 */
53

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

  
56
class RubikSolverFacelet
57
  {
58
  public static int U1 = 0;
59
  public static int U2 = 1;
60
  public static int U3 = 2;
61
  public static int U4 = 3;
62
  public static int U5 = 4;
63
  public static int U6 = 5;
64
  public static int U7 = 6;
65
  public static int U8 = 7;
66
  public static int U9 = 8;
67

  
68
  public static int R1 = 9;
69
  public static int R2 = 10;
70
  public static int R3 = 11;
71
  public static int R4 = 12;
72
  public static int R5 = 13;
73
  public static int R6 = 14;
74
  public static int R7 = 15;
75
  public static int R8 = 16;
76
  public static int R9 = 17;
77

  
78
  public static int F1 = 18;
79
  public static int F2 = 19;
80
  public static int F3 = 20;
81
  public static int F4 = 21;
82
  public static int F5 = 22;
83
  public static int F6 = 23;
84
  public static int F7 = 24;
85
  public static int F8 = 25;
86
  public static int F9 = 26;
87

  
88
  public static int D1 = 27;
89
  public static int D2 = 28;
90
  public static int D3 = 29;
91
  public static int D4 = 30;
92
  public static int D5 = 31;
93
  public static int D6 = 32;
94
  public static int D7 = 33;
95
  public static int D8 = 34;
96
  public static int D9 = 35;
97

  
98
  public static int L1 = 36;
99
  public static int L2 = 37;
100
  public static int L3 = 38;
101
  public static int L4 = 39;
102
  public static int L5 = 40;
103
  public static int L6 = 41;
104
  public static int L7 = 42;
105
  public static int L8 = 43;
106
  public static int L9 = 44;
107

  
108
  public static int B1 = 45;
109
  public static int B2 = 46;
110
  public static int B3 = 47;
111
  public static int B4 = 48;
112
  public static int B5 = 49;
113
  public static int B6 = 50;
114
  public static int B7 = 51;
115
  public static int B8 = 52;
116
  public static int B9 = 53;
117
  }
src/main/java/org/distorted/solvers/cube3/RubikSolverSearch.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2008 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.solvers.cube3;
21

  
22
import android.content.res.Resources;
23

  
24
///////////////////////////////////////////////////////////////////////////////////////////////////
25

  
26
public class RubikSolverSearch
27
{
28
	static int mNumMoves = 0;
29
	
30
	static int[] ax      = new int[31]; // The axis of the move
31
	static int[] po      = new int[31]; // The power of the move
32

  
33
	static int[] flip    = new int[31]; // phase1 coordinates
34
	static int[] twist   = new int[31];
35
	static int[] slice   = new int[31];
36

  
37
	static int[] parity  = new int[31]; // phase2 coordinates
38
	static int[] URFtoDLF= new int[31];
39
	static int[] FRtoBR  = new int[31];
40
	static int[] URtoUL  = new int[31];
41
	static int[] UBtoDF  = new int[31];
42
	static int[] URtoDF  = new int[31];
43

  
44
	static int[] minDistPhase1 = new int[31]; // IDA * distance to goal estimations
45
	static int[] minDistPhase2 = new int[31];
46

  
47
///////////////////////////////////////////////////////////////////////////////////////////////////
48

  
49
	static String solutionToString(int length) 
50
	  {
51
		StringBuilder s = new StringBuilder();
52
		
53
		for( int i=0; i<length; i++)
54
		  {
55
			switch(ax[i])
56
			  {
57
			  case 0: switch(po[i])
58
			            {
59
			            case 1: s.append(" 548"); break;
60
			            case 2: s.append(" 804"); break;
61
			            case 3: s.append(" 292"); break;
62
			            }
63
				        break;
64
			  case 1: switch(po[i])
65
	                {
66
	                case 1: s.append(" 516"); break;
67
	                case 2: s.append(" 772"); break;
68
	                case 3: s.append(" 260"); break;
69
	                }
70
				        break;
71
		  	case 2: switch(po[i])
72
                  {
73
                  case 1: s.append(" 580"); break;
74
                  case 2: s.append(" 836"); break;
75
                  case 3: s.append(" 324"); break;
76
                  }
77
				        break;
78
		  	case 3: switch(po[i])
79
                  {
80
                  case 1: s.append(" 289"); break;
81
                  case 2: s.append(" 033"); break;
82
                  case 3: s.append(" 545"); break;
83
                  }
84
				        break;
85
			  case 4: switch(po[i])
86
                  {
87
                  case 1: s.append(" 257"); break;
88
                  case 2: s.append(" 001"); break;
89
                  case 3: s.append(" 513"); break;
90
                  }
91
				        break;
92
			  case 5: switch(po[i])
93
                  {
94
                  case 1: s.append(" 321"); break;
95
                  case 2: s.append(" 065"); break;
96
                  case 3: s.append(" 577"); break;
97
                  }
98
				        break;
99
			  }
100
		  }
101
		return s.toString();
102
	}
103

  
104
///////////////////////////////////////////////////////////////////////////////////////////////////
105

  
106
	public static void prepare(Resources res)
107
	  {
108
	  RubikSolverCoordCube.initialize(res,0);
109
    RubikSolverCoordCube.initialize(res,1);
110
		RubikSolverCoordCube.initialize(res,2);
111
		RubikSolverCoordCube.initialize(res,3);
112
		RubikSolverCoordCube.initialize(res,4);
113
		RubikSolverCoordCube.initialize(res,5);
114
		RubikSolverCoordCube.initialize(res,6);
115
		RubikSolverCoordCube.initialize(res,7);
116
		RubikSolverCoordCube.initialize(res,8);
117
		RubikSolverCoordCube.initialize(res,9);
118
		RubikSolverCoordCube.initialize(res,10);
119
		RubikSolverCoordCube.initialize(res,11);
120
	  }
121

  
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123
/**
124
 * Computes the solver string for a given cube.
125
 *
126
 * @param facelets
127
 *          is the cube definition string, see {@link RubikSolverFacelet} for the format.
128
 *
129
 * @param maxDepth
130
 *          defines the maximal allowed maneuver length. For random cubes, a maxDepth of 21 usually
131
 *          will return a solution in less than 0.5 seconds. With a maxDepth of 20 it takes a few
132
 *          seconds on average to find a solution, but it may take much longer for specific cubes.
133
 *
134
 *@param timeOut
135
 *          defines the maximum computing time of the method in seconds. If it does not return with
136
 *          a solution, it returns with an error code.
137
 * @return The solution string or an error code:
138
 *         Error 1: There is not exactly one facelet of each color
139
 *         Error 2: Not all 12 edges exist exactly once
140
 *         Error 3: Flip error: One edge has to be flipped
141
 *         Error 4: Not all corners exist exactly once
142
 *         Error 5: Twist error: One corner has to be twisted
143
 *         Error 6: Parity error: Two corners or two edges have to be exchanged
144
 *         Error 7: No solution exists for the given maxDepth
145
 *         Error 8: Timeout, no solution within given time
146
 */
147

  
148
	public static String solution(String facelets, int maxDepth, long timeOut) 
149
	  {
150
		int s;
151
		int[] count = new int[6];
152

  
153
		try
154
		  {
155
			for( int i=0; i<54; i++)
156
				count[RubikSolverColor.toInt(facelets.substring(i,i+1))]++;
157
		  }
158
		catch (Exception e)
159
		  {
160
		  android.util.Log.d("error", "1");
161
			return "Error 1";
162
		  }
163

  
164
		for( int i=0; i<6; i++)
165
			if (count[i] != 9)
166
			  {
167
			  android.util.Log.d("error", "2");
168
				return "Error 1";
169
				}
170

  
171
		RubikSolverFaceCube fc = new RubikSolverFaceCube(facelets);
172
		RubikSolverCubieCube cc = fc.toCubieCube();
173
		if ((s = cc.verify()) != 0)
174
		  {
175
		  android.util.Log.d("error", "3");
176
			return "Error " + Math.abs(s);
177
			}
178

  
179
		RubikSolverCoordCube c = new RubikSolverCoordCube(cc);
180

  
181
		po[0] = 0;
182
		ax[0] = 0;
183
		flip[0] = c.flip;
184
		twist[0] = c.twist;
185
		parity[0] = c.parity;
186
		slice[0] = c.FRtoBR / 24;
187
		URFtoDLF[0] = c.URFtoDLF;
188
		FRtoBR[0] = c.FRtoBR;
189
		URtoUL[0] = c.URtoUL;
190
		UBtoDF[0] = c.UBtoDF;
191

  
192
		minDistPhase1[1] = 1;// else failure for depth=1, n=0
193
		int mv, n=0;
194
		boolean busy = false;
195
		int depthPhase1 = 1;
196

  
197
		long tStart = System.currentTimeMillis();
198

  
199
		do
200
		  {
201
			do
202
			  {
203
				if( (depthPhase1-n > minDistPhase1[n+1]) && !busy)
204
				  {
205
					if (ax[n]==0 || ax[n]==3)// Initialize next move
206
						ax[++n] = 1;
207
					else
208
						ax[++n] = 0;
209
					po[n] = 1;
210
				  }
211
				else if (++po[n] > 3)
212
				  {
213
					do
214
					  { // increment axis
215
						if (++ax[n] > 5)
216
						  {
217
							if (System.currentTimeMillis() - tStart > timeOut << 10)
218
								return "Error 8";
219

  
220
							if (n==0)
221
							  {
222
								if (depthPhase1 >= maxDepth)
223
									return "Error 7";
224
								else
225
								  {
226
									depthPhase1++;
227
									ax[n] = 0;
228
									po[n] = 1;
229
									busy = false;
230
									break;
231
								  }
232
							  }
233
							else
234
							  {
235
								n--;
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff