Created
February 13, 2018 15:31
-
-
Save lhartikk/d5fe6478f653cfe6e5d70a64f55ffa87 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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