diff --git a/S1/Echecs/guiTk.py b/S1/Echecs/guiTk.py index ca97ea9..f126d73 100644 --- a/S1/Echecs/guiTk.py +++ b/S1/Echecs/guiTk.py @@ -1,42 +1,51 @@ from tkinter import * from logique import LogiqueEchecs + class PlateauTk: + """ Plateau de jeu de damier en canvas Tk """ - RATIO_PCE_CASE = .95 # Place que prend la pièce sur la case - TEMPS_ANIM = 200 # Temps en ms d'une animation - INTER_ANIM = 10 # Temps en ms entre deux actualisations d'animation + RATIO_PCE_CASE = .95 # Place que prend la pièce sur la case + TEMPS_ANIM = 200 # Temps en ms d'une animation + INTER_ANIM = 10 # Temps en ms entre deux actualisations d'animation - COTE_TOUT_DEFAUT = 500 # Coté par défaut du plateau + COTE_TOUT_DEFAUT = 500 # Coté par défaut du plateau def __init__(self, fen, can, statut, logique): """ Constructeur de PlateauTk """ - self.can = can # Canvas - self.fen = fen # Fenêtre Tk (nécessaire pour lancer un timeout pour l'animation) - self.statut = statut # Fonction qui envoie un message à l'utilisateur - self.grilleDamier = [] # Tableau contenant les références aux cases du damier - self.grillePieces = [] # Tableau contenant les références aux pièces - self.photos = [] # Liste contenant les différentes photos utilisées (afin qu'elles ne soient pas recyclées) - self.imagesOriginales = {} # Dictionnaire associant chaque pièce à son image originale - self.imagesRedim = {} # Dictionnaire associant chaque pièce à son image redimensionnée - self.animations = [] # Liste contenant les animations en cours + self.can = can # Canvas + # Fenêtre Tk (nécessaire pour lancer un timeout pour l'animation) + self.fen = fen + self.statut = statut # Fonction qui envoie un message à l'utilisateur + # Tableau contenant les références aux cases du damier + self.grilleDamier = [] + self.grillePieces = [] # Tableau contenant les références aux pièces + self.photos = [] # Liste contenant les différentes photos utilisées + # (afin qu'elles ne soient pas recyclées) + # Dictionnaire associant chaque pièce à son image originale + self.imagesOriginales = {} + # Dictionnaire associant chaque pièce à son image redimensionnée + self.imagesRedim = {} + self.animations = [] # Liste contenant les animations en cours - self.dEtape = True # Étape du déplacement (True : prendre la pièce, False : poser la pièce) - self.dx1 = -1 # Coordonnées X de la pièce sélectionnée - self.dy1 = -1 # Coordonnées Y de la pièce sélectionnée - self.dx2 = -1 # Coordonnées X de la destination - self.dy2 = -1 # Coordonnées Y de la destination - self.mvtsPossibles = [] # Liste des mouvements possibles pour la pièce sélectionnée - self.coteCase = 0 # Coté d'une case + # Étape du déplacement (True : prendre la pièce, False : poser la + # pièce) + self.dEtape = True + self.dx1 = -1 # Coordonnées X de la pièce sélectionnée + self.dy1 = -1 # Coordonnées Y de la pièce sélectionnée + self.dx2 = -1 # Coordonnées X de la destination + self.dy2 = -1 # Coordonnées Y de la destination + # Liste des mouvements possibles pour la pièce sélectionnée + self.mvtsPossibles = [] + self.coteCase = 0 # Coté d'une case - self.logique = logique # Logique du jeu - + self.logique = logique # Logique du jeu self.importerImages() self.redimCan(self.COTE_TOUT_DEFAUT) @@ -59,33 +68,34 @@ class PlateauTk: self.cGrille() self.remplirGrille() - - def nomPiece(self, piece): + def nomPiece(self, tPiece): """ Renvoi le nom de fichier de la pièce donnée """ - tPiece = self.logique.tPiece(piece) if tPiece == self.logique.PCE_PION: - return 'pion' + nom = 'pion' elif tPiece == self.logique.PCE_TOUR: - return 'tour' + nom = 'tour' elif tPiece == self.logique.PCE_CAVALIER: - return 'cavalier' + nom = 'cavalier' elif tPiece == self.logique.PCE_FOU: - return 'fou' + nom = 'fou' elif tPiece == self.logique.PCE_DAME: - return 'dame' + nom = 'dame' elif tPiece == self.logique.PCE_ROI: - return 'roi' + nom = 'roi' else: return False + return nom - def importerImage(self, piece, couleur): # TODO piece stocke déjà la couleur + # TODO piece stocke déjà la couleur + def importerImage(self, piece, couleur): """ Importe l'image de la pièce donnée """ - nom = 'sprites/'+self.nomPiece(piece)+couleur+'.gif' - self.imagesOriginales.update({piece:PhotoImage(file=nom)}) + nom = 'sprites/' + \ + self.nomPiece(self.logique.tPiece(piece)) + couleur + '.gif' + self.imagesOriginales.update({piece: PhotoImage(file=nom)}) def importerImages(self): """ @@ -100,13 +110,15 @@ class PlateauTk: """ Redimensionne l'image de la pièce donnée """ - self.imagesRedim.update({piece:self.imagesOriginales[piece].subsample(sample)}) + self.imagesRedim.update( + {piece: self.imagesOriginales[piece].subsample(sample)}) def redimImages(self): """ Redimensionne l'image des pièces du jeu """ - sample = int(504 // (self.coteCase * self.RATIO_PCE_CASE)) # TODO S'en sort pour être toujours plus grand + sample = int(504 // (self.coteCase * self.RATIO_PCE_CASE) + ) # TODO S'en sort pour être toujours plus grand for piece in self.logique.BLANCS: self.redimImage(piece, sample) for piece in self.logique.NOIRS: @@ -118,28 +130,29 @@ class PlateauTk: """ Retourne la couleur hexadécimale de la case de couleur et de contexte donnée """ - if contexte == 1: # Sélectionné + if contexte == 1: # Sélectionné return '#a0cefe' if blanc else '#478bd1' - elif contexte == 2: # Possible / Victoire + elif contexte == 2: # Possible / Victoire return '#bafea0' if blanc else '#6ed147' - elif contexte == 3: # Impossible / Défaite + elif contexte == 3: # Impossible / Défaite return '#fea0ab' if blanc else '#d14758' - else: # Normal + else: # Normal return '#ffce9e' if blanc else '#d18b47' def cCase(self, x, y): """ Crée la case aux coordonnées données """ - couleur = self.caseCouleur(self.logique.eCaseBlanche(x, y), 0) - return self.can.create_rectangle(x * self.coteCase, y * self.coteCase, (x + 1) * self.coteCase, (y + 1) * self.coteCase) + return self.can.create_rectangle(x * self.coteCase, y * self.coteCase, + (x + 1) * self.coteCase, (y + 1) * self.coteCase) def coulCase(self, x, y, contexte=0): """ Colorie la case aux coordonnées données selon le contexte donné """ couleur = self.caseCouleur(self.logique.eCaseBlanche(x, y), contexte) - self.can.itemconfig(self.grilleDamier[x][y], fill=couleur, outline=couleur) + self.can.itemconfig( + self.grilleDamier[x][y], fill=couleur, outline=couleur) def coulDamier(self, contexte=0): """ @@ -154,7 +167,7 @@ class PlateauTk: Génère le damier """ self.grilleDamier = [] - for x in range(0, self.logique.CASES_COTE): # TODO Peut être amélioré + for x in range(0, self.logique.CASES_COTE): # TODO Peut être amélioré colonne = [] for y in range(0, self.logique.CASES_COTE): colonne.append(self.cCase(x, y)) @@ -166,7 +179,8 @@ class PlateauTk: Crée la pièce aux coordonnées données """ if self.logique.ePiece(piece): - self.grillePieces[x][y] = self.can.create_image((x + .5) * self.coteCase, (y + .5) * self.coteCase, image=self.imagesRedim[piece]) + self.grillePieces[x][y] = self.can.create_image((x + .5) * self.coteCase, + (y + .5) * self.coteCase, image=self.imagesRedim[piece]) else: self.grillePieces[x][y] = False @@ -208,7 +222,8 @@ class PlateauTk: """ Change le statut indiquant au joueur en cours de jouer. """ - self.statut('Aux ' + self.nomJoueur(self.logique.joueur, pluriel=True) + ' de sélectionner une pièce.') + self.statut('Aux ' + self.nomJoueur(self.logique.joueur, pluriel=True) + + ' de sélectionner une pièce.') @staticmethod def animationDCoords(i): @@ -216,8 +231,8 @@ class PlateauTk: Retourne les coordonnées auxquelles doit se placer une pièce en cours d'animation """ # TODO Faire autre chose qu'une animation linéaire constante - x = i['x1'] + (i['x2']-i['x1']) * (i['avancement']/i['total']) - y = i['y1'] + (i['y2']-i['y1']) * (i['avancement']/i['total']) + x = i['x1'] + (i['x2'] - i['x1']) * (i['avancement'] / i['total']) + y = i['y1'] + (i['y2'] - i['y1']) * (i['avancement'] / i['total']) return [x, y] def animation(self): @@ -245,7 +260,8 @@ class PlateauTk: self.coulCase(i['x'], i['y'], 0) self.animations = animationsNv if len(animationsNv): # Si il y aura encore des animations à faire - self.fen.after(self.INTER_ANIM, self.animation) # On prévoit une image (boucle) + # On prévoit une image (boucle) + self.fen.after(self.INTER_ANIM, self.animation) def animer(self, animation): """ @@ -264,9 +280,10 @@ class PlateauTk: if len(self.animations): for i in self.animations: if i['type'] == 'd' and i['piece'] == piece: - # Si une animation pour cette pièce existe déjà, on la reprend et on la modifie + # Si une animation pour cette pièce existe déjà, on la + # reprend et on la modifie coords = self.animationDCoords(i) - i['x1'] = coords[0] # TODO Simplifier avec update() + i['x1'] = coords[0] # TODO Simplifier avec update() i['y1'] = coords[1] i['x2'] = x2 i['y2'] = y2 @@ -285,7 +302,7 @@ class PlateauTk: 'total': self.TEMPS_ANIM, 'avancement': 0 } - self.can.tag_raise(piece) # Mise au premier plan + self.can.tag_raise(piece) # Mise au premier plan self.animer(animation) def animerF(self, piece): @@ -300,7 +317,7 @@ class PlateauTk: } self.animer(animation) - def animerC(self, x ,y): + def animerC(self, x, y): """ Ajoute une animation pour l'effacement de la surbrillance d'une case """ @@ -317,12 +334,13 @@ class PlateauTk: """ Indique à l'utilisateur la victoire et décore le plateau pour l'occasion """ - self.statut('Victoire des ' + self.nomJoueur(self.logique.victorieux) + ' !') + self.statut( + 'Victoire des ' + self.nomJoueur(self.logique.victorieux) + ' !') self.coulDamier() for x in range(0, self.logique.CASES_COTE): for y in range(0, self.logique.CASES_COTE): piece = self.logique.grille[x][y] - if self.logique.ePiece(piece): + if self.logique.ePiece(piece): if self.logique.ePieceNoir(piece) ^ self.logique.victorieux: self.coulCase(x, y, 2) else: @@ -334,16 +352,16 @@ class PlateauTk: (Vérifie la possibilité du mouvement et crée les animations nécessaires) """ test = self.logique.dPiece(x1, y1, x2, y2) - if test['valide'] == True: # Si déplacement possible + if test['valide'] == True: # Si déplacement possible for s in test['supprimer']: self.animerF(self.grillePieces[s[0]][s[1]]) for d in test['deplacer']: self.grillePieces[d[2]][d[3]], self.grillePieces[d[0]][d[1]] = \ - self.grillePieces[d[0]][d[1]], False - self.animerD((d[0] + .5) * self.coteCase, (d[1] + .5) * self.coteCase, \ - (d[2] + .5) * self.coteCase, (d[3] + .5) * self.coteCase, \ - self.grillePieces[d[2]][d[3]]) - + self.grillePieces[d[0]][d[1]], False + self.animerD((d[0] + .5) * self.coteCase, (d[1] + .5) * self.coteCase, + (d[2] + .5) * + self.coteCase, (d[3] + .5) * self.coteCase, + self.grillePieces[d[2]][d[3]]) else: self.statut('Déplacment invalide ! (' + test['message'] + ')') return test['valide'] @@ -353,29 +371,34 @@ class PlateauTk: Réagit en fonction d'un clic sur une case aux coordonnées données """ if not self.logique.partieFinie: - if self.dEtape: # Prendre + if self.dEtape: # Prendre self.dx1, self.dy1 = x, y - self.coulDamier() # Effacement des surbrillances - if self.logique.aSonTour(self.logique.grille[self.dx1][self.dy1]): # Si possible jouer - self.coulCase(self.dx1, self.dy1, 1) - self.mvtPossibleSansEchecs = self.logique.mvtsPossibles(self.dx1, self.dy1) # Surbrillance bleue - for i in self.mvtPossibleSansEchecs: # Surbrillances vertes + self.coulDamier() # Effacement des surbrillances + # Si peut jouer + if self.logique.aSonTour(self.logique.grille[self.dx1][self.dy1]): + self.coulCase(self.dx1, self.dy1, 1) + self.mvtsPossibles = \ + self.logique.mvtsPossibles( + self.dx1, self.dy1) # Surbrillance bleue + for i in self.mvtsPossibles: # Surbrillances vertes self.coulCase(i[0], i[1], 2) self.statut('Cliquez où déposer la pièce.') self.dEtape = not self.dEtape - else: # Si pas possible de jouer + else: # Si ne peut jouer self.coulCase(self.dx1, self.dy1, 3) self.animerC(self.dx1, self.dy1) - else: # Poser + else: # Poser self.dx2, self.dy2 = x, y - if self.dPiece(self.dx1, self.dy1, self.dx2, self.dy2) or (self.dx1 == self.dx2 and self.dy1 == self.dy2): # Si déplacement fait / Annule dépalcement - self.coulDamier() # Effacer Surbrillance + if self.dPiece(self.dx1, self.dy1, self.dx2, self.dy2) or \ + (self.dx1 == self.dx2 and self.dy1 == self.dy2): + # Si déplacement fait / annulé + self.coulDamier() # Effacer Surbrillance self.dEtape = not self.dEtape if self.logique.partieFinie: self.victoire() else: self.statutPrendre() - else: # Si mauvais déplacement + else: # Si mauvais déplacement self.coulCase(self.dx2, self.dy2, 3) self.animerC(self.dx2, self.dy2) @@ -383,27 +406,29 @@ class PlateauTk: """ Réagit en fonction d'un clic """ - # if event.x in range(0, self.coteCase * self.logique.CASES_COTE) and event.y in range(0, self.coteCase * self.logique.CASES_COTE): + # if event.x in range(0, self.coteCase * self.logique.CASES_COTE) \ + # and event.y in range(0, self.coteCase * self.logique.CASES_COTE): self.dClic(event.x // self.coteCase, event.y // self.coteCase) class FenetreTk: + """ Fenêtre pour jouer à des jeux sur damier """ - PLACEHOLDER_DIMENSIONS = 300 # Coté du canvas vide du début + PLACEHOLDER_DIMENSIONS = 300 # Coté du canvas vide du début def __init__(self): """ Constructeur de FenetreTk """ - self.fen = None # Objet Fenêtre - self.can = None # Objet Canvas - self.chaine = None # Objet Label de statut + self.fen = None # Objet Fenêtre + self.can = None # Objet Canvas + self.chaine = None # Objet Label de statut - self.plateau = None # Plateau de jeu + self.plateau = None # Plateau de jeu self.creerFen() self.fen.mainloop() @@ -414,16 +439,19 @@ class FenetreTk: """ self.fen = Tk() self.fen.title("Jeu de plateau") - self.can = Canvas(self.fen, width=self.PLACEHOLDER_DIMENSIONS, height=self.PLACEHOLDER_DIMENSIONS, bg="ivory") + self.can = Canvas(self.fen, width=self.PLACEHOLDER_DIMENSIONS, + height=self.PLACEHOLDER_DIMENSIONS, bg="ivory") self.can.grid(row=0, column=1, columnspan=3) self.chaine = Label(self.fen, text="Bienvenue !") self.chaine.grid(row=2, column=2, padx=3, pady=3) - Button(self.fen, text="Nv. Partie", command=self.nvPartie).grid(row=2, column=1, padx=3, pady=3) - Button(self.fen, text="Quitter", command=self.fen.destroy).grid(row=2, column=3, padx=3, pady=3) + Button(self.fen, text="Nv. Partie", command=self.nvPartie)\ + .grid(row=2, column=1, padx=3, pady=3) + Button(self.fen, text="Quitter", command=self.fen.destroy)\ + .grid(row=2, column=3, padx=3, pady=3) def statut(self, texte, delai=0): """ - Change le message affiché. + Change le message affiché. """ self.chaine.config(text=texte) # TODO Messages permanents et messages temporaires @@ -435,4 +463,5 @@ class FenetreTk: Démarre une nouvelle partie. """ del self.plateau - self.plateau = PlateauTk(self.fen, self.can, self.statut, LogiqueEchecs()) + self.plateau = PlateauTk( + self.fen, self.can, self.statut, LogiqueEchecs()) diff --git a/S1/Echecs/logique.py b/S1/Echecs/logique.py index 77778ca..0d5b4b5 100644 --- a/S1/Echecs/logique.py +++ b/S1/Echecs/logique.py @@ -1,13 +1,34 @@ import copy + class Logique: + """ Logique des jeux sur damier + (Ne peut être utilisé seul) """ - PCE_VIDE = 0 # Valeur à mettre sur la grille quand il n'y a pas de pièce - BLANC = True # Valeur correspondant au joueur blanc - NOIR = False # Valeur correspondant au joueur noir + PCE_VIDE = 0 # Valeur à mettre sur la grille quand il n'y a pas de pièce + BLANC = True # Valeur correspondant au joueur blanc + NOIR = False # Valeur correspondant au joueur noir + + # Valeurs devant être remplies par une classe héritante + CASES_COTE = 0 # Cases de coté + + # Valeur à partir de laquelle sont comprises les pièces blanches + DECALAGE_BLANCS = 0 + # Valeur à partir de laquelle sont comprises les pièces noires + DECALAGE_NOIRS = 0 + + BLANCS = range(0) # Intervalle contenant les pièces blanches + NOIRS = range(0) # Intervalle contenant les pièces noires + + def __init__(self): + self.grille = [] # Grille de jeu + self.cGrille() + self.joueur = self.BLANC # Premier joueur + self.partieFinie = False + self.victorieux = None @staticmethod def eCaseBlanche(x, y): @@ -20,7 +41,7 @@ class Logique: """ Crée le tableau self.grille. """ - for x in range(self.CASES_COTE): # TODO Peut être amélioré + for x in range(self.CASES_COTE): # TODO Peut être amélioré colonne = [] for y in range(self.CASES_COTE): colonne.append(self.PCE_VIDE) @@ -28,7 +49,7 @@ class Logique: def ePieceBlanc(self, piece): """ - Indique si la pièce est une pièce blanche. + Indique si la pièce est une pièce blanche. """ return piece in self.BLANCS @@ -40,7 +61,7 @@ class Logique: def ePiece(self, piece): """ - Indique si la pièce est une pièce. + Indique si la pièce donnée est une pièce. """ # return piece != self.PCE_VIDE return self.ePieceBlanc(piece) or self.ePieceNoir(piece) @@ -61,15 +82,16 @@ class Logique: Indique si la pièce donnée a le droit de jouer. """ return (self.ePieceNoir(piece) and self.joueur == self.NOIR) or \ - (self.ePieceBlanc(piece) and self.joueur == self.BLANC) + (self.ePieceBlanc(piece) and self.joueur == self.BLANC) class LogiqueEchecs(Logique): + """ Logique du jeu d'Échecs """ - CASES_COTE = 8 # Cases de coté + CASES_COTE = 8 # Cases de coté # Type de pièces PCE_PION = 1 @@ -79,12 +101,15 @@ class LogiqueEchecs(Logique): PCE_DAME = 5 PCE_ROI = 6 - DECALAGE_BLANCS = 0 # Valeur à partir de laquelle sont compris les pièces blanches - DECALAGE_NOIRS = 10 # Valeur à partir de laquelle sont compris les pièces noires - - BLANCS = range(DECALAGE_BLANCS+PCE_PION, DECALAGE_BLANCS+PCE_ROI+1) # Intervalle contenant les pièces blancs - NOIRS = range(DECALAGE_NOIRS+PCE_PION, DECALAGE_NOIRS+PCE_ROI+1) # Intervalle contenant les pièces noirs + # Valeur à partir de laquelle sont comprises les pièces blanches + DECALAGE_BLANCS = 0 + # Valeur à partir de laquelle sont comprises les pièces noires + DECALAGE_NOIRS = 10 + BLANCS = range(DECALAGE_BLANCS + PCE_PION, DECALAGE_BLANCS + PCE_ROI + 1) + # Intervalle contenant les pièces blanches + NOIRS = range(DECALAGE_NOIRS + PCE_PION, DECALAGE_NOIRS + PCE_ROI + 1) + # Intervalle contenant les pièces noires # Codes d'erreur de mouvement MVT_INCONNU = 'Cause inconnue' @@ -102,18 +127,15 @@ class LogiqueEchecs(Logique): """ Constructeur de LogiqueEchecs """ - self.grille = [] # Grille de jeu - self.cGrille() + Logique.__init__(self) self.remplirGrille() - self.joueur = self.BLANC # Premier joueur - self.partieFinie = False - self.victorieux = None def remplirGrille(self): """ Remplis la grille avec les pièces nécessaire à une nouvelle partie. """ - speciales = [self.PCE_TOUR, self.PCE_CAVALIER, self.PCE_FOU, self.PCE_ROI, self.PCE_DAME] + speciales = [self.PCE_TOUR, self.PCE_CAVALIER, + self.PCE_FOU, self.PCE_ROI, self.PCE_DAME] speciales += speciales[2::-1] for i in range(0, 8): self.grille[i][0] = self.DECALAGE_NOIRS + speciales[i] @@ -125,7 +147,7 @@ class LogiqueEchecs(Logique): """ Vérifie si le déplacement est possible pour un pion. """ - if x1 == x2 and self.grille[x2][y2] <= 0: # Avance + if x1 == x2 and self.grille[x2][y2] <= 0: # Avance if self.joueur: if y2 == y1 - 1: return self.MVT_OK @@ -140,16 +162,16 @@ class LogiqueEchecs(Logique): return self.MVT_OK else: return self.MVT_N_AUTORISE - elif abs(x1-x2) == 1: # Saut + elif abs(x1 - x2) == 1: # Saut if self.joueur: if y2 == y1 - 1 and \ - self.ePieceNoir(self.grille[x2][y2]): + self.ePieceNoir(self.grille[x2][y2]): return self.MVT_OK else: return self.MVT_N_AUTORISE else: if y2 == y1 + 1 and \ - self.ePieceBlanc(self.grille[x2][y2]): + self.ePieceBlanc(self.grille[x2][y2]): return self.MVT_OK else: return self.MVT_N_AUTORISE @@ -161,13 +183,13 @@ class LogiqueEchecs(Logique): Vérifie si le déplacement est possible pour une tour. """ if y1 == y2: - sens = (x2-x1)//abs(x2-x1) - for x in range(x1+sens, x2, sens): + sens = (x2 - x1) // abs(x2 - x1) + for x in range(x1 + sens, x2, sens): if self.ePiece(self.grille[x][y1]): return self.MVT_OBSTRUCTION elif x1 == x2: - sens = (y2-y1)//abs(y2-y1) - for y in range(y1+sens, y2, sens): + sens = (y2 - y1) // abs(y2 - y1) + for y in range(y1 + sens, y2, sens): if self.ePiece(self.grille[x1][y]): return self.MVT_OBSTRUCTION else: @@ -178,23 +200,23 @@ class LogiqueEchecs(Logique): """ Vérifie si le déplacement est possible pour un fou. """ - if abs(x2-x1) == abs(y2-y1): - sensX = (x2-x1)//abs(x2-x1) - sensY = (y2-y1)//abs(y2-y1) + if abs(x2 - x1) == abs(y2 - y1): + sensX = (x2 - x1) // abs(x2 - x1) + sensY = (y2 - y1) // abs(y2 - y1) x = x1 y = y1 dist = 0 - distTot = abs(x2-x1) + distTot = abs(x2 - x1) while dist < distTot: dist += 1 x += sensX y += sensY if self.ePiece(self.grille[x][y]): if dist == distTot: - return self.MVT_OK # Saut + return self.MVT_OK # Saut else: return self.MVT_OBSTRUCTION - return self.MVT_OK # Vide + return self.MVT_OK # Vide else: return self.MVT_N_AUTORISE @@ -202,23 +224,24 @@ class LogiqueEchecs(Logique): """ Vérifie si le déplacement est possible pour un cavalier. """ - if (abs(x2-x1) == 2 and abs(y2-y1) == 1) or (abs(y2-y1) == 2 and abs(x2-x1) == 1): + if (abs(x2 - x1) == 2 and abs(y2 - y1) == 1) or (abs(y2 - y1) == 2 and abs(x2 - x1) == 1): return self.MVT_OK else: return self.MVT_N_AUTORISE - def deplPossible(self, x1, y1, x2, y2): # TODO Utiliser la gestion d'erreurs ? + # TODO Utiliser la gestion d'erreurs ? + def deplPossible(self, x1, y1, x2, y2): """ Vérifie si le déplacement est possible. """ piece = self.grille[x1][y1] if self.aSonTour(piece): - if (x1 != x2 or y1 != y2): + if x1 != x2 or y1 != y2: if not self.aSonTour(self.grille[x2][y2]): tPiece = self.tPiece(piece) - if tPiece == self.PCE_PION: # Pion + if tPiece == self.PCE_PION: # Pion return self.deplPossiblePion(x1, y1, x2, y2) - elif tPiece == self.PCE_TOUR: # Tour + elif tPiece == self.PCE_TOUR: # Tour return self.deplPossibleTour(x1, y1, x2, y2) elif tPiece == self.PCE_CAVALIER: return self.deplPossibleCavalier(x1, y1, x2, y2) @@ -232,10 +255,10 @@ class LogiqueEchecs(Logique): elif tour == self.MVT_OBSTRUCTION or fou == self.MVT_OBSTRUCTION: return self.MVT_OBSTRUCTION else: - return self.MVT_N_AUTORISE + return self.MVT_N_AUTORISE elif tPiece == self.PCE_ROI: - if abs(x2-x1) <= 1 and abs(y2-y1) <= 1: - return self.MVT_OK + if abs(x2 - x1) <= 1 and abs(y2 - y1) <= 1: + return self.MVT_OK else: return self.MVT_N_AUTORISE else: @@ -247,34 +270,38 @@ class LogiqueEchecs(Logique): else: return self.MVT_SELECTION return self.MVT_INCONNU - + def mvtPossible(self, x1, y1, x2, y2): """ Vérifie si le mouvement est possible. Contrairement aux fonctions de vérification de déplacement, celle-ci - vérifie si le mouvement est réalisable si le roi est en échec. + vérifie si le mouvement est réalisable si le roi est en échec. """ test = self.deplPossible(x1, y1, x2, y2) if test == self.MVT_OK: - # On copie la partie actuelle pour tester le mouvement et vérifier l'échec - copie = copy.deepcopy(self); + # On copie la partie actuelle pour tester le mouvement et vérifier + # l'échec + copie = copy.deepcopy(self) copie.dPieceSansEchec(x1, y1, x2, y2) mvtsPossiblesTousAdverses = [] # On cherche la position du roi - pieceRoi = self.PCE_ROI + self.DECALAGE_BLANCS if self.joueur else self.DECALAGE_NOIRS + pieceRoi = self.PCE_ROI + \ + self.DECALAGE_BLANCS if self.joueur else self.DECALAGE_NOIRS roi = [-1, -1] for x in range(0, self.CASES_COTE): for y in range(0, self.CASES_COTE): - mvtsPossiblesTousAdverses += copie.mvtsPossiblesSansEchec(x, y) + mvtsPossiblesTousAdverses += copie.mvtsPossiblesSansEchec( + x, y) if copie.grille[x][y] == pieceRoi: roi = [x, y] - if roi in mvtsPossiblesTousAdverses: # Si le roi peut être sauté au tour adverse + # Si le roi peut être sauté au tour adverse + if roi in mvtsPossiblesTousAdverses: return self.MVT_ECHEC else: return test else: return test - + def mvtsPossiblesSansEchec(self, x1, y1): """ Donne la liste des déplacements possible pour la pièce donnée. @@ -305,7 +332,8 @@ class LogiqueEchecs(Logique): """ test = self.deplPossible(x1, y1, x2, y2) if test == self.MVT_OK: - self.grille[x1][y1], self.grille[x2][y2] = self.PCE_VIDE, self.grille[x1][y1] + self.grille[x1][y1], self.grille[x2][ + y2] = self.PCE_VIDE, self.grille[x1][y1] self.joueur = not self.joueur def vEchecMat(self): @@ -332,15 +360,16 @@ class LogiqueEchecs(Logique): retour = { 'valide': False, 'message': test, - 'deplacer': [], # Pièces à déplacer - 'supprimer': [], # Pièces à supprimer + 'deplacer': [], # Pièces à déplacer + 'supprimer': [], # Pièces à supprimer } if test == self.MVT_OK: retour['valide'] = True if self.ePiece(self.grille[x2][y2]): retour['supprimer'].append([x2, y2]) retour['deplacer'].append([x1, y1, x2, y2]) - self.grille[x1][y1], self.grille[x2][y2] = self.PCE_VIDE, self.grille[x1][y1] + self.grille[x1][y1], self.grille[x2][ + y2] = self.PCE_VIDE, self.grille[x1][y1] self.joueur = not self.joueur self.vEchecMat() return retour