Add files via upload
This commit is contained in:
parent
845468e869
commit
ad2d020b19
12 changed files with 2193 additions and 0 deletions
143
Action.py
Normal file
143
Action.py
Normal 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
151
Bouton.py
Normal 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
104
Commande.py
Normal 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
25
ConstanteTouche.py
Normal 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
186
Cube.py
Normal 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
510
Cube1x1.py
Normal 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
207
CubeGetteur.py
Normal 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
80
InterfaceBoutons.py
Normal 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
734
Solveur.py
Normal 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
BIN
img/B1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
BIN
img/B2.png
Normal file
BIN
img/B2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
53
main.py
Normal file
53
main.py
Normal 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)
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue