Forme.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #from __future__ import unicode_literals
  2. # -*- coding: utf-8 -*-
  3. from __future__ import division
  4. class Forme():
  5. """forme a affecter a une creature, decor ou autre..."""
  6. def __init__(self, formeCases = "H", parent=None):
  7. self.formeDef = [] #coord relatives par rapport a la case (0,0) definissant la forme (vide si forme 1*1)
  8. #les anneaux sont utilises pour les rotations (coordonnees relatives a la case centrale)
  9. #attention: il est important que les cases soient enregistrees dans le sens de la rotation (sens des aiguilles d'une montre)
  10. self.formeCases = formeCases # "C" ou "H" pour carre ou hexagone
  11. def anneau(self, distance=0):
  12. """renvoie la liste des cases situees a [distance] cases du centre, dans l'ordre des aiguilles d'une montre"""
  13. anneau = {}
  14. if self.formeCases == "H":
  15. anneau[1] = [(0,-1),(1,0),(1,1),(0,1),(-1,1),(-1,0)]
  16. 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)]
  17. anneau[3] = [(0,-3),(1,-2),(2,-2),(3,-1),(3,0),(3,1),(3,2),(2,2),(1,3), \
  18. (0,3),(-1,3),(-2,2),(-3,2),(-3,1),(-3,0),(-3,-1),(-2,-2),(-1,-2)]
  19. 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), \
  20. (0,4),(-1,4),(-2,3),(-3,3),(-4,2),(-4,1),(-4,0),(-4,-1),(-4,-2),(-3,-2),(-2,-3),(-1,-3)]
  21. 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), \
  22. (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)]
  23. elif self.formeCases == "C":
  24. anneau[1] = [(0,-1),(1,-1),(1,0),(1,1),\
  25. (0,1),(-1,1),(-1,0),(-1,-1)]
  26. anneau[2] = [(0,-2),(1,-2),(2,-2),(2,-1),(2,0),(2,1),(2,2),(1,2),\
  27. (0,2),(-1,2),(-2,2),(-2,1),(-2,0),(-2,-1),(-2,-2),(-1,-2)]
  28. 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),\
  29. (0,3),(-1,3),(-2,3),(-3,3),(-3,2),(-3,1),(-3,0),(-3,-1),(-3,-2),(-3,-3),(-2,-3),(-1,-3)]
  30. 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),\
  31. (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)]
  32. 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),\
  33. (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)]
  34. if distance > 0:
  35. retour = anneau[distance]
  36. elif distance == 0:
  37. retour = anneau
  38. return retour
  39. def __repr__(self):
  40. """renvoie la liste des cases occupees par la forme"""
  41. retour = str(self.listeCases((0,0)))
  42. return retour
  43. def ajouterCase(self, coordRelatives):
  44. """ajoute une case a la liste des cases occupees de la forme"""
  45. ajoutee = False
  46. if not coordRelatives in self.formeDef:
  47. for distance in self.anneau(0):
  48. if coordRelatives in self.anneau(distance):
  49. self.formeDef.append(coordRelatives)
  50. ajoutee = True
  51. if not ajoutee:
  52. print("case non prise en charge (trop eloignee du centre)")
  53. def definirForme(self, formeDef):
  54. """utilise une forme pre-definie"""
  55. self.formeDef = []
  56. if formeDef:
  57. if len(formeDef)>0:
  58. for coordRelatives in formeDef:
  59. self.ajouterCase(coordRelatives)
  60. def retirerCase(self, coordRelatives):
  61. """retire une case a la liste des cases occupees de la forme"""
  62. if coordRelatives in self.formeDef:
  63. self.formeDef.remove(coordRelatives)
  64. def pivoter(self, nbRotations = 1):
  65. """pivote si possible la forme dans le sens '+' ou '-' et renvoie la liste des cases qui seront occupees"""
  66. sens = 1
  67. if nbRotations < 0: sens = -1
  68. formeDefPivote = []
  69. tmp = self.formeDef
  70. if self.formeCases == "H":
  71. k = 1
  72. else:
  73. k = 2 #on avance de deux cases sur l'anneau dans le cas de cases carrees
  74. if len(self.formeDef) > 0:
  75. for i in range(0,abs(nbRotations)):
  76. for coord in tmp:
  77. ## #correctif a appliquer pour les abscisses impaires avec cases hexa
  78. ## cy = 0
  79. ## if self.formeCases == "H" and 1==(coord[0]%2):
  80. ## cy = 1
  81. ## coord = (coord[0], coord[1]+cy)
  82. #on trouve dans quel anneau se situe cette case
  83. distance = 0
  84. i = 0
  85. while distance == 0 and i <= len(self.anneau(0)):
  86. i += 1
  87. if coord in self.anneau(i):
  88. distance = i
  89. #si on a trouve la case, on la deplace selon les conditions de la rotation
  90. if distance > 0:
  91. #position actuelle dans la liste des cases de l'anneau
  92. position = self.anneau(distance).index(coord)
  93. #le pivot entraine un deplacement dans la liste des cases de l'anneau egal a sa distance au centre
  94. nouvellePosition = position + k*sens*distance
  95. #retour au debut/a la fin de l'anneau si on atteint la fin/ le debut
  96. if nouvellePosition >= len(self.anneau(distance)):
  97. nouvellePosition -= len(self.anneau(distance))
  98. elif nouvellePosition < 0:
  99. nouvellePosition += len(self.anneau(distance))
  100. #on retrouve les nouvelles coordonnees relatives a partir de la position dans l'anneau
  101. nouvellesCoord = self.anneau(distance)[nouvellePosition]
  102. #on ajoute cette position a la nouvelle definition de forme
  103. formeDefPivote.append((nouvellesCoord[0], nouvellesCoord[1]))
  104. else:
  105. print("{} non trouvee dans les anneaux".format(coord))
  106. tmp = formeDefPivote
  107. formeDefPivote = []
  108. formeDefPivote = tmp
  109. return formeDefPivote
  110. def listeCases(self, coordCibles, nbRotations = 0):
  111. """renvoie la liste des cases occupees par la forme en cours"""
  112. retour = [coordCibles]
  113. if nbRotations != 0:
  114. formeEnCours = self.pivoter(nbRotations)
  115. else:
  116. formeEnCours = self.formeDef
  117. if len(formeEnCours) > 0:
  118. for coordRelatives in formeEnCours:
  119. #correctif a appliquer pour les abscisses impaires avec cases hexa
  120. cy = 0
  121. if self.formeCases == "H" and 0==(coordCibles[0]%2):
  122. if 1==(coordRelatives[0]%2):
  123. cy = -1
  124. retour.append((coordCibles[0]+coordRelatives[0], coordCibles[1]+coordRelatives[1]+cy))
  125. return retour