123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508 |
- from Outils.Moteur_de_jeu.Pathfinding import *
- from Outils.Moteur_de_jeu.Barriere import *
- from Outils.Moteur_de_jeu.Coup import *
- def suppr (t, a) : #Elric et Baptiste 09/2016
- """ On supprime tout les elements valant a dans le tableau t """
- for i in t :
- if i == a :
- t.remove(i)
- """
- Conventions :
- - Les coordonnées vont de 0 à lg - 1 horizontalement et ht - 1 verticalement
- - L'origine des axes est en haut à gauche
- - Le barycentre d'une barrière est reperé par les coordonnées de la case en haut à gauche
- --- ---
- |ici| |
- ---B--- B = milieu de la barrière
- | | |
- --- ---
-
- - Le joueur 0 commence sur la ligne 0, le joueur 1 sur la ligne ht - 1
- - D'accord ici
- """
- class Plateau : # Jovian : 18 octobre 2016
- """
- On dispose des méthodes suivantes :
- .copie(self)
- .joueur_sur_case(self, num, x, y)
- .cases_voisines(self, x, y)
- .cases_accessibles(self, x, y)
- .cases_accessibles_depuis(self, x, y, num)
- .cases_accessibles_joueur(self, num)
- .point_libre(plateau, x, y)
- .point_barrieres_possibles(self, x, y)
- .rangee_desiree(self, num)
- .barriere_possible(self, barriere)
- .liste_barrieres_possibles(plateau, num)
- .liste_coups_possibles(self, num)
- .executer_coup(self, coup, num)
- .gagnant(self)
- .longueur_chemin(self, num)
- .barrieres_adjacentes
- .pions_voisins
- .bord_adjacent
- .contact (self,num)
- """
-
- def __init__(self, lg, ht, nombre_barrieres) : # Quentin 06/10/2016
- self.pions = [[(lg-1)//2, 0], [(lg-1)//2, ht - 1]]
- self.barrieres_restantes = [nombre_barrieres, nombre_barrieres]
- self.liste_barrieres = []
- self.lg = lg
- self.ht = ht
- self.tour = 0 # Joueur dont c'est le tour
- def copie(self) : #Quentin 06/10/2016
- """ Retourne un nouveau plateau, copie de celui passé en paramètre. """
- nouveau = Plateau(self.lg, self.ht, 0)
- nouveau.pions = [list(self.pions[0]),list(self.pions[1])]
- nouveau.barrieres_restantes = list(self.barrieres_restantes)
- nouveau.liste_barrieres = list(self.liste_barrieres)
- nouveau.tour = self.tour
- return nouveau
- def copie_complete(self) :
- """ Copie également les barrières """
- nouveau = Plateau(self.lg, self.ht, 0)
- nouveau.pions = [list(self.pions[0]),list(self.pions[1])]
- nouveau.barrieres_restantes = list(self.barrieres_restantes)
- for b in self.liste_barrieres :
- nouveau.liste_barrieres.append(b.copie())
-
- nouveau.tour = self.tour
- return nouveau
-
- def joueur_sur_case(self, num, x, y) : #Elric et Baptiste 10/2016
- """ Retourne True si le joueur num est sur la case (x,y) """
- return self.pions[num] == [x,y]
- def cases_accessibles_depuis(self, x0, y0, num) : #Elric et Baptiste, 11/10
- """Cases accessibles depuis la case (x0, y0) par le joueur num s'il était placé sur cette case. Prend en compte la possibilité de saut et les barrières."""
- liste = cases_accessibles(self, x0, y0)
- for c in liste :
- (x, y) = c
- if self.joueur_sur_case(1-num, x, y) :#Si l'adversaire est présent sur une case voisine,
- suppr(liste,c)
- liste2 = cases_accessibles(self, x, y)
- for i in liste2 :
- liste.append(i)
-
- suppr(liste,(x0,y0))
- return liste
-
- def cases_accessibles_joueur(self, num) : #Quentin 06/10/2016
- """ Cases accessibles par le joueur num depuis la case où il est réellement placé """
- return self.cases_accessibles_depuis(self.pions[num][0], self.pions[num][1], num)
-
- def point_libre(self, x, y) : #Elric et Baptiste 09/2016
- """
- Retourne une chaîne de caractères correspondant aux barrières pouvant être placées en (x, y)
- "" : aucune
- "h" : horizontale
- "v" : verticale
- "vh" : les deux
- """
- b = self.liste_barrieres
- t = ["v", "h"]
- for bar in b :
- if bar.x == x-1 and bar.y == y and bar.orientation == "h" :
- suppr (t, "h")
- elif bar.x == x+1 and bar.y == y and bar.orientation == "h" :
- suppr (t, "h")
- elif bar.x == x and bar.y == y-1 and bar.orientation == "v" :
- suppr (t, "v")
- if bar.x == x and bar.y == y+1 and bar.orientation == "v" :
- suppr (t, "v")
- elif bar.x == x and bar.y == y :
- t = []
- while len(t) < 2 :
- t.append(" ")
- return(t[0] + t[1])
- def pourri_chemin (self , t ) :
- """
- prend un plateau et un chemin en entrée
- retourne la liste des barrières permettant de pourrir le chemin entré
- """
- n = len(t)
- tab = []
- for k in range (n - 1) :
- x1 = t[k][0]
- x2 = t[k+1][0]
- y1 = t[k][1]
- y2 = t[k+1][1]
-
- if x1 == x2 :
- if y1 == y2 + 1 :
- tab.append ( Barriere("h", x1, y2) )
- tab.append (Barriere("h", x1 - 1, y2) )
- else:
- tab.append ( Barriere("h", x1, y1) )
- tab.append ( Barriere("h", x1 - 1, y1) )
- else :
- if x1 == x2 + 1 :
- tab.append ( Barriere("v", x1 - 1, y1 - 1) )
- tab.append ( Barriere("v", x1 - 1, y1) )
- else :
- tab.append ( Barriere("v", x1, y1 ) )
- tab.append ( Barriere("v", x1, y1 - 1) )
- return tab
-
- def point_barrieres_possibles(self, x, y) : #Elric et Baptiste 09/2016
- """Retourne la liste des barrières pouvant être placées en (x, y)"""
- p = self.point_libre(x, y)
- if " " == p :
- return []
- elif p == "h " :
- return [Barriere("h", x, y)]
- elif p == "v " :
- return [Barriere("v", x, y)]
- else :
- return [Barriere("h", x, y), Barriere("v", x, y)]
-
- def rangee_desiree(self, num) : #Quentin 04/10/2016
- """ Retourne la rangée que doit atteindre le joueur num """
- return (self.ht - 1)*(1 - num)
-
- def barriere_possible (self, barriere) : # Jovian 18/10/16 : optimisation
- """
- Permet de savoir si une barrière peut être placée sans isoler un pion du bord qu'il cherche à atteindre.
- Argument self : le plateau qui lance la méthode.
- Argument barriere : objet barrière supposée posable sans collision.
- Retour : un booléen qui retourne True si la barrière est valide.
- """
- # Si la barrière a moins de deux contacts, elle ne peut pas fermer de contour. Il n'est donc pas nécessaire de la vérifier.
- if self.nombre_contacts(barriere) < 2 :
- return True
- # Mise en place de la barrière pour l'expérience
- self.liste_barrieres.append( barriere )
- # Pathfinding joueur A
- joueurA = self.pions[0]
- trajetA = path_finding( self, joueurA[0], joueurA[1], self.rangee_desiree(0) )
- if trajetA == [] :
- # Arrivée non joignable dans ce cas
- self.liste_barrieres.pop()
- return False
- # Pathfinding joueur B
- joueurB = self.pions[1]
- trajetB = path_finding( self, joueurB[0], joueurB[1], self.rangee_desiree(1) )
- if trajetB == [] :
- # Arrivée non joignable dans ce cas
- self.liste_barrieres.pop()
- return False
- # L'arrivée est joignable
- self.liste_barrieres.pop()
- return True
- ## def liste_barrieres_possibles (self) : #Elric et Baptiste 04/10/2016 #accélération Elric 25/11
- ## """
- ## Retourne la liste de toutes les barrières pouvant être placées ce tour-ci en tenant compte de toutes les contraintes existantes.
- ## """
- ##
- ## if self.barrieres_restantes[self.tour] == 0 :
- ## return []
- ## tab = []
- ##
- ## for y in range (self.ht - 1) :
- ## for x in range (self.lg - 1) :
- ## bar = self.point_barrieres_possibles (x, y)
- ## for i in bar :
- ## if self.barriere_possible (i) :
- ## tab.append(i)
- ##
- ##
- ## """joueurA = self.pions[0]
- ## trajetA = path_finding( self, joueurA[0], joueurA[1], self.rangee_desiree(0) )
- ## t = self.pourri_chemin(trajetA)
- ## joueurB = self.pions[1]
- ## trajetB = path_finding( self, joueurB[0], joueurB[1], self.rangee_desiree(1) )
- ##
- ## t += self.pourri_chemin(trajetB)
- ##
- ## for i in t :
- ## if self.barriere_possible (i) :
- ## tab.append(i)"""
- ##
- ## return tab
- def liste_barrieres_possibles (self) : #Elric et Baptiste 04/10/2016 #accélération Elric 25/11
- """
- Retourne la liste de toutes les barrières pouvant être placées ce tour-ci en tenant compte de toutes les contraintes existantes.
- """
-
- if self.barrieres_restantes[self.tour] == 0 :
- return []
- tab = []
- joueurA = self.pions[0]
- trajetA = path_finding( self, joueurA[0], joueurA[1], self.rangee_desiree(0) )
- t = self.pourri_chemin(trajetA)
- joueurB = self.pions[1]
- trajetB = path_finding( self, joueurB[0], joueurB[1], self.rangee_desiree(1) )
- t += self.pourri_chemin(trajetB)
- for x in range ( self.lg -1):
- for y in range (self.ht -1) :
- bar = self.point_barrieres_possibles( x, y)
- for i in bar :
- if i in t :
- if self.barriere_possible (i) :
- tab.append(i)
- else :
- tab.append(i)
- return tab
- def liste_coups_possibles(self) :
- """
- Liste des coups possibles à disposition du joueur actuel
- """
- t = []
- mouvements = self.cases_accessibles_joueur(self.tour)
- barrieres = self.liste_barrieres_possibles()
- #On met les mouvements
- for m in mouvements :
- t.append(Coup("M",case = m))
- # On met les barrières
- for b in barrieres :
- t.append(Coup("B",barriere = b))
- return t
-
- def executer_coup(self, coup) : #Quentin 06/10/2016
- """ Exécute un coup de la part du joueur dont c'est le tour"""
-
- if coup.type == "M" :
- self.pions[self.tour][0] = coup.case[0]
- self.pions[self.tour][1] = coup.case[1]
- else :
- self.liste_barrieres.append(coup.barriere)
- self.barrieres_restantes[self.tour] -= 1
- self.tour = 1 - self.tour
- def gagnant(self) :
- """
- Détermine si un plateau correpsond à une partie terminée. Retourne :
- > -1 si la partie est toujours en cours
- > le numéro du gagannt sinon
- """
- if self.pions[0][1] == self.rangee_desiree(0) :
- return 0
- elif self.pions[1][1] == self.rangee_desiree(1) :
- return 1
- else :
- return -1
- def chemin(self,num) :
- return path_finding(self, self.pions[num][0], self.pions[num][1], self.rangee_desiree(num))
-
- def longueur_chemin(self, num) : # Quentin 08/11/2016
- """ Retourne la longueur du chemin le plus court entre un joueur et le bord recherché """
- return len( path_finding(self, self.pions[num][0], self.pions[num][1], self.rangee_desiree(num)) ) - 1
-
-
- def bord_adjacent (self, bar) : # Elric, 09/11/2016
- """
- Prend un barrière en entrée, et retourne le tableau contenant les bords la touchant
- RETOURNE un tableau de booléens
- """
- if bar.orientation == "h" :
- return [bar.x == 0, False, bar.x == self.lg - 2]
- else :
- return [bar.y == 0, False, bar.y == self.ht - 2]
- def pions_voisins(self, bar) : # Elric, 19/11/2016
- """
- Prend une barrière en entrée, donne s'il y a un pion qui colle la barrière ou pas.
- RETOURNE un booléen
- """
- position1 = self.pions[0]
- position2 = self.pions[1]
- t = [[bar.x,bar.y] , [bar.x + 1 , bar.y + 1] ,
- [bar.x , bar.y + 1 ] , [bar.x +1, bar.y ]]
- return ( position1 in t or position2 in t )
- def barrieres_adjacentes(self, bar) :
- """
- Prend une barrière en entrée, et retourne le tableau contenant les barrières la touchant
- """
- if bar.orientation == "h" :
- b1 = Barriere ("v", bar.x, bar.y + 1)
- b2 = Barriere ("v", bar.x - 1, bar.y + 1)
- b3 = Barriere ("v", bar.x + 1, bar.y + 1)
- b4 = Barriere ("v", bar.x, bar.y - 1)
- b5 = Barriere ("v", bar.x + 1, bar.y - 1)
- b6 = Barriere ("v", bar.x - 1, bar.y - 1)
- b7 = Barriere ("h", bar.x - 2, bar.y)
- b8 = Barriere ("h", bar.x + 2, bar.y)
- b9 = Barriere ("v", bar.x - 1, bar.y)
- b10 = Barriere ("v", bar.x + 1, bar.y)
- t = [b1, b2, b3, b4, b5, b6, b7, b8, b9, b10 ]
- res = []
- for a in self.liste_barrieres :
- if a in t :
- res.append(a)
- else :
- b1 = Barriere ("v", bar.x, bar.y + 2)
- b2 = Barriere ("v", bar.x, bar.y - 2)
- b3 = Barriere ("h", bar.x + 1, bar.y + 1)
- b4 = Barriere ("h", bar.x + 1, bar.y - 1)
- b5 = Barriere ("h", bar.x + 1, bar.y)
- b6 = Barriere ("h", bar.x - 1, bar.y - 1)
- b7 = Barriere ("h", bar.x - 1, bar.y)
- b8 = Barriere ("h", bar.x - 1, bar.y + 1)
- b9 = Barriere ("h", bar.x , bar.y - 1)
- b10 = Barriere ("h", bar.x , bar.y + 1)
- res = []
- t = [b1, b2, b3, b4, b5, b6, b7, b8, b9, b10 ]
- for a in self.liste_barrieres :
- if a in t :
- res.append(a)
- return res
- def barrieres_adjacentes_precis(self, b0) : # Quentin 15/11/2016
- """
- b0 est une barrière, qui peut être vue comme un triplet de trois noeuds.
- Cette fonction retourne la liste des barrières et des bords (représentés par des None) qui touchent chaque noeud, sous forme d'un tableau de tableaux.
- Le sens de lecture est de gauche à droite si b0 est horizontale, et de haut en bas si b0 est verticale.
- """
- tab_final = [[],[],[]]
- if b0.orientation == "h" :
- tab_potentiel = [[Barriere ("v", b0.x - 1, b0.y - 1), Barriere ("v", b0.x - 1, b0.y), Barriere ("v", b0.x - 1, b0.y + 1), Barriere ("h", b0.x - 2, b0.y)],
- [Barriere ("v", b0.x, b0.y - 1), Barriere ("v", b0.x, b0.y + 1)],
- [Barriere ("v", b0.x + 1, b0.y - 1), Barriere ("v", b0.x + 1, b0.y), Barriere ("v", b0.x + 1, b0.y + 1), Barriere ("h", b0.x + 2, b0.y)]]
- if b0.x == 0 :
- tab_final[0].append(None)
- if b0.x == self.lg - 2 :
- tab_final[2].append(None)
-
- else :
- tab_potentiel = [[Barriere ("h", b0.x - 1, b0.y - 1), Barriere ("h", b0.x, b0.y - 1), Barriere ("h", b0.x + 1, b0.y - 1), Barriere ("v", b0.x, b0.y - 2)],
- [Barriere ("h", b0.x - 1, b0.y), Barriere ("h", b0.x + 1, b0.y)],
- [Barriere ("h", b0.x - 1, b0.y + 1), Barriere ("h", b0.x, b0.y + 1), Barriere ("h", b0.x + 1, b0.y + 1), Barriere ("v", b0.x, b0.y + 2)]]
- if b0.y == 0 :
- tab_final[0].append(None)
- if b0.y == self.ht - 2 :
- tab_final[2].append(None)
- for b in self.liste_barrieres :
- for i in range(3) :
- if b in tab_potentiel[i] :
- tab_final[i].append(b)
- return tab_final
- def nombre_contacts(self, b) :
- """ Retourne le nombre de noeuds de la barrière b ayant un contact avec une barrière du plateau """
- tab = self.barrieres_adjacentes_precis(b)
- nb = 0
- for i in range(3) :
- if tab[i] != [] :
- nb += 1
- return nb
- def contact (self, x, y) :#Elric, 25/11
- """
- Si une barrière touche le pion num. C'est un booléen
- """
- for i in self.liste_barrieres :
- if (i.x == x and i.y == y ) or (i.x == x-1 and i.y == y ) or (i.x == x and i.y == y-1 ) or (i.x == x-1 and i.y == y-1 ) :
- return True
- return False
-
-
-
|