Add files via upload

This commit is contained in:
JeanMarieMineau 2017-05-13 18:49:33 +02:00 committed by GitHub
parent 845468e869
commit ad2d020b19
12 changed files with 2193 additions and 0 deletions

143
Action.py Normal file
View file

@ -0,0 +1,143 @@
#!/usr/bin/env python3
# coding: utf-8
'''
Created on 16 mars 2017
Copyright 2017 Jean-Marie Mineau, Maxime Keller
This file is part of "ISN's Cube".
"ISN's Cube" is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
"ISN's Cube" is distributed in the hope that it will be useful and
recreative, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with "ISN's Cube". If not, see <http://www.gnu.org/licenses/>.
@author: <mineau.jean.marie@gmail.com>
programme réalisé sur une base du programme dévellopé par Leonel Machava <leonelmachava@gmail.com>
http://codeNtronix.com
'''
from random import choice
class Action:
"""Object qui permet de tourner les faces."""
def __init__(self, parent):
"""parent est le cube qui utilise l'instance."""
self.parent = parent
self.angle = 0 # Angle restant à parcourir
self.actions = [] # Actions à effectuer
self.indexs = [] # Indices des cubies à tourner
self.anglesRotation = []# Angle en x, y, et z à tourner.
self.listeActionsPossible = ["H CWI", "H ACWI",
"B CWI", "B ACWI",
"D CWI", "D ACWI",
"G CWI", "G ACWI",
"AV CWI", "AV ACWI",
"AR CWI", "AR ACWI"]
def doAll(self):
"""Execute toutes les actions de la liste."""
while self.actions:
self.__call__()
def __call__(self):
"""Méthode principale."""
if self.angle == 0 and not self.actions:
#self.actions.append("ALEA")
return #Si l'action est terminée et qu'il n'y en a pas d'autre, on passe.
elif self.angle == 0:
self.initNewAction()
for i in self.indexs:
self.parent.cubies[i] = self.parent.cubies[i].rotationX(self.anglesRotation[0])
self.parent.cubies[i] = self.parent.cubies[i].rotationY(self.anglesRotation[1])
self.parent.cubies[i] = self.parent.cubies[i].rotationZ(self.anglesRotation[2])
angle = 0
for i in self.anglesRotation:
angle += i
if self.angle < 0:
print("deadlock")
self.angle -= abs(angle)
def initNewAction(self, actions = None):
"""Initialise une nouvelle action. Si une action est mise en argument,
elle est initialisée, sinon, l'action est prise dans la liste d'action."""
if actions:
commande = actions
actions.split()
else:
commande = self.actions.pop(0)
actions = commande.split()
if actions[0] == "ALEA":
self.melange()
if self.actions:
actions = self.actions.pop(0).split()
if actions[0] == "SOLVE":
self.resoudre()
elif actions[1] == "CW":
self.angle = 90
angle = 10
elif actions[1] == "ACW":
self.angle = 90
angle = -10
elif actions[1] == "CWI":
self.angle = 90
angle = 90
elif actions[1] == "ACWI":
self.angle = 90
angle = -90
else:
raise ValueError("La valeur " + str(actions[1]) + " est inconnue.")
x, y, z = 0, 0, 0
if actions[0] == "H":
y = angle
self.indexs = self.parent.getH()
elif actions[0] == "B":
y = angle
self.indexs = self.parent.getB()
elif actions[0] == "G":
x = angle
self.indexs = self.parent.getG()
elif actions[0] == "D":
x = angle
self.indexs = self.parent.getD()
elif actions[0] == "AV":
z = angle
self.indexs = self.parent.getAv()
elif actions[0] == "AR":
z = angle
self.indexs = self.parent.getAr()
elif actions[0] == "X":
x = angle
self.indexs = [i for i in range(len(self.parent.cubies))]
elif actions[0] == "Y":
y = angle
self.indexs = [i for i in range(len(self.parent.cubies))]
elif actions[0] == "Z":
z = angle
self.indexs = [i for i in range(len(self.parent.cubies))]
elif actions[0] != "SOLVE" and actions[0] != "ALEA":
raise ValueError("La commande " + str(commande) + " est inconnue.")
self.anglesRotation = [x, y, z]
def melange(self):
"""Met des actions aléatoire dans la liste d'action."""
liste = []
while len(liste) < 21:
liste.append(choice(self.listeActionsPossible))
self.actions = liste + self.actions
print(liste)
def resoudre(self):
"""Lance la resolution."""
self.parent.resoudre()

151
Bouton.py Normal file
View file

@ -0,0 +1,151 @@
'''
Created on 5 mai 2017
Copyright 2017 Jean-Marie Mineau, Maxime Keller
This file is part of "ISN's Cube".
"ISN's Cube" is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
"ISN's Cube" is distributed in the hope that it will be useful and
recreative, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with "ISN's Cube". If not, see <http://www.gnu.org/licenses/>.
@author: <mineau.jean.marie@gmail.com>
Class pour les boutons. Une classe qui gère l'ensemble des
boutons, et une autre qui est le bouton.
'''
import pygame
class Boutons:
"""Class gérant la création de boutons et le fait de clique dessus,
ainsi que l'affichage."""
def __init__(self):
"""Cette class à pour attribut une liste de boutons."""
self.boutons = []
def nouveauBouton(self, pos, image=None, couleur=(255,0,255),
size=(60,60), callback=lambda *args: None, argsCallback=[]):
"""Crée un nouveau bouton."""
bouton = Bouton(pos, self, image=image, couleur=couleur,
size=size, callback=callback, argsCallback=argsCallback)
self.boutons.append(bouton)
return bouton
def update(self, events):
"""Gère le click sur le bouton."""
for event in events:
if event.type == pygame.MOUSEBUTTONDOWN:
pos = event.pos
self.callbackClic(pos)
def callbackClic(self, pos):
"""Methode appellé lors d'un clic."""
for bouton in self.boutons:
if bouton.rect.collidepoint(*pos):
bouton.callback(*bouton.argsCallback)
return
def display(self, screen):
"""Affiche les Boutons."""
for bouton in self.boutons:
bouton.display(screen)
class Bouton:
"""Un Bouton."""
def __init__(self, pos, parent, image=None, couleur=(255,0,255),
size=(60,60), callback=lambda *args: None, argsCallback=[]):
"""Crée un bouton, si une image est donné, il la charge, sinon,
c'est un rectangle de taille size et de couleur couleur qui est affiché."""
self.parent = parent
self.pos = pos
if image is not None:
self.surface = pygame.image.load(image).convert_alpha()
self.rect = self.surface.get_rect()
else:
self.surface = pygame.Surface(size)
self.surface.fill(couleur)
self.rect = self.surface.get_rect()
self.rect = self.rect.move(self.pos)
self.callback = callback
self.argsCallback = argsCallback
def suppr(self):
"""Suprime le Bouton."""
self.parent.boutons.remove(self)
def display(self, screen):
"""Affiche le Bouton."""
screen.blit(self.surface, self.rect)
def callbackTest(a, b, c, d, e, f, g):
"""Test de callback."""
print(a)
print(b)
print(c)
print(d)
print(e)
print(f)
print(g)
def callback2(*args):
print("toto")
if __name__ == "__main__":
boutons = Boutons()
screen = pygame.display.set_mode((1000, 400))
clock = pygame.time.Clock()
pos = (50,50)
bouton = boutons.nouveauBouton(pos, callback=callbackTest, argsCallback=["A",
"B",
"C",
"D",
"E",
"F",
"G"])
pos2 = (50, 200)
bouton2 = boutons.nouveauBouton(pos2, callback=callback2, argsCallback=["H",
"I",
"J",
"K",
"L",
"M",
"N"])
while True:
screen.fill((150, 150, 150))
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
exit()
quit()
boutons.update(events)
boutons.display(screen)
pygame.display.update()
clock.tick(30)

104
Commande.py Normal file
View file

@ -0,0 +1,104 @@
#!/usr/bin/env python3
#coding: utf-8
"""
Copyright 2017 Jean-Marie Mineau, Maxime Keller
This file is part of "ISN's Cube".
"ISN's Cube" is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
"ISN's Cube" is distributed in the hope that it will be useful and
recreative, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with "ISN's Cube". If not, see <http://www.gnu.org/licenses/>.
@author: Maxime Keller
"""
import pygame
from pygame.locals import *
from ConstanteTouche import *
from Action import Action
#pygame.init()
class Commande:
"""Objet permettant de gérer les touches du clavier"""
def __init__(self, parent):
self.action = Action(parent)
self.KANOMI = (K_UP, K_UP, K_DOWN, K_DOWN, K_LEFT, K_RIGHT, K_LEFT, K_RIGHT, TOUCHE_b, TOUCHE_a)
self.iKonami = 0
def testKonamie(self, event):
"""Fait avancer, ou remet a 0, le konami code."""
if event.key == self.KANOMI[self.iKonami]:
self.iKonami += 1
if event.key == TOUCHE_a:
event.key = None
else:
self.iKonami = 0
if self.iKonami == 10:
self.iKonami = 0
self.action.actions.append("SOLVE")
def touches(self):
"""Les touches sont reliés a un autre programme"""
self.events = pygame.event.get()
for event in self.events:
if event.type == QUIT:
pygame.quit()
quit()
if event.type == KEYDOWN:
self.testKonamie(event)
if event.key == TOUCHE_a:
self.action.actions.append("ALEA")
print("alea")
elif event.key == TOUCHE_e :
self.action.actions.append("H CW")
elif event.key == TOUCHE_r :
self.action.actions.append("B CW")
elif event.key == TOUCHE_y :
self.action.actions.append("AV CW")
elif event.key == TOUCHE_u :
self.action.actions.append("AR CW")
elif event.key == TOUCHE_o :
self.action.actions.append("G CW")
elif event.key == TOUCHE_p :
self.action.actions.append("D CW")
elif event.key == TOUCHE_d :
self.action.actions.append("H ACW")
elif event.key == TOUCHE_f :
self.action.actions.append("B ACW")
elif event.key == TOUCHE_h :
self.action.actions.append("AV ACW")
elif event.key == TOUCHE_j :
self.action.actions.append("AR ACW")
elif event.key == TOUCHE_l :
self.action.actions.append("G ACW")
elif event.key == TOUCHE_m :
self.action.actions.append("D ACW")
elif event.key == TOUCHE_z :
print("stop")
# self.orientation[1] = -45
#elif event.key == K_RIGHT :
# self.orientation[0] = -45
# self.orientation[2] = -45
#elif event.key == K_LEFT :
# self.orientation[2] = 135
# self.orientation[0] = 135
#elif event.type == KEYUP:
# if event.key == K_UP :
# self.orientation[1] = 45
# elif event.key == K_RIGHT :
# self.orientation[0] = 45
# self.orientation[2] = 45
# elif event.key == K_LEFT :
# self.orientation[2] = 45
# self.orientation[0] = 45

25
ConstanteTouche.py Normal file
View file

@ -0,0 +1,25 @@
from pygame.locals import K_a
#TOUCHE_a = 113
TOUCHE_a = K_a
TOUCHE_z = 119
TOUCHE_e = 101
TOUCHE_r = 114
TOUCHE_t = 116
TOUCHE_y = 121
TOUCHE_u = 117
TOUCHE_i = 105
TOUCHE_o = 111
TOUCHE_p = 112
TOUCHE_q = 97
TOUCHE_s = 115
TOUCHE_d = 100
TOUCHE_f = 102
TOUCHE_g = 103
TOUCHE_h = 104
TOUCHE_j = 106
TOUCHE_k = 107
TOUCHE_l = 108
TOUCHE_m = 59
TOUCHE_b = 98

186
Cube.py Normal file
View file

@ -0,0 +1,186 @@
#!/usr/bin/env python3
# coding: utf-8
'''
Created on 16 mars 2017
Copyright 2017 Jean-Marie Mineau, Maxime Keller
This file is part of "ISN's Cube".
"ISN's Cube" is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
"ISN's Cube" is distributed in the hope that it will be useful and
recreative, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with "ISN's Cube". If not, see <http://www.gnu.org/licenses/>.
@author: <mineau.jean.marie@gmail.com>, Maxime Keller
'''
import pygame
from operator import itemgetter
from random import choice
from Cube1x1 import Cubie3D
from Action import Action
from CubeGetteur import CubeGetteur
from Commande import Commande
from Solveur import Solver
ROUGE, ORANGE, JAUNE, BLANC, VERT, BLEU = (255,0,0), (255,130,20), (255,255,20), (255,255,255), (0,255,0), (0,0,255)
class Cube(Commande, CubeGetteur, Solver):
"""Objet représentant le rubick's Cube."""
def __init__(self, screen, vide = False):
"""Init. ''vide'' permet d'éviter une réinitialisation de tous le cube."""
Commande.__init__(self, parent = self)
if not vide:
#Place les cubies
lpos = []
for x in [-4, 0, 4]:
for y in [-4, 0, 4]:
for z in [-4, 0, 4]:
lpos.append((x, y, z))
self.cubies = [Cubie3D(pos) for pos in lpos if pos != (0,0,0)]
self.orientation = [-30,30,0]
self.screen = screen
self.setColor()
def creationRefletNonOriente(self):
"""Crée un reflet du cube non orienté."""
newCube = Cube(None, vide = True)
newCube.orientation = [0,0,0]
newCubies = [cubie.copie() for cubie in self.cubies]
newCube.cubies = newCubies
newCube.screen = self.screen
return newCube
def creationReflet(self):
"""Crée un reflet du cube orienté selon l'orientation du cube."""
newCube = Cube(None, vide = True)
newCube.orientation = self.orientation
newCubies = [cubie.rotationX(self.orientation[0]) for cubie in self.cubies]
newCubies = [cubie.rotationY(self.orientation[1]) for cubie in newCubies]
newCubies = [cubie.rotationZ(self.orientation[2]) for cubie in newCubies]
newCube.cubies = newCubies
newCube.screen = self.screen
return newCube
def affichage(self):
"""Affiche le cube"""
cubiesZ = [[cubie, cubie.minZ] for cubie in self.cubies]
#self.nbImg = 0
liste = sorted(cubiesZ, key=itemgetter(1), reverse=True)
for tmp in liste:
cubie = tmp[0]
cubie.affichage(self.screen)
#pygame.display.flip()
#pygame.display.flip()
#pygame.image.save(screen,"./img/" + str(self.nbImg) + "Tri2.png")
#self.nbImg += 1
#pygame.time.wait(100)
def setColor(self):
"""Attribut les couleurs aux faces."""
liste = self.getH()
for i in liste:
self.cubies[i].couleurs[0] = ROUGE
self.cubies[i].couleursResolution.append(ROUGE)
liste = self.getB()
for i in liste:
self.cubies[i].couleurs[1] = ORANGE
self.cubies[i].couleursResolution.append(ORANGE)
liste = self.getG()
for i in liste:
self.cubies[i].couleurs[2] = JAUNE
self.cubies[i].couleursResolution.append(JAUNE)
liste = self.getD()
for i in liste:
self.cubies[i].couleurs[3] = BLANC
self.cubies[i].couleursResolution.append(BLANC)
liste = self.getAr()
for i in liste:
self.cubies[i].couleurs[4] = VERT
self.cubies[i].couleursResolution.append(VERT)
liste = self.getAv()
for i in liste:
self.cubies[i].couleurs[5] = BLEU
self.cubies[i].couleursResolution.append(BLEU)
def run(self):
"""Lance l'affichage."""
self.touches()
self.action()
reflet = self.creationReflet()
reflet.affichage()
if __name__ == "__main__":
pygame.init()
angle = 5
screen = pygame.display.set_mode((500, 500))
pygame.display.set_caption("Rubick's Cube")
cubes = [Cube(screen)]
prendreImage = False
rot = False
#cubes[0].orientation = [-30,30,0]
#print(cubes[0].cubies[cubes[0].getCubieByPos((1,1,-1))].getOrientationFace(ROUGE))
#cubes[0].action.actions.append("H CWI")
#cubes[0].action.actions.append("H CWI")
#cubes[0].action.actions.append("B CWI")
#cubes[0].action.actions.append("B CWI")
#cubes[0].action.actions.append("D CWI")
#cubes[0].action.actions.append("D CWI")
#cubes[0].action.actions.append("G CWI")
#cubes[0].action.actions.append("G CWI")
#cubes[0].action.actions.append("AV CWI")
#cubes[0].action.actions.append("AV CWI")
#cubes[0].action.actions.append("AR CWI")
#cubes[0].action.actions.append("AR CWI")
#cubes[0].action.doAll()
#cubes[0].action.actions.append("ALEA")
#cubes[0].resoudre()
while True:
#for event in pygame.event.get():
# if event.type == pygame.QUIT:
# pygame.quit()
# sys.exit()
# if event.type == pygame.KEYDOWN:
# if event.key == pygame.K_SPACE:
# if rot:
# rot = False
# else:
# rot = True
# if event.key == pygame.K_LEFT:
# angle = 5
# if event.key == pygame.K_RIGHT:
# angle = -5
screen.fill((255,255,255))
for cube in cubes:
cube.run()
pygame.display.flip()
#pygame.time.wait(25)
if rot:
for cube in cubes:
orientation = cube.orientation
cube.orientation = [alpha + angle for alpha in orientation]
if prendreImage:
pygame.image.save(screen,"./img/pasDeTrie.png")
prendreImage = False

510
Cube1x1.py Normal file
View file

@ -0,0 +1,510 @@
'''
Created on 9 mars 2017
Copyright 2017 Jean-Marie Mineau, Maxime Keller
This file is part of "ISN's Cube".
"ISN's Cube" is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
"ISN's Cube" is distributed in the hope that it will be useful and
recreative, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with "ISN's Cube". If not, see <http://www.gnu.org/licenses/>.
@author: <mineau.jean.marie@gmail.com>
Programme inspiré d'un programme dévellopé par Leonel Machava <leonelmachava@gmail.com>
http://codeNtronix.com
'''
import sys, math, pygame
from operator import itemgetter
class Point3D:
def __init__(self, x = 0, y = 0, z = 0):
self.x, self.y, self.z = float(x), float(y), float(z)
def rotationX(self, angle):
""" Fait pivoter le point autour de l'axe X d'une valeur donnée en degrés. """
rad = angle * math.pi / 180
cosa = math.cos(rad)
sina = math.sin(rad)
y = self.y * cosa - self.z * sina #Formules d'addition de trigo.
z = self.y * sina + self.z * cosa
return Point3D(self.x, y, z)
def rotationY(self, angle):
""" Fait pivoter le point autour de l'axe Y d'une valeur donnée en degrés. """
rad = angle * math.pi / 180
cosa = math.cos(rad)
sina = math.sin(rad)
z = self.z * cosa - self.x * sina #Formules d'addition de trigo.
x = self.z * sina + self.x * cosa
return Point3D(x, self.y, z)
def rotationZ(self, angle):
""" Fait pivoter le point autour de l'axe Z d'une valeur donnée en degrés. """
rad = angle * math.pi / 180
cosa = math.cos(rad)
sina = math.sin(rad)
x = self.x * cosa - self.y * sina #Formules d'addition de trigo.
y = self.x * sina + self.y * cosa
return Point3D(x, y, self.z)
def projection(self, largeur_ecran, hauteur_ecran, zoom, distance):
""" Transforme ce point 3D en point 2D (avec la profondeur conservé). """
factor = zoom / (distance + self.z)
x = self.x * factor + largeur_ecran / 2
y = -self.y * factor + hauteur_ecran / 2
return Point3D(x, y, self.z)
def __eq__(self, point):
"""opérateur d'égalité."""
x = abs(self.x - point.x) < 0.01
y = abs(self.y - point.y) < 0.01
z = abs(self.z - point.z) < 0.01
return x and y and z
def dans(self, points):
"""Test si un point est dans une liste de points avec une impressition."""
for point in points:
x = False
y = False
z = False
if abs(self.x - point.x) < 0.01:
x = True
if abs(self.y - point.y) < 0.01:
y = True
if abs(self.z - point.z) < 0.01:
z = True
if x and y and z:
return True
return False
def copie(self):
"""Retourne une copie de l'objet."""
return Point3D(self.x, self.y, self.z)
class Peintre:
"""Objet de tri pour les faces."""
def __init__(self, LARGEUR_ECRAN = 500, HAUTEUR_ECRAN = 500, ZOOM = 254, DISTANCE = 50, ECART_INTER = 0.01):
self.LARGEUR_ECRAN = LARGEUR_ECRAN # DISTANCE 10
self.HAUTEUR_ECRAN = HAUTEUR_ECRAN
self.ZOOM = ZOOM
self.DISTANCE = DISTANCE
self.ECART_INTER = ECART_INTER
self.coin = []
self.faces = []
def intersection(self, A, B, C, D):
"""Retourne l'intersection des secgments [point1 point2] et [point3 point4] en 2 dimentions"""
# Segments paralleles
if A.x == B.x and C.x == D.x: return None
elif (A.x == B.x):
c = (C.y - D.y)/(C.x - D.x)
d = C.y - (c*C.x)
x = A.x
y = c*x + d
elif (C.x == D.x):
a = (A.y - B.y)/(A.x - B.x)
b = A.y - (a*A.x)
x = C.x
y = a*x + b
else:
a = (A.y - B.y)/(A.x - B.x)
b = A.y - (a*A.x)
c = (C.y - D.y)/(C.x - D.x)
d = C.y - (c*C.x)
if a == c:
return None # Segment parallèles
elif a == 0:
y = B.y
x = (y - d)/c
elif c == 0:
y = D.y
x = (y - b/a)
else:
x = (d - b)/(a - c)
y = a*x + b
pointDansSegment1 = (min(A.x, B.x) + self.ECART_INTER < x < max(A.x, B.x) - self.ECART_INTER) \
and (min(A.y, B.y) + self.ECART_INTER < y < max(A.y, B.y) - self.ECART_INTER)
pointDansSegment2 = (min(C.x, D.x) + self.ECART_INTER < x < max(C.x, D.x) - self.ECART_INTER) \
and (min(C.y, D.y + self.ECART_INTER) < y < max(C.y, D.y) - self.ECART_INTER)
if pointDansSegment1 and pointDansSegment2:
return Point3D(x, y, 0)
else:
return None
def profondeurIntersection(self, A, B, I):
"""Retourne le point avec sa profondeur"""
x = I.x
y = I.y
if A.z == B.z:
z = A.z
return Point3D(x, y, z)
a = (A.x - B.x)/(A.z - B.z)
b = B.x - (a*B.z)
c = (A.y - B.y)/(A.z - B.z)
d = B.y - (c*B.z)
# Attention grosse formule!
denominateur = ((x - self.LARGEUR_ECRAN/2) - a*self.ZOOM)
if denominateur != 0:
z = (b*self.ZOOM - (x - self.LARGEUR_ECRAN/2)*self.DISTANCE)/denominateur
return Point3D(x, y, z)
denominateur = (c*self.ZOOM + y - self.HAUTEUR_ECRAN/2)
if denominateur != 0:
z = (-d*self.ZOOM - (y - self.HAUTEUR_ECRAN/2)*self.DISTANCE)/denominateur
return Point3D(x, y, z)
denominateur = (y - self.HAUTEUR_ECRAN/2 + (c+d)*self.ZOOM)
if denominateur != 0:
z = -(y - self.HAUTEUR_ECRAN/2)*self.DISTANCE/denominateur
return Point3D(x, y, z)
## Formules qui MARCHENT:
#z = - (y - HAUTEUR_ECRAN/2)*DISTANCE / (y - HAUTEUR_ECRAN/2 + (c+d)*ZOOM)
#z = (-d*ZOOM - (y - HAUTEUR_ECRAN/2)*DISTANCE)/(c*ZOOM + y - HAUTEUR_ECRAN/2)
#z = (b*ZOOM - (x - LARGEUR_ECRAN/2)*DISTANCE)/((x - LARGEUR_ECRAN/2) - a*ZOOM)
## Formules FAUSSENT z = ((y - HAUTEUR_ECRAN/2)*a/ZOOM + b) / (1- (a/ZOOM)*(y - HAUTEUR_ECRAN/2))
##z = ((x - LARGEUR_ECRAN/2)*DISTANCE - b*ZOOM)/(a*ZOOM - x - LARGEUR_ECRAN/2)
z = 0
return Point3D(x, y, z)
def tri(self, faces, intersections, segments, points3D, point2D):
"""Trie les faces en fonction des points d'intersection"""
# pointsSegments contient des listes avec en première valeur le point d'intersection
# en deuxième et troisième les extrèmitès du segment auquel il appartient.
# Ces listes vont normalement par paire.
while intersections:
# Selectionne deux points d'intersections de même position
intersection1 = intersections[0]
intersections = intersections[1:]
segment1 = segments[0]
segments = segments[1:]
for intersection2 in intersections:
if abs(intersection1.x - intersection2.x) < 0.01 and abs(intersection1.y - intersection2.y) < 0.01:
segment2 = segments[intersections.index(intersection2)]
segments.remove(segment2)
intersections.remove(intersection2)
break
# verifie la validite du point
if intersection1.x - intersection2.x < 0.01 and intersection1.y - intersection2.y < 0.01:
faces1 = []
faces2 = []
for face in faces:
i = faces.index(face)
pointsFaces = [points3D[j] for j in face]
if segment1[0].dans(pointsFaces) and \
segment1[1].dans(pointsFaces):
faces1.append(i)
if segment2[0].dans(pointsFaces) and \
segment2[1].dans(pointsFaces):
faces2.append(i)
# Nous avons associer deux points d'intersection de profondeur differentes
# aux faces qui contiennent le segment
# Il faut que les faces donc le segment est le plus proche soit avans les
# deux autres.
interTpm = [intersection1, intersection2]
facesTpm = [faces1, faces2]
# Le point le plus éloigné en premier, donc les premieres faces a afficher en premier
if interTpm[0].z > interTpm[1].z:
tmp = facesTpm[0]
facesTpm[0] = facesTpm[1]
facesTpm[1] = tmp
# les premieres faces doivent etre avant la limite
limite = min(facesTpm[0])
indice1, indice2 = facesTpm[1]
if indice1 > limite and indice2 > limite:
faces1Liste = faces[:limite]
faces2Liste = faces[limite:]
faces1Liste.append(faces[min(indice1, indice2)])
faces1Liste.append(faces[max(indice1, indice2)])
faces2Liste.remove(faces[indice1])
faces2Liste.remove(faces[indice2])
faces = faces1Liste + faces2Liste
elif indice1 > limite:
faces1Liste = faces[:limite]
faces2Liste = faces[limite:]
faces1Liste.append(faces[indice1])
faces2Liste.remove(faces[indice1])
faces = faces1Liste + faces2Liste
elif indice2 > limite:
faces1Liste = faces[:limite]
faces2Liste = faces[limite:]
faces1Liste.append(faces[indice2])
faces2Liste.remove(faces[indice2])
faces = faces1Liste + faces2Liste
return faces
def peintre1(self, faces, points2D):
"""Algorithme du peintre traditionnel."""
moy_z = []
i = 0
for f in faces:
z = (points2D[f[0]].z + points2D[f[1]].z + points2D[f[2]].z + points2D[f[3]].z) / 4.0
moy_z.append([i,z])
i = i + 1
nouvellesFaces = []
# Trie lessurfaces en utlisant l'algorithme du peintre
# Les faces les plus éloignées sont tracées avant les plus proches.
for tmp in sorted(moy_z,key=itemgetter(1),reverse=True):
indiceFace = tmp[0]
nouvellesFaces.append(faces[indiceFace])
return nouvellesFaces
def peintre2(self):
"""Retourne une liste de surface clasés selon l'algorythme du peintre, ainsi que leur couleur"""
points3D = self.coins
points2D = [i.projection(self.LARGEUR_ECRAN, self.HAUTEUR_ECRAN, self.ZOOM, self.DISTANCE) for i in self.coins]
faces = self.faces
intersections = []
segments = []
for face1 in self.faces:
#Test l'intersection de tous les point de chaque face
for face2 in self.faces:
for j in [-1, 0, 1, 2]:
for i in [-1, 0, 1, 2]:
A3D = points3D[face1[j]]
B3D = points3D[face1[j+1]]
C3D = points3D[face2[i]]
D3D = points3D[face2[i+1]]
A = points2D[face1[j]]
B = points2D[face1[j+1]]
C = points2D[face2[i]]
D = points2D[face2[i+1]]
inter = self.intersection(A, B, C, D)
if inter:
intersections.append(self.profondeurIntersection(A3D, B3D, inter))
segments.append([A3D, B3D])
intersections.append(self.profondeurIntersection(C3D, D3D, inter))
segments.append([C3D, D3D])
faces = self.peintre1(faces, points2D)
faces = self.tri(faces, intersections, segments, points3D, points2D)
return faces
class Cubie3D(Peintre):
"""Class définissant un cube en 3D"""
def __init__(self, pos):
"""Définit le cube de centre pos et de coté 2"""
Peintre.__init__(self)
self.centre = Point3D(pos[0], pos[1], pos[2])
self.coins = [
Point3D(pos[0]-2,pos[1]+2,pos[2]+2), # droit haut arrière
Point3D(pos[0]+2,pos[1]+2,pos[2]+2), # gauche haut arrière
Point3D(pos[0]-2,pos[1]+2,pos[2]-2), # droit haut avant
Point3D(pos[0]+2,pos[1]+2,pos[2]-2), # gauche haut avant
Point3D(pos[0]-2,pos[1]-2,pos[2]+2), # droit bas arrière
Point3D(pos[0]+2,pos[1]-2,pos[2]+2), # gauche bas arrière
Point3D(pos[0]-2,pos[1]-2,pos[2]-2), # droit bas avant
Point3D(pos[0]+2,pos[1]-2,pos[2]-2)] # gauche bas avant
#Liste des faces, les valeurs sont les indices du point correspondant dans la liste coins.
self.faces = [
(0,1,3,2), # Haut
(4,5,7,6), # Bas
(0,2,6,4), # Droite
(1,3,7,5), # Gauche
(0,1,5,4), # Arrière
(2,3,7,6)] # Avant
#Liste des couleurs, leur indices sont les mêmes que ceux de la faces associer.
self.couleurs = [
(0,0,0), #(255,0,0), # Haut
(0,0,0), #(255,70,0), # Bas
(0,0,0), #(255,255,0), # Gauche
(0,0,0), #(255,255,255), # Droite
(0,0,0), #(0,255,0), # Arrière
(0,0,0)] #(0,0,255)] # Avant
self.couleursResolution = []
def getMinZ(self):
"""Retourne la profondeur du point le plus proche."""
z = self.coins[0].z
for pt in self.coins:
if pt.z < z:
z = pt.z
return z
minZ = property(fget = getMinZ)
def rotationX(self, angle):
""" Fait pivoter le cube autour de l'axe X d'une valeur donnée en degrés. """
newCoins = []
for point in self.coins:
newCoins.append(point.rotationX(angle))
newCube = self.copie()
newCube.coins = newCoins
newCube.centre = self.centre.rotationX(angle)
return newCube
def rotationY(self, angle):
""" Fait pivoter le cube autour de l'axe Y d'une valeur donnée en degrés. """
newCoins = []
for point in self.coins:
newCoins.append(point.rotationY(angle))
newCube = self.copie()
newCube.coins = newCoins
newCube.coins = newCoins
newCube.centre = self.centre.rotationY(angle)
return newCube
def rotationZ(self, angle):
""" Fait pivoter le cube autour de l'axe Z d'une valeur donnée en degrés. """
newCoins = []
for point in self.coins:
newCoins.append(point.rotationZ(angle))
newCube = self.copie()
newCube.coins = newCoins
newCube.centre = self.centre.rotationZ(angle)
return newCube
def getOrientationFace(self, couleur):
"""Retourn l'orientation de la face de la couleur donnée.
Elle est donné sous la forme x, y, z, seul l'axe perpendiculaire
à la face est différent ce 0, et le signe son de quel côté du cube il ce trouve."""
indiceFace = self.couleurs.index(couleur)
pointsFace = [(self.coins[i].x, self.coins[i].y, self.coins[i].z) for i in self.faces[indiceFace]]
pointsFaceOposee = [(self.coins[i].x, self.coins[i].y, self.coins[i].z)
for i in range(len(self.coins)) if i not in self.faces[indiceFace]]
orientation = [0, 0, 0]
for i in [0, 1, 2]:
#on compart les coordonnées du premier point des deux faces, pour x, y puis z
if pointsFace[0][i] > pointsFaceOposee[0][i]: orientation[i] = 1
elif pointsFace[0][i] < pointsFaceOposee[0][i]: orientation[i] = -1
for point in pointsFace:
for i in [0, 1, 2]:
if abs(point[i] - pointsFace[0][i]) > 0.01:
#if point[i] != pointsFace[0][i]:
orientation[i] = 0
# pour donner l'axe de la face,
#on compart les coordonnées e x,y et z entre les points de la place.
if orientation == [0, 0, 0]:
raise Exception("Cette face ne semble pas avoir d'orientation, what?")
return tuple(orientation)
def affichage(self, screen):
"""Affiche le cube sur l'écran screen en utilisant l'algorithme du peintre"""
t = []
for coin in self.coins:
p = coin.projection(self.LARGEUR_ECRAN, self.HAUTEUR_ECRAN, self.ZOOM, self.DISTANCE)
# Place le point dans une liste de coins transformés
t.append(p)
# Trace la surface en utlisant l'algorithme du peintre
# Les faces les plus éloignées sont tracées avant les plus proches.
faces = self.peintre2()
for f in faces[-3:]:
pointlist = [(t[f[0]].x, t[f[0]].y), (t[f[1]].x, t[f[1]].y),
(t[f[1]].x, t[f[1]].y), (t[f[2]].x, t[f[2]].y),
(t[f[2]].x, t[f[2]].y), (t[f[3]].x, t[f[3]].y),
(t[f[3]].x, t[f[3]].y), (t[f[0]].x, t[f[0]].y)]
pygame.draw.polygon(screen,(0,0,0),pointlist, 3)
#Pour que les faces caches les traits
#en arrière, ils faut les affichers après les arrètes
pygame.draw.polygon(screen,self.couleurs[self.faces.index(f)],pointlist)
#pygame.display.flip()
#pygame.time.wait(100)
def copie(self):
"""Retourne une copie de l'objet."""
newCubie = Cubie3D((0,0,0))
newCubie.centre = self.centre
newCubie.coins = self.coins
newCubie.faces = self.faces
newCubie.couleurs = self.couleurs
newCubie.couleursResolution = self.couleursResolution
return newCubie
if __name__ == "__main__":
###nb_image = 0 #######
pygame.init()
cubes = [Cubie3D((-2,-2,-2))]
angle = 5
screen = pygame.display.set_mode((500, 500))
pygame.display.set_caption("Rubick's Cube")
rot = True
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
if rot:
rot = False
else:
rot = True
if event.key == pygame.K_LEFT:
angle = 5
if event.key == pygame.K_RIGHT:
angle = -5
screen.fill((255,255,255))
for cube in cubes:
cube.affichage(screen)
#if nb_image == 40:
# pygame.quit()
# sys.exit()
#pygame.image.save(screen,"./img/" + str(nb_image)+".png")
#nb_image+=1################################################
pygame.display.flip()
pygame.time.wait(100)
if rot:
for i, cube in enumerate(cubes):
cubes[i] = cube.rotationZ(angle)#.rotationY(angle).rotationX(angle)

207
CubeGetteur.py Normal file
View file

@ -0,0 +1,207 @@
#!/usr/bin/env python3
#coding: utf-8
'''
Created on 5 avr. 2017
Copyright 2017 Jean-Marie Mineau, Maxime Keller
This file is part of "ISN's Cube".
"ISN's Cube" is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
"ISN's Cube" is distributed in the hope that it will be useful and
recreative, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with "ISN's Cube". If not, see <http://www.gnu.org/licenses/>.
@author: <mineau.jean.marie@gmail.com>
Sert à traiter des cubies.
'''
from operator import itemgetter
class CubeGetteur:
"""Sert à traiter des cubies."""
def __init__(self):
pass
def getH(self):
"""Récupère les cubie du haut et retourne leur index."""
cubiesH = []
for cubie in self.cubies:
if len(cubiesH) < 9:
cubiesH.append([self.cubies.index(cubie), cubie.centre.y])
else:
cubiesH = sorted(cubiesH,key=itemgetter(1))
if cubiesH[0][1] < cubie.centre.y:
cubiesH = cubiesH[1:]
cubiesH.append([self.cubies.index(cubie), cubie.centre.y])
cubiesH = [item[0] for item in cubiesH]
return cubiesH
def getB(self):
"""Récupère les cubie du bas et retourne leur index."""
cubiesH = []
for cubie in self.cubies:
if len(cubiesH) < 9:
cubiesH.append([self.cubies.index(cubie), cubie.centre.y])
else:
cubiesH = sorted(cubiesH,key=itemgetter(1), reverse=True)
if cubiesH[0][1] > cubie.centre.y:
cubiesH = cubiesH[1:]
cubiesH.append([self.cubies.index(cubie), cubie.centre.y])
cubiesH = [item[0] for item in cubiesH]
return cubiesH
def getD(self):
"""Récupère les cubie de droite et retourne leur index."""
cubiesD = []
for cubie in self.cubies:
if len(cubiesD) < 9:
cubiesD.append([self.cubies.index(cubie), cubie.centre.x])
else:
cubiesD = sorted(cubiesD,key=itemgetter(1))
if cubiesD[0][1] < cubie.centre.x:
cubiesD = cubiesD[1:]
cubiesD.append([self.cubies.index(cubie), cubie.centre.x])
cubiesD = [item[0] for item in cubiesD]
return cubiesD
def getG(self):
"""Récupère les cubie de Gauche et retourne leur index."""
cubiesG = []
for cubie in self.cubies:
if len(cubiesG) < 9:
cubiesG.append([self.cubies.index(cubie), cubie.centre.x])
else:
cubiesG = sorted(cubiesG,key=itemgetter(1), reverse=True)
if cubiesG[0][1] > cubie.centre.x:
cubiesG = cubiesG[1:]
cubiesG.append([self.cubies.index(cubie), cubie.centre.x])
cubiesG = [item[0] for item in cubiesG]
return cubiesG
def getAv(self):
"""Récupère les cubie derrière et retourne leur index."""
cubiesA = []
for cubie in self.cubies:
if len(cubiesA) < 9:
cubiesA.append([self.cubies.index(cubie), cubie.centre.z])
else:
cubiesH = sorted(cubiesA,key=itemgetter(1), reverse=True)
if cubiesH[0][1] > cubie.centre.z:
cubiesA = cubiesH[1:]
cubiesA.append([self.cubies.index(cubie), cubie.centre.z])
cubiesA = [item[0] for item in cubiesA]
return cubiesA
def getAr(self):
"""Récupère les cubie de derrière et retourne leur index."""
cubiesA = []
for cubie in self.cubies:
if len(cubiesA) < 9:
cubiesA.append([self.cubies.index(cubie), cubie.centre.z])
else:
cubiesA = sorted(cubiesA,key=itemgetter(1))
if cubiesA[0][1] < cubie.centre.z:
cubiesA = cubiesA[1:]
cubiesA.append([self.cubies.index(cubie), cubie.centre.z])
cubiesA = [item[0] for item in cubiesA]
return cubiesA
def getCubieByPos(self, pos):
"""Retourne l'indice du Cubie de pos donné. Cette pos est relative au cube,
elle est donné en x,y,z, l'origine étant le centre du cube, et l'unité
correspond à 1 cubie."""
if pos[0] == -1:
potentielsCubies = self.getG()
elif pos[0] == 1:
potentielsCubies = self.getD()
elif pos[0] == 0:
#Celui est est plus embetant, il n'y a pas de méthode pour les recuperer
#Donc c'est toutes les valeur sauf celle des deux autre tranchhes.
indicesFaux = self.getG() + self.getD()
potentielsCubies = [i for i in range(len(self.cubies)) if i not in indicesFaux]
else:
raise ValueError("Vous devez demander une ordonné de -1, 0 ou 1")
# Parce que la pep 20 est bien
if pos[1] == -1:
potentielsCubies = [i for i in potentielsCubies if i in self.getB()]
elif pos[1] == 1:
potentielsCubies = [i for i in potentielsCubies if i in self.getH()]
elif pos[1] == 0:
indicesFaux = self.getB() + self.getH()
potentielsCubies = [i for i in potentielsCubies if i not in indicesFaux]
else:
raise ValueError("Vous devez demander une abscice de -1, 0 ou 1")
#Errors should never pass silently.
if pos[2] == -1:
potentielsCubies = [i for i in potentielsCubies if i in self.getAv()]
elif pos[2] == 1:
potentielsCubies = [i for i in potentielsCubies if i in self.getAr()]
elif pos[2] == 0:
indicesFaux = self.getAv() + self.getAr()
potentielsCubies = [i for i in potentielsCubies if i not in indicesFaux]
else:
raise ValueError("Vous devez demander une profondeur de -1, 0 ou 1")
#Oui, aujourd'hui j'ai voulu faire propre.
if len(potentielsCubies) > 1:
raise Exception("Maxime, je sait pas comment t'as fait, mais t'as réussit à trouver \
Une coordonnée avec plusieurs Cubie!!!")
elif len(potentielsCubies) == 0:
raise Exception("Pas de Cubies ici, peut être avez vous demandé l'origine?")
else:
return potentielsCubies[0]
def getCubieByColors(self, couleurs):
"""Retourne l'indice du Cubie de couleurs données. Ces couleurs sont
une liste donnant les couleurs exact, mais pas obligatoirement dans l'ordre."""
for cubie in self.cubies:
if len(couleurs) != len(cubie.couleursResolution):
continue
bonCubie = True
for couleur in couleurs:
if couleur not in cubie.couleursResolution:
bonCubie = False
break
if bonCubie: return self.cubies.index(cubie)
raise Exception("Pas de cubies correspondanr aux couleurs données.")
def getPosRelative(self, cubie):
"""Retourne la position relative du cubie (don on donne l'indice)."""
if cubie not in range(len(self.cubies)):
raise ValueError("Vous devez rentrer un indice de l'argument 'cubies'.")
if cubie in self.getG():
x = -1
elif cubie in self.getD():
x = 1
else:
x = 0
if cubie in self.getB():
y = -1
elif cubie in self.getH():
y = 1
else :
y = 0
if cubie in self.getAv():
z = -1
elif cubie in self.getAr():
z = 1
else:
z = 0
return x, y, z

80
InterfaceBoutons.py Normal file
View file

@ -0,0 +1,80 @@
#!/usr/bin/env python3
#coding: utf-8
"""
Copyright 2017 Jean-Marie Mineau, Maxime Keller
This file is part of "ISN's Cube".
"ISN's Cube" is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
"ISN's Cube" is distributed in the hope that it will be useful and
recreative, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with "ISN's Cube". If not, see <http://www.gnu.org/licenses/>.
@author: <mineau.jean.marie@gmail.com>
Interface de boutons fait à la va vite.
"""
import pygame
from Bouton import Boutons
def addAction(cube, action):
"""Ajoute une action à la liste."""
cube.action.actions.append(action)
CARACTS_BOUTONS = [[(100,30), "img/B1.png", addAction, ["ALEA"]],
[(400,30), "img/B2.png", addAction, ["SOLVE"]],
[(100,600), None, addAction, ["B CW"]],
[(500,600), None, addAction, ["B ACW"]],
[(200,600), None, addAction, ["AV CW"]],
[(400,600), None, addAction, ["AV ACW"]],
[(100,150), None, addAction, ["H CW"]],
[(500,150), None, addAction, ["H ACW"]],
[(200,150), None, addAction, ["AR CW"]],
[(400,150), None, addAction, ["AR ACW"]],
[(100,350), None, addAction, ["G CW"]],
[(100,450), None, addAction, ["G ACW"]],
[(500,350), None, addAction, ["D CW"]],
[(500,450), None, addAction, ["D ACW"]]]
class InterfaceBoutons:
"""interface gérant l'ensemble des boutons."""
def __init__(self, screen, cube, caractsBoutons=None):
"""caractsBoutons est une liste contenants des listes
de caracteristiques des boutons, dans l'ordre:
[position, img, callback, argsCallback]"""
if caractsBoutons is None:
caractsBoutons = CARACTS_BOUTONS
self.screen = screen
self.cube = cube
self.boutons = Boutons()
for caracts in caractsBoutons:
pos, img, callback, argsCallback = caracts
# Bon c'est pas propre mais faut bien mettre le Cube
# quelque part...
argsCallback = [self.cube] + argsCallback
self.boutons.nouveauBouton(pos, image=img, callback=callback,
argsCallback=argsCallback)
def run(self):
"""Affiche et check les envents pour une itération de la
boucle principale."""
events = self.cube.events
self.boutons.update(events)
self.boutons.display(self.screen)

734
Solveur.py Normal file
View file

@ -0,0 +1,734 @@
#!/usr/bin/env python3
# coding: utf-8
'''
Created on 5 avr. 2017
Copyright 2017 Jean-Marie Mineau, Maxime Keller
This file is part of "ISN's Cube".
"ISN's Cube" is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
"ISN's Cube" is distributed in the hope that it will be useful and
recreative, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with "ISN's Cube". If not, see <http://www.gnu.org/licenses/>.
@author: <mineau.jean.marie@gmail.com>
Solveur du cube à faire hériter à un Cube.
'''
class Solver:
"""Class pour résoudre le Cube,
Faire hériter.
Résoud un reflet avec des action instantanées
(en ajoutant un I a la direction, CWI ou ACWI)"""
def __init__(self):
pass
def resoudre(self):
"""Méthode principale.
Pour une question de vitesse, elle résoud un cube virtuel (reflet)
et retourn la liste d'action à éfectuer sur le modèle d'origine."""
####/DEBUG\####
self.action.doAll()
####\DEBUG/####
resolution = []
reflet = self.creationRefletNonOriente()
resolution.extend(self.croixHaute(reflet))
resolution.extend(self.coinsHaut(reflet))
resolution.extend(self.arretesMilieu(reflet))
actions = ["X CW", "X CW"]
resolution.extend(actions)
reflet.action.actions.extend([action + "I" for action in actions])
reflet.action.doAll()
resolution.extend(self.croixBas(reflet))
resolution.extend(self.croixBasArrete(reflet))
resolution.extend(self.coinsBasPos(reflet))
resolution.extend(self.orientationCoinsBas(reflet))
####/DEBUG\####
#resolution = [i + "I" for i in resolution]
#self.action.actions.extend(resolution)
#self.action.doAll()
#resolution =[]
####\DEBUG/####
print(resolution)
self.action.actions.extend(resolution)
def croixHaute(self, cube):
"""Résoud la croix du haut."""
resolution = []
for i in range(4):
resolution.extend(self.croixHauteArreteDeFace(cube))
cube.action.actions.append("Y CWI")
cube.action.doAll()
resolution.append("Y CW")
return resolution
def croixHauteArreteDeFace(self, cube):
"""Place l'arrete de face."""
resolution = []
#Positionne l'arrete
centreAv = cube.getCubieByPos((0,0,-1))
centreH = cube.getCubieByPos((0,1,0))
couleurAv = cube.cubies[centreAv].couleursResolution[0]
couleurH = cube.cubies[centreH].couleursResolution[0]
couleursArrete = [couleurAv, couleurH]
arrete = cube.getCubieByColors(couleursArrete)
posArrete = cube.getPosRelative(arrete)
####/DEBUG\####
#savePos = posArrete
####\DEBUG/####
# Le but de cette parti est de placer l'arrete en (1,-1,0), cad face de droite millieu bas.
if posArrete == (0,1,-1): #La position finale
orientation = cube.cubies[arrete].getOrientationFace(couleurH)
if orientation == (0,1,0): #Vers le Haut
return resolution
else:
actions = ["AV CW", "AV CW", "B ACW"]
resolution.extend(actions)
cube.action.actions.extend([action + "I" for action in actions])
cube.action.doAll()
elif posArrete[1] == 1: #Le cubie est sur la face du Haut
if posArrete[0] == -1:
actions = ["G CW", "G CW"]
elif posArrete[0] == 0:
actions = ["AR CW", "AR CW"]
elif posArrete[0] == 1:
actions = ["D CW", "D CW"]
resolution.extend(actions)
cube.action.actions.extend([action + "I" for action in actions])
cube.action.doAll()
elif posArrete[1] == 0: # Le cubie est sur la tranche du Millieu
if posArrete[0] == -1: # Cette action place place ce cubie sur la face du Bas, mais pas forcement
if posArrete[2] == -1: # à la bonne place
actions = ["G ACW", "B CW", "G CW"]
elif posArrete[2] == 1:
actions = ["G CW", "B CW", "G ACW"]
elif posArrete[0] == 1:
if posArrete[2] == -1:
actions = ["D ACW", "B CW", "D CW"]
elif posArrete[2] == 1:
actions = ["D CW", "B CW", "D ACW"]
resolution.extend(actions)
cube.action.actions.extend([action + "I" for action in actions])
cube.action.doAll()
#Normalement, arrivé ici, l'arrete est forcement sur la face du bas.
posArrete = cube.getPosRelative(arrete)
####/DEBUG\####
#if posArrete[1] != -1:
# print("error")
# print(savePos)
#nbIter = 0
####\DEBUG/####
while not posArrete == (1,-1,0):
actions = ["B CW"]
resolution.extend(actions)
cube.action.actions.extend([action + "I" for action in actions])
cube.action.doAll()
posArrete = cube.getPosRelative(arrete)
####/DEBUG\####
#nbIter += 1
#if nbIter > 10:
# print("Error")
####\DEBUG/####
#Maintenant, la face est en (1,-1,0), il reste une formule à appliquer,
#qu'il faut choisir en fonction de l'orientation du cubie.
orientation = cube.cubies[arrete].getOrientationFace(couleurH)
if orientation == (0,-1,0):
actions = ["B CW", "AV CW", "AV CW"]
else:
actions = ["D CW", "AV CW", "D ACW"]
resolution.extend(actions)
cube.action.actions.extend([action + "I" for action in actions])
cube.action.doAll()
# Une arrete de finit!
return resolution
def coinsHaut(self, cube):
"""Résoud les coins de la face du haut."""
resolution = []
for i in range(4):
resolution.extend(self.coinHaut(cube))
cube.action.actions.append("Y CWI")
cube.action.doAll()
resolution.append("Y CW")
return resolution
def coinHaut(self, cube):
"""Résoud le coin en (1,1,-1), cad face avant, coin haut droit."""
resolution = []
#Position du coin
centreAv = cube.getCubieByPos((0,0,-1))
centreH = cube.getCubieByPos((0,1,0))
centreD = cube.getCubieByPos((1,0,0))
couleurAv = cube.cubies[centreAv].couleursResolution[0]
couleurH = cube.cubies[centreH].couleursResolution[0]
couleurD = cube.cubies[centreD].couleursResolution[0]
couleursCoin = [couleurAv, couleurH, couleurD]
coin = cube.getCubieByColors(couleursCoin)
posCoin = cube.getPosRelative(coin)
####/DEBUG\####
#savePos = posArrete
####\DEBUG/####
#Si le point est en Haut, le but est de le mettre sur la face du Bas
actions = None
if posCoin == (1,1,-1): #Pos final
orientation = cube.cubies[coin].getOrientationFace(couleurH)
if orientation == (0,1,0):#Bien placé
return resolution
else:
actions = ["D ACW", "B CW", "D CW"]
elif posCoin == (1,1,1):
actions = ["D CW", "B CW", "D ACW"]
elif posCoin == (-1,1,1):
actions = ["G CW", "B CW", "G ACW"]
elif posCoin == (-1,1,-1):
actions = ["G ACW", "B CW", "G CW"]
if actions is not None:
resolution.extend(actions)
cube.action.actions.extend([action + "I" for action in actions])
cube.action.doAll()
#Positionne le coin en (1,-1,-1), cad face avant, coin bas droit.
posCoin = cube.getPosRelative(coin)
####/DEBUG\####
#if posCoin[1] != -1:
# print("Error")
####\DEBUG/####
while posCoin != (1,-1,-1):
actions = ["B CW"]
resolution.extend(actions)
cube.action.actions.extend([action + "I" for action in actions])
cube.action.doAll()
posCoin = cube.getPosRelative(coin)
#Positionne le coin en (1,1,-1) et l'oriente.
orientation = cube.cubies[coin].getOrientationFace(couleurH)
if orientation == (1,0,0):
actions = ["B ACW", "AV ACW", "B CW", "AV CW"]
elif orientation == (0,-1,0):
actions = ["D ACW", "B ACW", "D CW", "B CW", "AV ACW", "B CW", "AV CW"]
else:
actions = ["B CW", "D ACW", "B ACW", "D CW"]
resolution.extend(actions)
cube.action.actions.extend([action + "I" for action in actions])
cube.action.doAll()
return resolution
def arretesMilieu(self, cube):
"""Résoud les arrêtes de la tranche du milieu."""
resolution = []
for i in range(4):
resolution.extend(self.arreteMillieuxDroit(cube))
cube.action.actions.append("Y CWI")
cube.action.doAll()
resolution.append("Y CW")
return resolution
def arreteMillieuxDroit(self, cube):
"""Résoud l'arrete du milieux droit de la face Avant (1,0,-1)."""
resolution = []
#Positionne l'arrete
centreAv = cube.getCubieByPos((0,0,-1))
centreD = cube.getCubieByPos((1,0,0))
couleurAv = cube.cubies[centreAv].couleursResolution[0]
couleurD = cube.cubies[centreD].couleursResolution[0]
couleursArrete = [couleurAv, couleurD]
arrete = cube.getCubieByColors(couleursArrete)
posArrete = cube.getPosRelative(arrete)
orientation = cube.cubies[arrete].getOrientationFace(couleurAv)
if posArrete == (1,0,-1) and orientation == (0,0,-1):
return resolution
elif posArrete[1] == 0:
#Si l'arrete est sur la tranche du milieu.
while not posArrete == (1,0,-1):
#positionne le cube de facon à placer l'arrete en (1,0,-1)
cube.action.actions.append("Y CWI")
cube.action.doAll()
resolution.append("Y CW")
posArrete = cube.getPosRelative(arrete)
resolution.extend(self.belgeD(cube))
posCentreAv = cube.getPosRelative(centreAv)
while not posCentreAv == (0,0,-1):
#positionne le cube de facon à replacer la face de depart en face.
cube.action.actions.append("Y CWI")
cube.action.doAll()
resolution.append("Y CW")
posCentreAv = cube.getPosRelative(centreAv)
posArrete = cube.getPosRelative(arrete)
while not posArrete == (0,-1,-1):
#Place l'arrete en bas de la face.
cube.action.actions.append("B CWI")
cube.action.doAll()
resolution.append("B CW")
posArrete = cube.getPosRelative(arrete)
orientation = cube.cubies[arrete].getOrientationFace(couleurAv)
if orientation == (0,0,-1):
resolution.extend(self.belgeD(cube))
else:
actions = ["Y CW", "B ACW"]
resolution.extend(actions)
cube.action.actions.extend([action + "I" for action in actions])
cube.action.doAll()
resolution.extend(self.belgeG(cube))
cube.action.actions.append("Y ACWI")
cube.action.doAll()
resolution.append("Y ACW")
posArrete = cube.getPosRelative(arrete)
posArrete = cube.getPosRelative(arrete)
####/DEBUG\####
#if posArrete != (1,0,-1):
# print("error")
# print(resolution)
####\DEBUG/####
return resolution
def belgeD(self, cube):
"""Applique l'algo du Belge à droite."""
resolution = ["B CW", "D ACW", "B ACW", "D CW", "B ACW", "AV ACW", "B CW", "AV CW"]
cube.action.actions.extend([action + "I" for action in resolution])
cube.action.doAll()
return resolution
def belgeG(self, cube):
"""Applique l'algo du Belge à gauche."""
resolution = ["B ACW", "G ACW", "B CW", "G CW", "B CW", "AV CW", "B ACW", "AV ACW"]
cube.action.actions.extend([action + "I" for action in resolution])
cube.action.doAll()
return resolution
def croixBas(self, cube):
"""Résoud la croix du bas (pour la resolution, le cube est retourné,
donc la croix du bas est en fait en haut)."""
resolution = []
posAretes, boolOrientation, nbBienOriente = self.croixBasOrientation(cube)
iG = posAretes.index((-1,1,0))
iD = posAretes.index((1,1,0))
iAv = posAretes.index((0,1,-1))
iAr = posAretes.index((0,1,1))
if nbBienOriente == 4:
return resolution
elif nbBienOriente == 0:
resolution.extend(self.algoCroixBas(cube))
cube.action.actions.append("Y CWI")
cube.action.doAll()
resolution.append("Y CW")
resolution.extend(self.algoCroixBas(cube))
resolution.extend(self.algoCroixBas(cube))
return resolution
elif nbBienOriente == 2:
aligne = (boolOrientation[iG] and boolOrientation[iD]) or \
(boolOrientation[iAr] and boolOrientation[iAv])
if aligne:
if not (boolOrientation[iAr] and boolOrientation[iAv]):
cube.action.actions.append("Y CWI")
cube.action.doAll()
resolution.append("Y CW")
resolution.extend(self.algoCroixBas(cube))
resolution.extend(self.algoCroixBas(cube))
else:
while not (boolOrientation[iAr] and boolOrientation[iG]):
cube.action.actions.append("Y CWI")
cube.action.doAll()
resolution.append("Y CW")
posAretes, boolOrientation, nbBienOriente = self.croixBasOrientation(cube)
resolution.extend(self.algoCroixBas(cube))
else:
print("Mais commenent quoi comment?")
return resolution
def croixBasOrientation(self, cube):
"""Retourne une liste associant position des arretes
et une bool indiquant si leur orientation est bonne
au pas et le nombre d'orientation correct."""
#Résoud les orientation
centreH = cube.getCubieByPos((0,1,0))
couleurH = cube.cubies[centreH].couleursResolution[0]
retourBoolOrientation = []
retourPos = [(-1,1,0), (0,1,-1), (1,1,0), (0,1,1)]
nbOrientationBonnes = 0
for pos in retourPos:
cubie = cube.getCubieByPos(pos)
orientation = cube.cubies[cubie].getOrientationFace(couleurH)
if orientation == (0,1,0):
boolOrientation = True
nbOrientationBonnes += 1
else: boolOrientation = False
retourBoolOrientation.append(boolOrientation)
return retourPos, retourBoolOrientation, nbOrientationBonnes
def algoCroixBas(self, cube):
"""Applique l'algo pour la croix du bas."""
resolution = ["D ACW", "H ACW", "AV CW", "H CW", "AV ACW", "D CW"]
cube.action.actions.extend([action + "I" for action in resolution])
cube.action.doAll()
return resolution
def croixBasArrete(self, cube):
"""Resolution de la position des arretes de la face du bas."""
resolution = []
posAretes, posTheo, nbPosBonnes = self.testCroixBas(cube)
iG = posAretes.index((-1,1,0))
iD = posAretes.index((1,1,0))
iAv = posAretes.index((0,1,-1))
iAr = posAretes.index((0,1,1))
if nbPosBonnes == 4:
return resolution
while nbPosBonnes == 0:
cube.action.actions.append("H CWI")
cube.action.doAll()
resolution.append("H CW")
posAretes, posTheo, nbPosBonnes = self.testCroixBas(cube)
if nbPosBonnes == 4:
return resolution
if nbPosBonnes == 2:
aligne = (posAretes[iG] == posTheo[iG]) and (posAretes[iD] == posTheo[iD]) or \
(posAretes[iAv] == posTheo[iAv]) and (posAretes[iAr] == posTheo[iAr])
if aligne:
if posAretes[iD] == posTheo[iD]:
cube.action.actions.append("H CWI")
cube.action.doAll()
resolution.append("H CW")
resolution.extend(self.algoTCW(cube))
posAretes, posTheo, nbPosBonnes = self.testCroixBas(cube)
while nbPosBonnes == 0:
cube.action.actions.append("H CWI")
cube.action.doAll()
resolution.append("H CW")
posAretes, posTheo, nbPosBonnes = self.testCroixBas(cube)
if nbPosBonnes == 4:
return resolution
elif nbPosBonnes == 2:
print("Mais, cette configuration n'est pas sensé exister!")
return resolution
else:
#nbBoucle = 0
while nbPosBonnes != 1:
cube.action.actions.append("H CWI")
cube.action.doAll()
resolution.append("H CW")
posAretes, posTheo, nbPosBonnes = self.testCroixBas(cube)
####/DEBUG\####
#nbBoucle += 1
#if nbBoucle > 10:
# print("Trop d'iteration")
####\DEBUG/####
if nbPosBonnes == 1:
while posAretes[iG] != posTheo[iG]:
cube.action.actions.append("Y CWI")
cube.action.doAll()
resolution.append("Y CW")
posAretes, posTheo, nbPosBonnes = self.testCroixBas(cube)
if posAretes[iAv] == posTheo[iAr]:
resolution.extend(self.algoTCW(cube))
elif posAretes[iAr] == posTheo[iAv]:
resolution.extend(self.algoTACW(cube))
else:
print("wtf")
return resolution
def algoTACW(self, cube):
"""Algo de resolution en T dans le sens anti horaire,
décale les cubies de la face du haut en forme de T
orienté le bas à droite, le haut à gauche.
Permet aussi de changer l'orientation des coins combinés à
algoTCW."""
resolution = ["D ACW", "H ACW", "D CW", "H ACW", "D ACW", "H ACW", "H ACW", "D CW", "H ACW", "H ACW"]
cube.action.actions.extend([action + "I" for action in resolution])
cube.action.doAll()
return resolution
def algoTCW(self, cube):
"""Algo de resolution en T dans le sens horaire,
décale les cubies de la face du haut en forme de T
orienté le bas à droite, le haut à gauche.
Permet aussi de changer l'orientation des coins combinés à
algoTACW."""
resolution = ["D CW", "H CW", "D ACW", "H CW", "D CW", "H CW", "H CW", "D ACW", "H CW", "H CW"]
cube.action.actions.extend([action + "I" for action in resolution])
cube.action.doAll()
return resolution
def testCroixBas(self, cube):
"""Test les arrete de la croix bas (donc en haut car le cube est retourné).
Retourne la position des cubies, la position final des cubies et le nombre
de cubies à la bonne place."""
centreH = cube.getCubieByPos((0,1,0))
couleurH = cube.cubies[centreH].couleursResolution[0]
retourPosTheo = [None, None, None, None]
nbPosBonnes = 0
retourPos = [(-1,1,0), (0,1,-1), (1,1,0), (0,1,1)]
couleursFace = []
for p in retourPos:
p = (p[0],0,p[2])
c = cube.getCubieByPos(p)
couleursFace.append(cube.cubies[c].couleursResolution[0])
for p in retourPos:
c = cube.getCubieByPos(p)
couleur = [ i for i in cube.cubies[c].couleursResolution if i != couleurH][0]
i = couleursFace.index(couleur)
retourPosTheo[i] = p
if i == retourPos.index(p):
nbPosBonnes += 1
return retourPos, retourPosTheo, nbPosBonnes
def coinsBasPos(self, cube):
"""Place les coins du bas (du haut comme le cube est retourné)
à leur position."""
resolution = []
posCoins, posCoinsTheo, nbPosBonnes = self.testCoinsBas(cube)
iAvG = posCoins.index((-1,1,-1))
iAvD = posCoins.index((1,1,-1))
iArD = posCoins.index((1,1,1))
iArG = posCoins.index((-1,1,1))
if nbPosBonnes == 0:
resolution.extend(self.algoTriangleCW(cube))
posCoins, posCoinsTheo, nbPosBonnes = self.testCoinsBas(cube)
if nbPosBonnes == 4:
return resolution
elif nbPosBonnes != 1:
print("On vous a bien dit que le tournevis n'est pas la solution!")
return resolution
while posCoins[iAvD] != posCoinsTheo[iAvD]:
cube.action.actions.append("Y CWI")
cube.action.doAll()
resolution.append("Y CW")
posCoins, posCoinsTheo, nbPosBonnes = self.testCoinsBas(cube)
if posCoins[iArD] == posCoinsTheo[iAvG]:
resolution.extend(self.algoTriangleCW(cube))
elif posCoins[iAvG] == posCoinsTheo[iArD]:
cube.action.actions.append("Y CWI")
cube.action.doAll()
resolution.append("Y CW")
resolution.extend(self.algoTriangleACW(cube))
else:
print("PAS DE TOURNEVIS!")
return resolution
def algoTriangleCW(self, cube):
"""Algorithme en triangle dans le sens horaire, sur la face du haut,
décale les coins dans le sens hoaire, sauf le coin avant droit."""
resolution = ["G CW", "H CW", "D CW", "H ACW", "G ACW", "H CW", "D ACW", "H ACW"]
cube.action.actions.extend([action + "I" for action in resolution])
cube.action.doAll()
return resolution
def algoTriangleACW(self, cube):
"""Algorithme en triangle dans le sens anti horaire, sur la face du haut,
décale les coins dans le sens anti hoaire, sauf le coin avant gauche."""
resolution = ["D CW", "H ACW", "G CW", "H CW", "D ACW", "H ACW", "G ACW", "H CW"]
cube.action.actions.extend([action + "I" for action in resolution])
cube.action.doAll()
return resolution
def testCoinsBas(self, cube):
"""Test les coins du bas (donc du haut car le cube est retourné).
Retourne la position des cubies, la position final des cubies et le nombre
de cubies à la bonne place."""
retourPosTheo = [None, None, None, None]
nbPosBonnes = 0
retourPos = [(-1,1,-1), (1,1,-1), (1,1,1), (-1,1,1)]
couleursCoins = []
# Creer la liste couleursCoins qui contien la couleur des
# cubie qui devraient ce trouver à cette place.
for p in retourPos:
couleurs = []
avancement = 0
for i in p:
pos = [0,0,0]
pos[avancement] = i
avancement += 1
c = cube.getCubieByPos(tuple(pos))
couleurs.append(cube.cubies[c].couleursResolution[0])
couleursCoins.append(couleurs)
for couleurs in couleursCoins:
# Met la position théorique du coin dans la liste pos théorique
# à l'indice correspondant à sa position.
c = cube.getCubieByColors(couleurs)
posRelative = cube.getPosRelative(c)
retourPosTheo[couleursCoins.index(couleurs)] = posRelative
if posRelative == retourPos[couleursCoins.index(couleurs)]:
nbPosBonnes += 1
return retourPos, retourPosTheo, nbPosBonnes
def orientationCoinsBas(self, cube):
"""Oriente les coins de la face du bas (qui est en haut
car le cube est retourné)."""
resolution = []
posCoins, orientationCoin, nbBonneOrientation = self.testOrientationCoinsBas(cube)
#Indices des pos
iAvG = posCoins.index((-1,1,-1))
iAvD = posCoins.index((1,1,-1))
iArD = posCoins.index((1,1,1))
iArG = posCoins.index((-1,1,1))
####/DEBUG\####
#print((orientationCoin, nbBonneOrientation))
####\DEBUG/####
if nbBonneOrientation == 4:
return resolution
if nbBonneOrientation == 0:
while not self.testOrientationCoinsBasHomogene(cube):
cube.action.actions.append("Y CWI")
cube.action.doAll()
resolution.append("Y CW")
resolution.extend(self.resolutionOrientationCoinsBasHomogene(cube))
posCoins, orientationCoin, nbBonneOrientation = self.testOrientationCoinsBas(cube)
if nbBonneOrientation == 1:
while not orientationCoin[iAvD] == (0,1,0):
cube.action.actions.append("Y CWI")
cube.action.doAll()
resolution.append("Y CW")
posCoins, orientationCoin, nbBonneOrientation = self.testOrientationCoinsBas(cube)
resolution.extend(self.algoTCW(cube))
resolution.extend(self.algoTACW(cube))
posCoins, orientationCoin, nbBonneOrientation = self.testOrientationCoinsBas(cube)
if nbBonneOrientation == 2:
diagonal = (orientationCoin[iAvD] == (0,1,0) and orientationCoin[iArG] == (0,1,0)) or \
(orientationCoin[iArD] == (0,1,0) and orientationCoin[iAvG] == (0,1,0))
if diagonal:
while not orientationCoin[iAvD] == (1,0,0):
cube.action.actions.append("Y CWI")
cube.action.doAll()
resolution.append("Y CW")
posCoins, orientationCoin, nbBonneOrientation = self.testOrientationCoinsBas(cube)
actions = ["AV CW"]
resolution.extend(actions)
cube.action.actions.extend([action + "I" for action in actions])
cube.action.doAll()
resolution.extend(self.algoTCW(cube))
resolution.extend(self.algoTACW(cube))
actions = ["AV ACW"]
resolution.extend(actions)
cube.action.actions.extend([action + "I" for action in actions])
cube.action.doAll()
else:
while not self.testOrientationCoinsBasHomogene(cube):
cube.action.actions.append("Y CWI")
cube.action.doAll()
resolution.append("Y CW")
posCoins, orientationCoin, nbBonneOrientation = self.testOrientationCoinsBas(cube)
resolution.extend(self.resolutionOrientationCoinsBasHomogene(cube))
return resolution
def testOrientationCoinsBasHomogene(self, cube):
"""Test si les coins de droite orienté de façon "Homogene", cad
orientable par la fonction associer. Utilisé dans le cadre de
l'orentation des coin de la face du bas. (en haut parce que le cube
est retourné)"""
posCoins, orientationCoin, nbBonneOrientation = self.testOrientationCoinsBas(cube)
#Indices des pos
iAvG = posCoins.index((-1,1,-1))
iArG = posCoins.index((-1,1,1))
facesHautesVersLaDoite = (orientationCoin[iAvG] == (-1,0,0) and orientationCoin[iArG] == (-1,0,0))
facesHautesVersAvAr = (orientationCoin[iAvG] == (0,0,-1) and orientationCoin[iArG] == (0,0,1))
return (facesHautesVersLaDoite or facesHautesVersAvAr)
def resolutionOrientationCoinsBasHomogene(self, cube):
"""Oriente correctement les coins en (-1,1,-1) et (-1,1,1) si ils sont
"Homogene". S'utilise dans le cadre de l'orientation des coins du bas.
(qui sont en haut car on a retournés le cube)"""
if not self.testOrientationCoinsBasHomogene(cube):
raise Exception("Les coins ne sont pas Homogènes.")
resolution = []
posCoins, orientationCoin, nbBonneOrientation = self.testOrientationCoinsBas(cube)
#Indices des pos
iAvG = posCoins.index((-1,1,-1))
iArG = posCoins.index((-1,1,1))
if (orientationCoin[iAvG] == (0,0,-1) and orientationCoin[iArG] == (0,0,1)):
resolution.extend(self.algoTCW(cube))
resolution.extend(self.algoTACW(cube))
elif (orientationCoin[iAvG] == (-1,0,0) and orientationCoin[iArG] == (-1,0,0)):
actions = ["Z ACW", "Y CW", "Y CW"]
resolution.extend(actions)
cube.action.actions.extend([action + "I" for action in actions])
cube.action.doAll()
resolution.extend(self.algoTCW(cube))
resolution.extend(self.algoTACW(cube))
actions = ["Y CW", "Y CW", "Z CW"]
resolution.extend(actions)
cube.action.actions.extend([action + "I" for action in actions])
cube.action.doAll()
return resolution
def testOrientationCoinsBas(self, cube):
"""Test l'orientation des coins de la face du bas
(qui eest en haut parce que le cube est retourné.
Retourn la liste de la position des coins, celle de leur
orientation et le nombre de coin bien orientés."""
retourOrientation = []
nbBonneOrientation = 0
retourPos = [(-1,1,-1), (1,1,-1), (1,1,1), (-1,1,1)]
cubieCentreHaut = cube.getCubieByPos((0,1,0))
couleurH = cube.cubies[cubieCentreHaut].couleursResolution[0]
for pos in retourPos:
cubie = cube.getCubieByPos(pos)
orientation = cube.cubies[cubie].getOrientationFace(couleurH)
retourOrientation.append(orientation)
if orientation == (0,1,0):
nbBonneOrientation += 1
return retourPos, retourOrientation, nbBonneOrientation

BIN
img/B1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
img/B2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

53
main.py Normal file
View file

@ -0,0 +1,53 @@
#!/usr/bin/env python3
#coding: utf-8
'''
Created on 5 mai 2017
Copyright 2017 Jean-Marie Mineau, Maxime Keller
This file is part of "ISN's Cube".
"ISN's Cube" is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
"ISN's Cube" is distributed in the hope that it will be useful and
recreative, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with "ISN's Cube". If not, see <http://www.gnu.org/licenses/>.
@author: <mineau.jean.marie@gmail.com>, Maxime Keller
https://www.python.org/ (c'est le language, donc important)
Module principale du programme de Rubicks cube.
'''
import this # (c'est important aussi)
import pygame
from Cube import Cube
from InterfaceBoutons import InterfaceBoutons
if __name__ == "__main__":
pygame.init()
surfaceCube = pygame.Surface((500, 500))
screen = pygame.display.set_mode((700, 700))
pygame.display.set_caption("ISN's Cube")
cube = Cube(surfaceCube)
interfaceBoutons = InterfaceBoutons(screen, cube)
while True:
surfaceCube.fill((255,255,255))
screen.fill((255,255,255))
cube.run()
screen.blit(surfaceCube, (100,100))
interfaceBoutons.run()
pygame.display.flip()
pygame.time.wait(25)