La première étape de notre réflexion a été de définir la structure du cube à implémenter.
2 choix
2 choix s'offraient à nous :
-
Opter pour une structure représentant toutes les facettes du cube, soit 48 facettes sur les 54 en tout, les 6 centrales étant inamovibles.
-
Opter pour une structure représentant tous les petits cubes constituant le rubik's cube soit 20 petits cubes.
Nous pensions que choisir la seconde option serait plus intéressant étant donné qu'on devait permuter des petits cubes pour chaque mouvement et non des facettes, ce qui ferait beaucoup moins d'opérations. Or nous n'avions pas prévu que pour certains mouvements (les mouvements verticaux) on devait aussi permuter des facettes au sein d'un petit cube. Suite à ce constat nous avons décider de calculer le nombre d'opérations en moyenne afin de savoir si on devait changer notre structure (cf. Nombre d'operations).
Après calcul on a 20
opérations d'affectations par mouvement avec une solution stockant les facettes contre 17.4
opérations en moyenne pour une solution stockant les petits cubes.
Notre structure de données
Nous avons donc décidé de garder notre première structure qui est plus économe en mouvements et aussi plus facile à utiliser/comprendre à nos yeux.
Les petits cubes sont donc représentés par leur emplacement sur le Rubik's cube:
PETITS_CUBES = ['FU','FRU','FR','FRD','FD','LFD','FL','LFU','LU','LD',
'BU','RBU','BR','RBD','BD','BLD','BL','BLU','RU','RD']
Le cube en entier est représenté par un dictionnaire de tableaux numpy
:
cubes = {
'FU' : <tableau>,
'FRU': <tableau>,
...
}
On distingue deux sortes de petit cube :
- les cubes coins (3 lettres)
- les cubes arêtes (2 lettres)
ex : FRU
= Front-Right-Up, on fait donc référence au coin commun à la face avant (Front), à la face droite (Right) et à la phase du haut (Up)
Dans chaque petit cube, on stocke autant de chiffres qu'il y a de lettres, correspondant à leur couleur :
ex : dans FRU
, on peut stocker [1,2,5]
le 1 correspondant à la couleur de la facette de la face avant (F
), le 2 correspondant à la couleur de la facette de droite (R
) et le 5 correspondant à la couleur de la face supérieur (U
).
On respecte ce code :
White (W) = 0
Blue (B) = 1
Red (R) = 2
Green (G) = 3
Orange (0) = 4
Yellow (Y) = 5
On a fait le choix de stocker un entier, on occupe ainsi moins de place qu'une chaîne en Python.
Une fois le cube créée, on peut le manipuler en effectuant des mouvements dessus
MOUVEMENTS = [
"U", "Ui", "U'", "U’", "U2",
"L", "Li", "L'", "L’", "L2",
"F", "Fi", "F'", "F’", "F2",
"R", "Ri", "R'", "R’", "R2",
"B", "Bi", "B'", "B’", "B2",
"D", "Di", "D'", "D’", "D2",
]
La lettre "i" est utilisée pour signifier le mouvement inverse (l'apostrophe " ' " est aussi parfois utilisée)
Quand on effectue un mouvement, les petits cubes ne changent pas de place, c'est les couleurs des facettes les composant qui vont changer, à chaque mouvement, on met donc à jour le dictionnaire de tableaux numpy contenant les couleurs.
ex : si on à FU = [1,5] et LU = [4,5] et qu'on fait une rotation "Ui" alors physiquement le cube LU va prendre la place de FU, ici, le cube FU va prendre les nouvelles valeurs relatives aux nouvelles couleurs du cube qui se situe désormais a la place FU, on aura donc FU = [4,5]