#from __future__ import unicode_literals # -*- coding: utf-8 -*- from __future__ import division class Forme(): """forme a affecter a une creature, decor ou autre...""" def __init__(self, formeCases = "H", parent=None): self.formeDef = [] #coord relatives par rapport a la case (0,0) definissant la forme (vide si forme 1*1) #les anneaux sont utilises pour les rotations (coordonnees relatives a la case centrale) #attention: il est important que les cases soient enregistrees dans le sens de la rotation (sens des aiguilles d'une montre) self.formeCases = formeCases # "C" ou "H" pour carre ou hexagone def anneau(self, distance=0): """renvoie la liste des cases situees a [distance] cases du centre, dans l'ordre des aiguilles d'une montre""" anneau = {} if self.formeCases == "H": anneau[1] = [(0,-1),(1,0),(1,1),(0,1),(-1,1),(-1,0)] anneau[2] = [(0,-2),(1,-1),(2,-1),(2,0),(2,1),(1,2),(0,2),(-1,2),(-2,1),(-2,0),(-2,-1),(-1,-1)] anneau[3] = [(0,-3),(1,-2),(2,-2),(3,-1),(3,0),(3,1),(3,2),(2,2),(1,3), \ (0,3),(-1,3),(-2,2),(-3,2),(-3,1),(-3,0),(-3,-1),(-2,-2),(-1,-2)] anneau[4] = [(0,-4),(1,-3),(2,-3),(3,-2),(4,-2),(4,-1),(4,0),(4,1),(4,2),(3,3),(2,3),(1,4), \ (0,4),(-1,4),(-2,3),(-3,3),(-4,2),(-4,1),(-4,0),(-4,-1),(-4,-2),(-3,-2),(-2,-3),(-1,-3)] anneau[5] = [(0,-5),(1,-4),(2,-4),(3,-3),(4,-3),(5,-2),(5,-1),(5,0),(5,1),(5,2),(5,3),(4,3),(3,4),(2,4),(1,5), \ (0,5),(-1,5),(-2,4),(-3,4),(-4,3),(-5,3),(-5,2),(-5,1),(-5,0),(-5,-1),(-5,-2),(-4,-3),(-3,-3),(-2,-4),(-1,-4)] elif self.formeCases == "C": anneau[1] = [(0,-1),(1,-1),(1,0),(1,1),\ (0,1),(-1,1),(-1,0),(-1,-1)] anneau[2] = [(0,-2),(1,-2),(2,-2),(2,-1),(2,0),(2,1),(2,2),(1,2),\ (0,2),(-1,2),(-2,2),(-2,1),(-2,0),(-2,-1),(-2,-2),(-1,-2)] anneau[3] = [(0,-3),(1,-3),(2,-3),(3,-3),(3,-2),(3,-1),(3,0),(3,1),(3,2),(3,3),(2,3),(1,3),\ (0,3),(-1,3),(-2,3),(-3,3),(-3,2),(-3,1),(-3,0),(-3,-1),(-3,-2),(-3,-3),(-2,-3),(-1,-3)] anneau[4] = [(0,-4),(1,-4),(2,-4),(3,-4),(4,-4),(4,-3),(4,-2),(4,-1),(4,0),(4,1),(4,2),(4,3),(4,4),(3,4),(2,4),(1,4),\ (0,4),(-1,4),(-2,4),(-3,4),(-4,4),(-4,3),(-4,2),(-4,1),(-4,0),(-4,-1),(-4,-2),(-4,-3),(-4,-4),(-3,-4),(-2,-4),(-1,-4)] anneau[5] = [(0,-5),(1,-5),(2,-5),(3,-5),(4,-5),(5,-5),(5,-4),(5,-3),(5,-2),(5,-1),(5,0),(5,1),(5,2),(5,3),(5,4),(5,5),(4,5),(3,5),(2,5),(1,5),\ (0,5),(-1,5),(-2,5),(-3,5),(-4,5),(-5,5),(-5,4),(-5,3),(-5,2),(-5,1),(-5,0),(-5,-1),(-5,-2),(-5,-3),(-5,-4),(-5,-5),(-4,-5),(-3,-5),(-2,-5),(-1,-5)] if distance > 0: retour = anneau[distance] elif distance == 0: retour = anneau return retour def __repr__(self): """renvoie la liste des cases occupees par la forme""" retour = str(self.listeCases((0,0))) return retour def ajouterCase(self, coordRelatives): """ajoute une case a la liste des cases occupees de la forme""" ajoutee = False if not coordRelatives in self.formeDef: for distance in self.anneau(0): if coordRelatives in self.anneau(distance): self.formeDef.append(coordRelatives) ajoutee = True if not ajoutee: print("case non prise en charge (trop eloignee du centre)") def definirForme(self, formeDef): """utilise une forme pre-definie""" self.formeDef = [] if formeDef: if len(formeDef)>0: for coordRelatives in formeDef: self.ajouterCase(coordRelatives) def retirerCase(self, coordRelatives): """retire une case a la liste des cases occupees de la forme""" if coordRelatives in self.formeDef: self.formeDef.remove(coordRelatives) def pivoter(self, nbRotations = 1): """pivote si possible la forme dans le sens '+' ou '-' et renvoie la liste des cases qui seront occupees""" sens = 1 if nbRotations < 0: sens = -1 formeDefPivote = [] tmp = self.formeDef if self.formeCases == "H": k = 1 else: k = 2 #on avance de deux cases sur l'anneau dans le cas de cases carrees if len(self.formeDef) > 0: for i in range(0,abs(nbRotations)): for coord in tmp: ## #correctif a appliquer pour les abscisses impaires avec cases hexa ## cy = 0 ## if self.formeCases == "H" and 1==(coord[0]%2): ## cy = 1 ## coord = (coord[0], coord[1]+cy) #on trouve dans quel anneau se situe cette case distance = 0 i = 0 while distance == 0 and i <= len(self.anneau(0)): i += 1 if coord in self.anneau(i): distance = i #si on a trouve la case, on la deplace selon les conditions de la rotation if distance > 0: #position actuelle dans la liste des cases de l'anneau position = self.anneau(distance).index(coord) #le pivot entraine un deplacement dans la liste des cases de l'anneau egal a sa distance au centre nouvellePosition = position + k*sens*distance #retour au debut/a la fin de l'anneau si on atteint la fin/ le debut if nouvellePosition >= len(self.anneau(distance)): nouvellePosition -= len(self.anneau(distance)) elif nouvellePosition < 0: nouvellePosition += len(self.anneau(distance)) #on retrouve les nouvelles coordonnees relatives a partir de la position dans l'anneau nouvellesCoord = self.anneau(distance)[nouvellePosition] #on ajoute cette position a la nouvelle definition de forme formeDefPivote.append((nouvellesCoord[0], nouvellesCoord[1])) else: print("{} non trouvee dans les anneaux".format(coord)) tmp = formeDefPivote formeDefPivote = [] formeDefPivote = tmp return formeDefPivote def listeCases(self, coordCibles, nbRotations = 0): """renvoie la liste des cases occupees par la forme en cours""" retour = [coordCibles] if nbRotations != 0: formeEnCours = self.pivoter(nbRotations) else: formeEnCours = self.formeDef if len(formeEnCours) > 0: for coordRelatives in formeEnCours: #correctif a appliquer pour les abscisses impaires avec cases hexa cy = 0 if self.formeCases == "H" and 0==(coordCibles[0]%2): if 1==(coordRelatives[0]%2): cy = -1 retour.append((coordCibles[0]+coordRelatives[0], coordCibles[1]+coordRelatives[1]+cy)) return retour