diff --git a/S1/Echecs/README.md b/S1/Echecs/README.md index a752268..55435dd 100644 --- a/S1/Echecs/README.md +++ b/S1/Echecs/README.md @@ -44,7 +44,7 @@ Chaque fonction possède une brève description de son fonctionnemenent. L'ajout * Qualité du code -Bien que le code fonctionne, soit plutôt flexible, relativement documenté et utilise la notion d'objet, il est loin d'être irréprochable. Certaines fonctions font probablement plus de calcul que nécessaire, la création de certaines variables pourraient être évité. L'ajout de plus de constante au lieu de valeurs arbitraire contribuerait à la lisibilité du code. Certaines instructions ne sont probablement pas sémantiquement correcte. +Bien que le code fonctionne, soit plutôt flexible, relativement documenté et utilise la notion d'objet, il est loin d'être irréprochable. Certaines fonctions font probablement plus de calcul que nécessaire, la création de certaines variables pourraient être évité. L'ajout de plus de constante au lieu de valeurs arbitraire contribuerait à la lisibilité du code. Certaines instructions ne sont probablement pas sémantiquement correcte. Certaines parties du code devraient avoir une gestion d'erreurs car elles sont succeptibles d'en avoir. * Originalité diff --git a/S1/Echecs/guiTk.py b/S1/Echecs/guiTk.py index 4e556f0..78688cc 100644 --- a/S1/Echecs/guiTk.py +++ b/S1/Echecs/guiTk.py @@ -1,5 +1,5 @@ from tkinter import * -from logique import LogiqueEchecs +from logique import LogiqueEchecs, LogiqueDames class PlateauTk: @@ -72,24 +72,25 @@ class PlateauTk: """ Importe l'image de la pièce donnée """ - nom = 'sprites/' - tPiece = self.logique.tPiece(piece) - if tPiece == self.logique.PCE_PION: - nom += 'pion' - elif tPiece == self.logique.PCE_TOUR: - nom += 'tour' - elif tPiece == self.logique.PCE_CAVALIER: - nom += 'cavalier' - elif tPiece == self.logique.PCE_FOU: - nom += 'fou' - elif tPiece == self.logique.PCE_DAME: - nom += 'dame' - elif tPiece == self.logique.PCE_ROI: - nom += 'roi' - else: + try: + nom = 'sprites/' + tPiece = self.logique.tPiece(piece) + if tPiece == self.logique.PCE_PION: + nom += 'pion' + elif tPiece == self.logique.PCE_DAME: + nom += 'dame' + elif tPiece == self.logique.PCE_TOUR: + nom += 'tour' + elif tPiece == self.logique.PCE_CAVALIER: + nom += 'cavalier' + elif tPiece == self.logique.PCE_FOU: + nom += 'fou' + elif tPiece == self.logique.PCE_ROI: + nom += 'roi' + nom += ('B' if self.logique.ePieceBlanche(piece) else 'N') + '.gif' + self.imagesOriginales.update({piece: PhotoImage(file=nom)}) + except: return False - nom += 'B' if self.logique.ePieceBlanche(piece) else 'N' + '.gif' - self.imagesOriginales.update({piece: PhotoImage(file=nom)}) def importerImages(self): """ @@ -329,7 +330,7 @@ class PlateauTk: for y in range(0, self.logique.CASES_COTE): piece = self.logique.grille[x][y] if self.logique.ePiece(piece): - if self.logique.ePieceNoir(piece) ^ self.logique.victorieux: + if self.logique.ePieceNoire(piece) ^ self.logique.victorieux: self.coulCase(x, y, 2) else: self.coulCase(x, y, 3) @@ -452,4 +453,4 @@ class FenetreTk: """ del self.plateau self.plateau = PlateauTk( - self.fen, self.can, self.statut, LogiqueEchecs()) + self.fen, self.can, self.statut, LogiqueDames()) diff --git a/S1/Echecs/logique.py b/S1/Echecs/logique.py index e7ec882..493fd03 100644 --- a/S1/Echecs/logique.py +++ b/S1/Echecs/logique.py @@ -44,13 +44,13 @@ class Logique: self.grille = [[self.PCE_VIDE for y in range(self.CASES_COTE)] \ for x in range(self.CASES_COTE)] - def ePieceBlanc(self, piece): + def ePieceBlanche(self, piece): """ Indique si la pièce est une pièce blanche. """ return piece in self.BLANCS - def ePieceNoir(self, piece): + def ePieceNoire(self, piece): """ Indique si la pièce est une pièce noire. """ @@ -61,15 +61,15 @@ class Logique: Indique si la pièce donnée est une pièce. """ # return piece != self.PCE_VIDE - return self.ePieceBlanc(piece) or self.ePieceNoir(piece) + return self.ePieceBlanche(piece) or self.ePieceNoire(piece) def tPiece(self, piece): """ Retourne le type de pièce de la pièce donnée. """ - if self.ePieceBlanc(piece): + if self.ePieceBlanche(piece): return piece - self.DECALAGE_BLANCS - elif self.ePieceNoir(piece): + elif self.ePieceNoire(piece): return piece - self.DECALAGE_NOIRS else: return self.PCE_VIDE @@ -78,12 +78,205 @@ 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) + return (self.ePieceNoire(piece) and self.joueur == self.NOIR) or \ + (self.ePieceBlanche(piece) and self.joueur == self.BLANC) +class LogiqueDames(Logique): + """ + Logique du jeu de Dames + """ + CASES_COTE = 10 + + PCE_PION = 1 + PCE_DAME = 2 + + DECALAGE_BLANCS = 0 + DECALAGE_NOIRS = 10 + + BLANCS = range(DECALAGE_BLANCS + PCE_PION, DECALAGE_BLANCS + PCE_DAME + 1) + NOIRS = range(DECALAGE_NOIRS + PCE_PION, DECALAGE_NOIRS + PCE_DAME + 1) + + MVT_INCONNU = 'Cause inconnue' + MVT_OK = 'Valide' + MVT_SELECTION = 'Mauvais tour' + MVT_SUR_PLACE = 'Immobile' + MVT_N_AUTORISE = 'Non-autorisé' + MVT_CASE_BLANCHE = 'Case blanche' + MVT_SAUT_AMI = 'Saut ami' + MVT_DEST_OCC = 'Destination occupée' + MVT_OBSTRUCTION = 'Pièce en chemin' + MVT_SOUFFLER = 'Souffler n\'est pas jouer' + MVT_PIECE_INC = 'Pièce inconnue' + + def __init__(self): + """ + Constructeur de LogiqueEchecs + """ + Logique.__init__(self) + self.remplirGrille() + + def remplirGrille(self): + """ + Remplis la grille avec les pièces nécessaire à une nouvelle partie. + """ + for y in range(0, 3+1): + for x in range(0, self.CASES_COTE): + if not self.eCaseBlanche(x, y): + self.grille[x][y] = self.DECALAGE_NOIRS + self.PCE_PION + for y in range(self.CASES_COTE-3-1, self.CASES_COTE): + for x in range(0, self.CASES_COTE): + if not self.eCaseBlanche(x, y): + self.grille[x][y] = self.DECALAGE_BLANCS + self.PCE_PION + + def deplPossiblePion(self, x1, y1, x2, y2): + """ + Vérifie si le déplacement est possible pour un pion. + """ + if abs(x2-x1) == 1 and abs(y2-y1) == 1: + if (self.joueur == self.BLANC and y1 > y2) or (self.joueur == self.NOIR and y1 < y2): + return self.MVT_OK + else: + return self.MVT_N_AUTORISE + + def deplPossibleDame(self, x1, y1, x2, y2): + """ + Vérifie si le déplacement est possible pour une dame. + """ + 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) + while dist < distTot: + dist += 1 + x += sensX + y += sensY + if self.ePiece(self.grille[x][y]): + if dist == distTot: + return self.MVT_OK # Saut + else: + return self.MVT_OBSTRUCTION + return self.MVT_OK # Vide + else: + return self.MVT_N_AUTORISE + + # TODO Utiliser la gestion d'erreurs de Python ? + 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 not self.ePiece(self.grille[x2][y2]): + if not self.eCaseBlanche(x2, y2): + tPiece = self.tPiece(piece) + if tPiece == self.PCE_PION: # Pion + return self.deplPossiblePion(x1, y1, x2, y2) + elif tPiece == self.PCE_DAME: + return self.deplPossibleDame(x1, y1, x2, y2) + else: + return self.MVT_PIECE_INC + else: + return self.MVT_CASE_BLANCHE + else: + return self.MVT_DEST_OCC + else: + return self.MVT_SUR_PLACE + 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 le "Soufler n'est pas jouer". + """ + test = self.deplPossible(x1, y1, x2, y2) + if test == self.MVT_OK: + # TODO Vérifier le souffler n'est pas jouer + if False: + return self.MVT_SOUFFLER + else: + return test + else: + return test + + def deplsPossibles(self, x1, y1): + """ + Donne la liste des déplacements possible pour la pièce donnée. + """ + tableau = [] + for x2 in range(0, self.CASES_COTE): + for y2 in range(0, self.CASES_COTE): + if self.deplPossible(x1, y1, x2, y2) == self.MVT_OK: + tableau.append([x2, y2]) + return tableau + + def mvtsPossibles(self, x1, y1): + """ + Donne la liste des mouvements possible pour la pièce donnée. + """ + tableau = [] + for x2 in range(0, self.CASES_COTE): + for y2 in range(0, self.CASES_COTE): + if self.mvtPossible(x1, y1, x2, y2) == self.MVT_OK: + tableau.append([x2, y2]) + return tableau + + def dPieceSansSouffler(self, x1, y1, x2, y2): + """ + Déplace la pièce aux coordonnées 1 données aux coordonnées 2 données. + Ne vérifie pas le "Souffler n'est pas jouer". + (Est utilisé dans pour cette détection) + """ + 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.joueur = not self.joueur + + def vPartieFinie(self): + """ + Vérifie si le joueur actuel ne peut plus jouer. + """ + # Vérifications si aucun mouvement pour aucune pièce n'est possible + for x in range(0, self.CASES_COTE): + for y in range(0, self.CASES_COTE): + if len(self.mvtsPossibles(x, y)) > 0: + return False + self.partieFinie = True + self.victorieux = not self.joueur + return True + + def dPiece(self, x1, y1, x2, y2): + """ + Déplace la pièce aux coordonnées 1 données aux coordonnées 2 données. + Renvoie les détails du mouvement. + """ + test = self.mvtPossible(x1, y1, x2, y2) + retour = { + 'valide': False, + 'message': test, + '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.joueur = not self.joueur + self.vPartieFinie() + return retour + class LogiqueEchecs(Logique): - """ Logique du jeu d'Échecs """ @@ -115,7 +308,7 @@ class LogiqueEchecs(Logique): MVT_SELECTION = 'Mauvais tour' MVT_SUR_PLACE = 'Immobile' MVT_SAUT_AMI = 'Saut ami' - MVT_PIECE_INC = 'Pièce inconnu' + MVT_PIECE_INC = 'Pièce inconnue' MVT_N_AUTORISE = 'Non-autorisé' MVT_OBSTRUCTION = 'Pièce en chemin' MVT_ECHEC = 'Échec au roi' @@ -134,11 +327,11 @@ class LogiqueEchecs(Logique): 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] - self.grille[i][1] = self.DECALAGE_NOIRS + self.PCE_PION - self.grille[i][6] = self.DECALAGE_BLANCS + self.PCE_PION - self.grille[i][7] = self.DECALAGE_BLANCS + speciales[i] + for x in range(0, 8): + self.grille[x][0] = self.DECALAGE_NOIRS + speciales[x] + self.grille[x][1] = self.DECALAGE_NOIRS + self.PCE_PION + self.grille[x][6] = self.DECALAGE_BLANCS + self.PCE_PION + self.grille[x][7] = self.DECALAGE_BLANCS + speciales[x] def deplPossiblePion(self, x1, y1, x2, y2): """ @@ -162,13 +355,13 @@ class LogiqueEchecs(Logique): elif abs(x1 - x2) == 1: # Saut if self.joueur: if y2 == y1 - 1 and \ - self.ePieceNoir(self.grille[x2][y2]): + self.ePieceNoire(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.ePieceBlanche(self.grille[x2][y2]): return self.MVT_OK else: return self.MVT_N_AUTORISE @@ -287,7 +480,7 @@ class LogiqueEchecs(Logique): roi = [-1, -1] for x in range(0, self.CASES_COTE): for y in range(0, self.CASES_COTE): - mvtsPossiblesTousAdverses += copie.mvtsPossiblesSansEchec( + mvtsPossiblesTousAdverses += copie.deplsPossibles( x, y) if copie.grille[x][y] == pieceRoi: roi = [x, y] @@ -299,7 +492,7 @@ class LogiqueEchecs(Logique): else: return test - def mvtsPossiblesSansEchec(self, x1, y1): + def deplsPossibles(self, x1, y1): """ Donne la liste des déplacements possible pour la pièce donnée. """