Преглед изворни кода

Pathfinding implémenté et fonctionnel

unknown пре 10 година
родитељ
комит
14388d0466

+ 5 - 0
doc/Algo de pathfinding.url

@@ -0,0 +1,5 @@
+[{000214A0-0000-0000-C000-000000000046}]
+Prop3=19,2
+[InternetShortcut]
+URL=http://qiao.github.io/PathFinding.js/visual/
+IDList=

+ 31 - 7
lib/AEtoile.py

@@ -3,8 +3,8 @@
 """algorithme de recherche du plus court chemin entre deux cases"""
 from math import *
 import time
-from threading import Thread
-
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
 #pour des performances correctes, ne pas utiliser pour de deplacements de plus de 100 cases
 
         
@@ -30,9 +30,9 @@ class N():
         self.kDep = kDep
         self.coutH = distanceCarree(self.coord, cible)
         self.coutG = self.parent.coutG + self.kDep
-        self.cout =  (self.coutG)**2 + self.coutH
+        self.cout =  self.coutG + self.coutH
 
-class Chemin(Thread):
+class Chemin():
     def __init__(self, plateau, origine, cible):
         self.plateau = plateau
         self.origine = origine
@@ -40,13 +40,21 @@ class Chemin(Thread):
         self.echec = False
         self.stop = False
 
+        ###active l'evolution sur le plateau
+        self.debug = False
+
     def arreter(self):
         self.stop = True
 
     def liste(self):
         """retourne la liste des coord a traverser pour atteindre l'objectif
            se base sur la fonction estFranchissable() des cases"""
-        Thread.__init__(self)
+        if self.debug:
+            for coord in self.plateau.cases:
+                self.plateau.cases[coord].majEstCibleCurseur(False)
+                self.plateau.cases[coord].majEstCibleAttaque(False)
+                QApplication.processEvents()
+
         t0 = time.time()
         nO = N(self.origine)
         nO.parent = None
@@ -60,7 +68,10 @@ class Chemin(Thread):
         echec = False
         
         #on continue jusqu'a tomber sur la case cible, ou jusqu'a un echec
+        it = 0
         while position.coord != self.cible and not self.echec:
+            it += 1
+##            print "iteration: ", i
             
             #on etudie tous les voisins de la case en cours
             for coord in self.plateau.cases[position.coord].voisins:
@@ -95,6 +106,10 @@ class Chemin(Thread):
                                     
                         if not trouve:
                             filOuvert.append(noeud)
+                            if self.debug:
+                                self.plateau.cases[noeud.coord].majEstCibleCurseur(True, True)
+                                time.sleep(0.05)
+                                QApplication.processEvents()
 
             #on parcourt les noeuds de la liste ouverte
             #et on cherche le meilleur noeud (le cout le plus faible)
@@ -112,6 +127,10 @@ class Chemin(Thread):
                     
             if meilleur:
                 filFerme.append(meilleur)
+                if self.debug:
+                    self.plateau.cases[meilleur.coord].majEstCibleCurseur(True, False)
+                    QApplication.processEvents()
+                    time.sleep(0.05)
                 filOuvert.remove(meilleur)
                 position = meilleur
             else:
@@ -122,10 +141,15 @@ class Chemin(Thread):
             while position.coord != self.origine:
                 if self.stop: return []
                 chemin.insert(0, position.coord)
+                if self.debug:
+                    self.plateau.cases[position.coord].majEstCibleCurseur(False)
+                    self.plateau.cases[position.coord].majEstCibleAttaque(True)
+                    QApplication.processEvents()
+                
                 position = position.parent
         else:
-            chemin = []
-        print len(chemin), time.time() - t0
+            chemin = []          
+        
         return chemin   
     
 ### pour les tests

+ 25 - 6
lib/Actions.py

@@ -67,6 +67,9 @@ class Action(object):
     def envoiSignal(self):
         pass
 
+    def pivoter(self, modRotation):
+        pass
+
 class Deplacement(Action):
     ### a completer avec des icones de deplacement,
     #la prise en compte de la nage et de l'escalade
@@ -76,17 +79,27 @@ class Deplacement(Action):
         self._chemin = []  #liste des coord des cases a traverser
         self._chercheurChemin = None
         self._cout = 0     #cout en points de dep
-        self._t0 = 0       #date de la derniere maj, pour eviter l'accumulation de mises a jours lors du survol des cases
+        self.cible_aConfirmer = None
 
+    def activer(self, plateau, numPion):
+        super(Deplacement, self).activer(plateau, numPion)
+        self.plateau.proj.creer(self.acteur())
+        
     def desactiver(self):
+        self.plateau.proj.desactiver()
         if self._chercheurChemin:
+            self._chercheurChemin.arreter()
             self._chercheurChemin = None
         super(Deplacement, self).desactiver()
 
     def valider(self):
-        if self.estValide():
-            self.plateau.pionDeposer(self._coordCible)
-            super(Deplacement, self).valider()
+        if not self.cible_aConfirmer or self.cible_aConfirmer != self._coordCible:             
+            self.cible_aConfirmer = self._coordCible
+            self.creerChemin()
+        else:
+            if self.estValide():
+                pion.majPosition(self.proj.coord(), self.proj.nbRotations())
+                super(Deplacement, self).valider()
 
     def estValide(self):
         return len(self._chemin)>0
@@ -96,15 +109,21 @@ class Deplacement(Action):
             super(Deplacement, self).majCoordCible(coord)
 
     def maj(self):
+        self.plateau.proj.majCoord(self._coordCible)
+
+    def pivoter(self, modRotation):
+        self.plateau.proj.majRotation(modRotation)
+            
+    def creerChemin(self):
         self.afficherCibles(False)
         self._chemin = []
         self._cout = 0
         if self._chercheurChemin:
+            self._chercheurChemin.arreter()
             self._chercheurChemin = None
-
         self._chercheurChemin = AEtoile.Chemin(self.plateau, self.coordActeur(), self._coordCible)
         self._chemin = self._chercheurChemin.liste()
-        self.afficherCibles(True)    
+        self.afficherCibles(True)        
 
     def afficherCibles(self, actif):
         for coord in self._chemin:

+ 10 - 8
lib/Case.py

@@ -93,12 +93,12 @@ class Case(QGraphicsPolygonItem):
         self.setZValue(0)
         self.setFiltersChildEvents(True)
 
-        #pour afficher les coordonnees des cases:        
-        #text = QGraphicsSimpleTextItem("{}-{}".format(self.x,self.y), parent=self)
-        #if self.plateau.formeCases == "H":
-        #    text.setPos(QPointF(((self.x*0.866)+0.2886)*self.plateau.hCase,  self.y*self.plateau.hCase))
-        #else:
-        #    text.setPos(QPointF(self.x*self.plateau.hCase,  self.y*self.plateau.hCase))
+##        #pour afficher les coordonnees des cases:        
+##        text = QGraphicsSimpleTextItem("{}-{}".format(self.x,self.y), parent=self)
+##        if self.plateau.formeCases == "H":
+##            text.setPos(QPointF(((self.x*0.866)+0.2886)*self.plateau.hCase,  self.y*self.plateau.hCase))
+##        else:
+##            text.setPos(QPointF(self.x*self.plateau.hCase,  self.y*self.plateau.hCase))
         
         #polygone utilise lorsque dans champ de deplacement 
         self.polygoneChampDep = QGraphicsPolygonItem(self.polygone(self.x, self.y), parent=self)
@@ -151,7 +151,6 @@ class Case(QGraphicsPolygonItem):
             #si x est impair sur un plateau a cases hexagonales, le y est augmente de 0.5
             if 1 == (x % 2):
                 y += 0.5
-                
             polygone  << QPointF(((x*0.866)+0.2886)*self.plateau.hCase,  y*self.plateau.hCase) \
                       << QPointF(((x*0.866)+0.866)*self.plateau.hCase,   y*self.plateau.hCase) \
                       << QPointF(((x*0.866)+1.1547)*self.plateau.hCase, (y+0.5)*self.plateau.hCase) \
@@ -170,7 +169,10 @@ class Case(QGraphicsPolygonItem):
            seulement cases existantes sur le plateau / seulement cases adjacentes (cas des cases carrees)"""
         voisins = []
         if self.plateau.formeCases == "H":
-            lst = [(x, y-1), (x+1, y-1), (x+1, y), (x,  y+1), (x-1, y), (x-1, y-1)]
+            if 1 == (x % 2):
+                lst = [(x, y-1), (x+1, y), (x+1, y+1), (x,  y+1), (x-1, y+1), (x-1, y)]
+            else:
+                lst = [(x, y-1), (x+1, y-1), (x+1, y), (x,  y+1), (x-1, y), (x-1, y-1)]
         else:
             lst = [(x, y-1), (x+1, y-1), (x+1, y), (x+1, y+1), (x,   y+1), (x-1, y+1), (x-1, y), (x-1, y-1)]
                   

+ 6 - 4
lib/EcranEditionTerrain.py

@@ -52,10 +52,11 @@ class EcranEditionTerrain(QDialog):
 ##            self.ui.visibiliteTerrain.setCheckState(2)
 ##        else:
 ##            self.ui.visibiliteTerrain.setCheckState(0)
+        self.ui.et_depAucun.setChecked(self.terrain.franchissable)
 ##        if self.terrain.franchissable:    
-##            self.ui.franchissableTerrain.setCheckState(2)
+##            self.ui.et_depAucun.setCheckState(2)
 ##        else:
-##            self.ui.franchissableTerrain.setCheckState(0)
+##            self.ui.et_depAucun.setCheckState(0)
         self.ui.et_supprimer.setEnabled(True)
 
     def majAffichage(self, txt):
@@ -100,10 +101,11 @@ class EcranEditionTerrain(QDialog):
            
     def enregistrer(self):
         """enregistre le terrain cree/edite"""
-        self.terrain.id = self.nouvelIdTerrain()
+        if not self.terrain.id:
+            self.terrain.id = self.nouvelIdTerrain()
         self.terrain.nom = str(self.ui.et_nom.text().toUtf8())
         self.terrain.imgTexture = self.nomImg
-##        self.terrain.franchissable = bool(self.ui.franchissableTerrain.checkState())
+        self.terrain.franchissable = (not self.ui.et_depAucun.isChecked())
         enregistrer(self.terrain.id, self.terrain, "lib\\biblio\\terrain")
         self.terrain = None
         self.done(1)

+ 7 - 2
lib/Modes.py

@@ -191,6 +191,7 @@ class MajCases(ModeBaseCp):
         if self.plateau.pinceau.estActif():
             for coord in self.plateau.pinceau.selection():
                 if self._param.__class__.__name__ == "Terrain":
+                    print self._param.franchissable
                     self.plateau.cases[coord].majTerrain(self._param)
                 elif self._param.__class__.__name__ == "QColor":
                     if self._param.isValid():
@@ -463,8 +464,12 @@ class PionSelectionne(ModeBasePi):
         else:
             super(PionSelectionne, self).clicDroit(event)
 
-
-
+    def toucheClavier(self, event):
+        if self._num > 0:
+            if event.key() == Qt.Key_Right:
+                self._action.pivoter(1)
+            elif event.key() == Qt.Key_Left:
+                self._action.pivoter(-1)
 
 
 

+ 0 - 1
lib/Pion.py

@@ -109,7 +109,6 @@ class Pion(QGraphicsItem):
         self.polygoneGraphique.setParentItem(self)
         self.polygoneGraphique.setPos(QPointF(0,0))
         if self.plateau.formeCases == "H":
-            
             self.polygoneGraphique.setTransformOriginPoint(QPointF(2*0.2886*self.plateau.hCase, 0.5*self.plateau.hCase))
         else:
             self.polygoneGraphique.setTransformOriginPoint(QPointF(0.5*self.plateau.hCase,0.5*self.plateau.hCase))

+ 8 - 10
lib/Plateau.py

@@ -1225,7 +1225,7 @@ class Plateau(QGraphicsScene):
             #on parcourt les faces des polygones des cases, et on ne garde que ceux qui n'ont pas de case 'en face'
             for coord in listeCases:
                 polygone = case.polygone(coord[0], coord[1])
-                voisins =  self.lstCoordAdjacentes(coord[0], coord[1])
+                voisins = self.lstCoordAdjacentes(coord[0], coord[1])
                 
                 for i in range(0, len(voisins)):
                     if not voisins[i] in listeCases:
@@ -1262,12 +1262,15 @@ class Plateau(QGraphicsScene):
         return polygone  
 
     def lstCoordAdjacentes(self, x, y):
-        """renvoie la liste des coordonnees adjacentes, sans condition d'existence sur le plateau
+        """renvoie la liste des coordonnees adjacentes, !!!! sans condition d'existence sur le plateau !!!!
            attention: l'ordre est important"""
         if self.formeCases == "H":
-            voisins = [(x, y-1), (x+1, y-1), (x+1, y), (x,  y+1), (x-1, y), (x-1, y-1)]
+            if 1 == (x % 2):
+                voisins = [(x, y-1), (x+1, y), (x+1, y+1), (x,  y+1), (x-1, y+1), (x-1, y)]
+            else:
+                voisins = [(x, y-1), (x+1, y-1), (x+1, y), (x,  y+1), (x-1, y), (x-1, y-1)]
         else:
-            voisins = [(x, y-1), (x+1, y), (x,   y+1), (x-1, y)]
+            voisins = [(x, y-1), (x+1, y-1), (x+1, y), (x+1, y+1), (x,   y+1), (x-1, y+1), (x-1, y), (x-1, y-1)]
         return voisins                                        
 
     def coordCentreListeCases(self, listeCases):
@@ -1869,13 +1872,8 @@ class Plateau(QGraphicsScene):
             pion = self.pionDecorSelectionne()
         
         if pion != None:
-           if self.proj.deplacementValide():        
-               if self.modePrincipal == "combat":
-                   self.majInfosPion()
+           if self.proj.projectionValide():        
                pion.majPosition(self.proj.coord(), self.proj.nbRotations())
-               self.majModeCombat("aucun")
-           else:
-               print("Deplacement impossible!")
 
     def afficherChampDeplacement(self, actif):
         """cree et affiche ou efface et detruit le champ de deplacement du pion selectionne"""

+ 4 - 1
lib/ProjectionDep.py

@@ -66,8 +66,11 @@ class ProjectionDep():
                     ok += 1
                 else:
                     #si la case est occupee par le pion lui-meme
-                    if self.plateau.cases[coord].estOccupeePar(self.z()) == self._pion:
+                    if self.plateau.cases[coord].estOccupeePar(self.z()) == None:
                         ok += 1
+                    else:
+                        if self.plateau.cases[coord].estOccupeePar(self.z()) == self._pion:
+                            ok += 1
         valide = (ok == compte and compte > 0)
         return valide        
 

+ 1 - 1
lib/Terrain.py

@@ -7,7 +7,7 @@ from PyQt4.QtGui import QColor
 class Terrain():
     """terrain a affecter a une case"""
     def __init__(self, parent=None):
-        self.id = "00"
+        self.id = None
         self.nom = ""                #libelle a afficher dans la liste 
         self.couleur = QColor("")    #couleur si pas de texture
         self.imgTexture = ""         #image source de la texture

BIN
lib/biblio/combattant



BIN
lib/biblio/terrain


BIN
parties/Partie1/svg/1.p


BIN
parties/Partie1/svg/2.p


+ 5 - 2
parties/Partie1/svg/infos_sauvegarde

@@ -1,4 +1,7 @@
-€}qU0}q(Unomcsip
+€}q(U1}q(Unomcsip
 _unpickle_type
 qUPyQt4.QtCoreqU
-QByteArrayUwxc…‡RqUdateCreationGAÕ[:š-UdateSvgGAÕ[Qu/UchapitreU1UenCours‰Upublic‰us.
+QByteArrayUrty…‡RqUdateCreationGAÕ[oËa‰7UdateSvgGAÕ[oÏ¥VUchapitreU1UenCours‰Upublic‰uU0}q(UnomhhU
+QByteArrayUwxc…‡RqUdateCreationGAÕ[:š-UdateSvgGAÕ[Qu/UchapitreU1UenCours‰Upublic‰uU2}q(Unomq	hhU
+QByteArrayUert…‡Rq
+UdateCreationqGAÕ[s‚c…UdateSvgqGAÕ[sƒí¸Uchapitreq
U1UenCoursq‰Upublicq‰uu.