Skip to content

Instantly share code, notes, and snippets.

@lhartikk
Created February 13, 2018 15:31
Show Gist options
  • Save lhartikk/d5fe6478f653cfe6e5d70a64f55ffa87 to your computer and use it in GitHub Desktop.
Save lhartikk/d5fe6478f653cfe6e5d70a64f55ffa87 to your computer and use it in GitHub Desktop.
pragma solidity ^0.4.8;
contract Rubik {
enum Color {Red, Blue, Yellow, Green, White, Orange}
Color[9][6] state;
address public owner = msg.sender;
uint8 constant FRONT = 0;
uint8 constant LEFT = 1;
uint8 constant UP = 2;
uint8 constant RIGHT = 3;
uint8 constant DOWN = 4;
uint8 constant BACK = 5;
bool initialStateSet = false;
function Rubik() public {
}
/*
Set the initial state of the cube.
For example a solved state would be:
[[0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1], [2, 2, 2, 2, 2, 2, 2, 2, 2], [3, 3, 3, 3, 3, 3, 3, 3, 3], [4, 4, 4, 4, 4, 4, 4, 4, 4], [5, 5, 5, 5, 5, 5, 5, 5, 5]]
It is possible to set the state to a nonsolvable state.
Only owner can set the state and once it is set it cannot be changed.
*/
function setInitialState(Color[9][6] initialState) public {
if(msg.sender == owner && initialStateSet == false) {
state = initialState;
// don't allow to change the state once it is set
initialStateSet = true;
}
}
/*
Checks that a given side is the correct color.
*/
function verifySide(Color[9][6] memory aState, uint8 FACE, Color expectedColor) internal pure returns (bool) {
return aState[FACE][0] == expectedColor &&
aState[FACE][1] == expectedColor &&
aState[FACE][2] == expectedColor &&
aState[FACE][3] == expectedColor &&
aState[FACE][4] == expectedColor &&
aState[FACE][5] == expectedColor &&
aState[FACE][6] == expectedColor &&
aState[FACE][7] == expectedColor &&
aState[FACE][8] == expectedColor;
}
/*
Checks if the given state is in solved state.
The cube is solved if the state equals:
[[0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1], [2, 2, 2, 2, 2, 2, 2, 2, 2], [3, 3, 3, 3, 3, 3, 3, 3, 3], [4, 4, 4, 4, 4, 4, 4, 4, 4], [5, 5, 5, 5, 5, 5, 5, 5, 5]]
*/
function isSolved(Color[9][6] memory aState) public pure returns (bool) {
return verifySide(aState, FRONT, Color.Red) &&
verifySide(aState, LEFT, Color.Blue) &&
verifySide(aState, UP, Color.Yellow) &&
verifySide(aState, RIGHT, Color.Green) &&
verifySide(aState, DOWN, Color.White) &&
verifySide(aState, BACK, Color.Orange);
}
function getInitialState() public view returns (Color[9][6]) {
return state;
}
/*
Shuffles a single side of a face. For instance:
1 2 3 7 4 1
4 5 6 -> 8 5 2
7 8 9 9 6 3
Calling only this function does not leave the cube in a valid state as
also the "sides" of the cubes must move.
*/
function shuffleFace(Color[9][6] memory aState, uint FACE) pure internal {
Color[9] memory swap;
swap[0] = aState[FACE][0];
swap[1] = aState[FACE][1];
swap[2] = aState[FACE][2];
swap[3] = aState[FACE][3];
swap[4] = aState[FACE][4];
swap[5] = aState[FACE][5];
swap[6] = aState[FACE][6];
swap[7] = aState[FACE][7];
swap[8] = aState[FACE][8];
aState[FACE][0] = swap[2];
aState[FACE][1] = swap[5];
aState[FACE][2] = swap[8];
aState[FACE][3] = swap[1];
aState[FACE][4] = swap[4];
aState[FACE][5] = swap[7];
aState[FACE][6] = swap[0];
aState[FACE][7] = swap[3];
aState[FACE][8] = swap[6];
}
function shuffleBack(Color[9][6] memory aState) pure internal {
shuffleFace(aState, BACK);
Color[12] memory swap;
swap[0] = aState[DOWN][2];
swap[1] = aState[DOWN][5];
swap[2] = aState[DOWN][8];
swap[3] = aState[RIGHT][8];
swap[4] = aState[RIGHT][7];
swap[5] = aState[RIGHT][6];
swap[6] = aState[UP][6];
swap[7] = aState[UP][3];
swap[8] = aState[UP][0];
swap[9] = aState[LEFT][0];
swap[10] = aState[LEFT][1];
swap[11] = aState[LEFT][2];
aState[DOWN][2] = swap[9];
aState[DOWN][5] = swap[10];
aState[DOWN][8] = swap[11];
aState[RIGHT][8] = swap[0];
aState[RIGHT][7] = swap[1];
aState[RIGHT][6] = swap[2];
aState[UP][6] = swap[3];
aState[UP][3] = swap[4];
aState[UP][0] = swap[5];
aState[LEFT][0] = swap[6];
aState[LEFT][1] = swap[7];
aState[LEFT][2] = swap[8];
}
function shuffleDown(Color[9][6] memory aState) pure internal {
shuffleFace(aState, DOWN);
Color[12] memory swap;
swap[0] = aState[FRONT][2];
swap[1] = aState[FRONT][5];
swap[2] = aState[FRONT][8];
swap[3] = aState[RIGHT][2];
swap[4] = aState[RIGHT][5];
swap[5] = aState[RIGHT][8];
swap[6] = aState[BACK][6];
swap[7] = aState[BACK][3];
swap[8] = aState[BACK][0];
swap[9] = aState[LEFT][2];
swap[10] = aState[LEFT][5];
swap[11] = aState[LEFT][8];
aState[FRONT][2] = swap[9];
aState[FRONT][5] = swap[10];
aState[FRONT][8] = swap[11];
aState[RIGHT][2] = swap[0];
aState[RIGHT][5] = swap[1];
aState[RIGHT][8] = swap[2];
aState[BACK][6] = swap[3];
aState[BACK][3] = swap[4];
aState[BACK][0] = swap[5];
aState[LEFT][2] = swap[6];
aState[LEFT][5] = swap[7];
aState[LEFT][8] = swap[8];
}
function shuffleRight(Color[9][6] memory aState) pure internal {
shuffleFace(aState, RIGHT);
Color[12] memory swap;
swap[0] = aState[UP][8];
swap[1] = aState[UP][7];
swap[2] = aState[UP][6];
swap[3] = aState[BACK][8];
swap[4] = aState[BACK][7];
swap[5] = aState[BACK][6];
swap[6] = aState[DOWN][8];
swap[7] = aState[DOWN][7];
swap[8] = aState[DOWN][6];
swap[9] = aState[FRONT][8];
swap[10] = aState[FRONT][7];
swap[11] = aState[FRONT][6];
aState[UP][8] = swap[9];
aState[UP][7] = swap[10];
aState[UP][6] = swap[11];
aState[BACK][8] = swap[0];
aState[BACK][7] = swap[1];
aState[BACK][6] = swap[2];
aState[DOWN][8] = swap[3];
aState[DOWN][7] = swap[4];
aState[DOWN][6] = swap[5];
aState[FRONT][8] = swap[6];
aState[FRONT][7] = swap[7];
aState[FRONT][6] = swap[8];
}
function shuffleUp(Color[9][6] memory aState) pure internal {
shuffleFace(aState, UP);
Color[12] memory swap;
swap[0] = aState[BACK][2];
swap[1] = aState[BACK][5];
swap[2] = aState[BACK][8];
swap[3] = aState[RIGHT][6];
swap[4] = aState[RIGHT][3];
swap[5] = aState[RIGHT][0];
swap[6] = aState[FRONT][6];
swap[7] = aState[FRONT][3];
swap[8] = aState[FRONT][0];
swap[9] = aState[LEFT][6];
swap[10] = aState[LEFT][3];
swap[11] = aState[LEFT][0];
aState[BACK][2] = swap[9];
aState[BACK][5] = swap[10];
aState[BACK][8] = swap[11];
aState[RIGHT][6] = swap[0];
aState[RIGHT][3] = swap[1];
aState[RIGHT][0] = swap[2];
aState[FRONT][6] = swap[3];
aState[FRONT][3] = swap[4];
aState[FRONT][0] = swap[5];
aState[LEFT][6] = swap[6];
aState[LEFT][3] = swap[7];
aState[LEFT][0] = swap[8];
}
function shuffleLeft(Color[9][6] memory aState) pure internal {
shuffleFace(aState, LEFT);
Color[12] memory swap;
swap[0] = aState[UP][0];
swap[1] = aState[UP][1];
swap[2] = aState[UP][2];
swap[3] = aState[FRONT][0];
swap[4] = aState[FRONT][1];
swap[5] = aState[FRONT][2];
swap[6] = aState[DOWN][0];
swap[7] = aState[DOWN][1];
swap[8] = aState[DOWN][2];
swap[9] = aState[BACK][0];
swap[10] = aState[BACK][1];
swap[11] = aState[BACK][2];
aState[UP][0] = swap[9];
aState[UP][1] = swap[10];
aState[UP][2] = swap[11];
aState[FRONT][0] = swap[0];
aState[FRONT][1] = swap[1];
aState[FRONT][2] = swap[2];
aState[DOWN][0] = swap[3];
aState[DOWN][1] = swap[4];
aState[DOWN][2] = swap[5];
aState[BACK][0] = swap[6];
aState[BACK][1] = swap[7];
aState[BACK][2] = swap[8];
}
function shuffleFront(Color[9][6] memory aState) pure internal {
shuffleFace(aState, FRONT);
Color[12] memory swap;
swap[0] = aState[UP][2];
swap[1] = aState[UP][5];
swap[2] = aState[UP][8];
swap[3] = aState[RIGHT][0];
swap[4] = aState[RIGHT][1];
swap[5] = aState[RIGHT][2];
swap[6] = aState[DOWN][6];
swap[7] = aState[DOWN][3];
swap[8] = aState[DOWN][0];
swap[9] = aState[LEFT][8];
swap[10] = aState[LEFT][7];
swap[11] = aState[LEFT][6];
aState[UP][2] = swap[9];
aState[UP][5] = swap[10];
aState[UP][8] = swap[11];
aState[RIGHT][0] = swap[0];
aState[RIGHT][1] = swap[1];
aState[RIGHT][2] = swap[2];
aState[DOWN][6] = swap[3];
aState[DOWN][3] = swap[4];
aState[DOWN][0] = swap[5];
aState[LEFT][8] = swap[6];
aState[LEFT][7] = swap[7];
aState[LEFT][6] = swap[8];
}
/*
Returns the state of the cube after performing the given moves.
*/
function trySolution(uint8[] move) public view returns (Color[9][6]) {
Color[9][6] memory aState = state;
for (uint i = 0; i < move.length; i++) {
if (move[i] == FRONT) {
shuffleFront(aState);
} else if (move[i] == LEFT) {
shuffleLeft(aState);
} else if (move[i] == UP) {
shuffleUp(aState);
} else if (move[i] == RIGHT) {
shuffleRight(aState);
} else if (move[i] == DOWN) {
shuffleDown(aState);
} else if (move[i] == BACK) {
shuffleBack(aState);
} else {
//invalid move;
require(false);
}
}
return aState;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment