Просмотр исходного кода

Création de la classe Action
Création d'une fonction de pathfinding (encore rudimentaire, mais fonctionnelle)

unknown 10 лет назад
Родитель
Сommit
998deccf10
2 измененных файлов с 258 добавлено и 0 удалено
  1. 153 0
      lib/AEtoile.py
  2. 105 0
      lib/Actions.py

+ 153 - 0
lib/AEtoile.py

@@ -0,0 +1,153 @@
+#from __future__ import unicode_literals
+# -*- coding: utf-8 -*-
+"""algorithme de recherche du plus court chemin entre deux cases"""
+from math import *
+
+
+def distance(coord1, coord2):
+    return sqrt((coord1[0] - coord2[0])**2 + (coord1[1] - coord2[1])**2)
+
+def distanceCarree(coord1, coord2):
+    """bcp plus rapide a calculer que la distance reelle"""
+    return (coord1[0] - coord2[0])**2 + (coord1[1] - coord2[1])**2
+
+def chemin(plateau, origine, cible):
+    """retourne la liste des coord a traverser pour atteindre l'objectif
+        se base sur la fonction estFranchissable() des cases"""
+
+    nO = N(origine)
+    nO.parent = None
+    nO.coutG = 0
+    nO.cout = 0
+
+    filOuvert = []   #"liste ouverte": noeuds etudies et a etudier
+    filFerme = [nO]    #"liste fermee":  noeuds retenus
+    chemin = []
+    position = nO
+    echec = False
+    it = 0
+    #on continue jusqu'a tomber sur la case cible, ou jusqu'a un echec
+    while position.coord != cible and not echec:
+        it += 1
+        print "##", it, position.coord
+        
+        #on etudie tous les voisins de la case en cours
+        for coord in plateau.cases[position.coord].voisins:
+            
+            #on elimine les cases deja retenues (celles qui sont dans le fil ferme)
+            trouve = False
+            for nTest in filFerme:
+                if nTest.coord == coord:
+                    trouve = True
+            if not trouve:
+                
+                #on elimine les cases infranchissables
+                if plateau.cases[coord].estFranchissable():
+                    noeud = N(coord)
+                    
+                    #on calcule le cout de la case
+                    noeud.creer(position, cible)
+
+                    #si le noeud est trouve dans la liste ouverte, on le compare a celui-ci
+                    # si ce nouveau noeud a un meilleur cout, on remplace
+                    # sinon on ajoute ce noeud a la liste ouverte
+                    trouve = False
+                    for nTest in filOuvert:
+                        if nTest.coord == noeud.coord:
+                            nTest.parent = noeud.parent
+                            nTest.cout = noeud.cout
+                            trouve = True
+                            print " | teste", coord, "maj", noeud.coutG, noeud.coutH
+                            
+                    if not trouve:
+                        filOuvert.append(noeud)
+                        print " | teste", coord, "ajout", noeud.coutG, noeud.coutH
+
+        #on parcourt les noeuds de la liste ouverte
+        #et on cherche le meilleur noeud (le cout le plus faible)
+        #si trouve: on l'ajoute a la liste fermee, on le retire de la liste ouverte et on continue
+        #sinon, le chemin n'existe pas
+        meilleur = None                
+                        
+        for noeud in filOuvert:
+            if meilleur == None:
+                meilleur = noeud
+            else:
+                if noeud.cout < meilleur.cout:
+                    meilleur = noeud
+        print " >> retenu", meilleur.coord, meilleur.cout
+                
+        if meilleur:
+            filFerme.append(meilleur)
+            filOuvert.remove(meilleur)
+            position = meilleur
+        else:
+            echec = True
+
+        for n in reversed(filFerme):    
+            chemin.append(n.coord)
+            
+    return chemin                    
+                    
+class N():
+    """noeud du chemin"""
+    def __init__(self, coord):
+        self.parent = None    #coord du noeud qui a amene a ce noeud-ci
+        self.coord = coord
+        self.coutG = 0
+        self.coutH = 0
+        self.cout = 0
+
+##    def __repr__(self):
+##        return "{} ({}+{}= {}) |".format(self.coord, self.coutG, self.coutH, self.cout)
+
+    def creer(self, parent, cible):
+        self.parent = parent
+        self.coutH = distanceCarree(self.coord, cible)
+        self.coutG = self.parent.coutG + 1
+        self.cout =  self.coutG + self.coutH
+
+
+### pour les tests
+##
+##class Plateau():
+##    def __init__(self):
+##        self.cases = {}
+##
+##class Case():
+##    def __init__(self, coord):
+##        self.coord = coord
+##        self.voisins = []
+##        self.majVoisins()
+##        
+##    def majVoisins(self):
+##        for x in range(1, 6):
+##            for y in range(1, 6):
+##                if x in [self.coord[0] - 1, self.coord[0], self.coord[0] + 1] and \
+##                   y in [self.coord[1] - 1, self.coord[1], self.coord[1] + 1] and \
+##                   (x, y) != self.coord:
+##                    self.voisins.append((x, y))
+##
+##    def estFranchissable(self):
+##        return not (self.coord[0]==2 and self.coord[1] in [2, 3, 4, 5])
+##
+##
+##plateau = Plateau()
+##
+##for x in range(1, 6):
+##    for y in range(1, 6):
+##        plateau.cases[(x, y)] = Case((x, y))
+##
+##
+##depart = (1, 2)
+##arrivee = (5, 5)
+##        
+##print chemin(plateau, depart, arrivee)
+##
+
+
+
+
+
+
+        

+ 105 - 0
lib/Actions.py

@@ -0,0 +1,105 @@
+#from __future__ import unicode_literals
+# -*- coding: utf-8 -*-
+
+
+class Action():
+    """action effectuee par un combattant sur le plateau de jeu"""
+    def __init__(self):
+        self._num = None         #no du pion actif
+        self._coordCible = None  #coord de la case ciblee par le curseur
+        self._cible = None       #cible (case ou pion)
+
+
+    def activer(self, plateau):
+        self.plateau = plateau
+
+    def majCoordCible(self, coord):
+        """met a jour les coordonnees de la cible,
+            cad la case actuellement survolee par la souris"""
+        if self.plateau.estCoordonneeValide(coord):
+            self._coordCible = coord
+            self.maj()
+
+    def desactiver(self):
+        pass
+
+    def valider(self):
+        #envoyer signal
+        self.desactiver()
+
+    def estValide(self):
+        return True
+
+    def maj(self):
+        pass
+
+    def acteur(self):
+        return self.plateau.combattants[self._num]
+
+    def coordActeur(self):
+        return self.acteur().position
+
+    #manipulation des items graphiques
+    def creerItemsGraphiques(self):
+        pass
+
+    def majItemsGraphiques(self):
+        pass    
+
+    def detruireItemsGraphiques(self):
+        pass
+
+    #affichage des cibles
+    def afficherCibles(self, actif):
+        pass
+
+
+class Deplacement(Action):
+    def __init__(self):
+        super(Deplacement, self).__init__(self)
+        self._chemin = []  #liste des coord des cases a traverser
+        self._cout = 0     #cout en points de dep
+
+
+    def activer(self, plateau):
+        super(Deplacement, self).activer(self, plateau)
+
+    def majCoordCible(self, coord):
+        if coord != self.coordActeur():
+            super(Deplacement, self).majCoordCible(self, coord)
+
+    def maj(self):
+        self.afficherCibles(False)
+
+        self._chemin = []
+        self._cout = 0
+
+        coordInit = self.coordActeur()
+        ki = 0
+        fil = []
+        
+        
+
+        self.afficherCibles(True)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+        
+