Pocket Cube Solver

Short introduction to project
During last holidays I decided to bring my LEGO robot back to the life and build something really interesting. After the course in Discrete Mathematics I wondered how much I improved my thinking about permutations etc. and if I’m now amble to create my own model of cube and represent it in somehow tricky and maybe even beautiful way.
After discover how to create programs on LEGO Mindstorms using Java language by LeJOS Firmware I was able to create single model of cube which is reused not only in robot but also in Android apps and computer simulations.
I’ve built my own implemntation of LEGO robot that is somehow similar to Mindcuber by David Gilday, but which in my opinion was harder in construct process because of the nature of Pocket Rubik cube. We can observe that it is much easer to move stadard Rubik’s cube than the smaller version - and that is in my opinion the point why I couldn’t find any realisation of Pocket Cube solver in the Internet.
Here you can see the final result of my work where the cube is scanned by the robot then sent to Android phone that finds the solution and at the end the cube is solved by robot using moves specified by android app solver.
Most interesting parts of project
The cube in the project was represented by the array of cube colors. Threre are 24 cube fields in the cube - each one represented by single cell in the array. The mapping of the cube was designed with keeping the simplicity of permutations of cube in mind.
Let’s see into Cube model code in Java which represents the single Pocket Cube:
public class Cube {
/* ... */
private static final Random GENERATOR = new Random();
private static final int FIELD_SIZE = 10;
private static final int FACE_SIZE = 2 * FIELD_SIZE;
private static final int CUBE_FIELDS = 24;
private final CubeColor[] cubeColors = new CubeColor[CUBE_FIELDS];
private final ICubeSolver cubeSolver = new BluetoothSolver();
/* ... */
public byte[] toBytes() {
byte[] cubeData = new byte[CUBE_FIELDS];
for (int i = 0; i < CUBE_FIELDS; i++)
cubeData[i] = cubeColors[i].toByte();
return cubeData;
}
public static Cube fromBytes(byte[] inputData) {
if (inputData.length != CUBE_FIELDS) throw new IllegalArgumentException("Bad input data to create the cube");
Cube dataCube = Cube.getEmpty();
for (int i = 0; i < CUBE_FIELDS; i++)
dataCube.setColor(i, CubeColor.fromByte(inputData[i]));
return dataCube;
}
/* ... */
private void applyPermutation(int[] permutation) {
assert permutation.length > 0 : "Empty permutation not allowed";
CubeColor first = cubeColors[permutation[0]];
for (int i = 0; i < permutation.length-1; i++) {
cubeColors[permutation[i]] = cubeColors[permutation[i+1]];
}
cubeColors[permutation[permutation.length-1]] = first;
}
public void move(CubeMove move) {
for (int[] permutation : move.getPermutations())
this.applyPermutation(permutation);
}
public boolean isSolved() {
for (int i = 0; i < 24; i += 4) {
for (int j = 1; j < 4; j++)
if (cubeColors[i] != cubeColors[i+j])
return false;
}
return true;
}
public CubeMove[] findSolution() throws NoSolutionFound {
return cubeSolver.findSolution(this);
}
/* ... */
}
We can see a few interesting parts in this code that in my opinion are worth mentioning:
Cube is represented as an array of CubeColor where every color can be translated into byte using toByte() function. It works also in the second direction. Thanks to this mechanism the cube can be esily converted into bytes and then send to second bluetooth devices.
There are permutations of integer numbers assigned to specific moves of cube in the CubeMove class and every of moves can return its permutations. Thanks to this the function applyPermutation() creates the move (which is built of a few permutations of cube fields) by applying every permutation of these given by CubeMove.
Checking solved state is really short and doesn’t include testing the orientation of faces of cube. Only the colors on single faces have to equal to get solved cube as we can see in isSolved().