[Echecs] Ajout du début de LogiqueDames

This commit is contained in:
Geoffrey Frogeye 2014-12-14 19:30:19 +01:00
parent e258823cd5
commit ccdb4c1657
3 changed files with 233 additions and 39 deletions

View file

@ -44,7 +44,7 @@ Chaque fonction possède une brève description de son fonctionnemenent. L'ajout
* Qualité du code * 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é * Originalité

View file

@ -1,5 +1,5 @@
from tkinter import * from tkinter import *
from logique import LogiqueEchecs from logique import LogiqueEchecs, LogiqueDames
class PlateauTk: class PlateauTk:
@ -72,24 +72,25 @@ class PlateauTk:
""" """
Importe l'image de la pièce donnée Importe l'image de la pièce donnée
""" """
try:
nom = 'sprites/' nom = 'sprites/'
tPiece = self.logique.tPiece(piece) tPiece = self.logique.tPiece(piece)
if tPiece == self.logique.PCE_PION: if tPiece == self.logique.PCE_PION:
nom += 'pion' nom += 'pion'
elif tPiece == self.logique.PCE_DAME:
nom += 'dame'
elif tPiece == self.logique.PCE_TOUR: elif tPiece == self.logique.PCE_TOUR:
nom += 'tour' nom += 'tour'
elif tPiece == self.logique.PCE_CAVALIER: elif tPiece == self.logique.PCE_CAVALIER:
nom += 'cavalier' nom += 'cavalier'
elif tPiece == self.logique.PCE_FOU: elif tPiece == self.logique.PCE_FOU:
nom += 'fou' nom += 'fou'
elif tPiece == self.logique.PCE_DAME:
nom += 'dame'
elif tPiece == self.logique.PCE_ROI: elif tPiece == self.logique.PCE_ROI:
nom += 'roi' nom += 'roi'
else: nom += ('B' if self.logique.ePieceBlanche(piece) else 'N') + '.gif'
return False
nom += 'B' if self.logique.ePieceBlanche(piece) else 'N' + '.gif'
self.imagesOriginales.update({piece: PhotoImage(file=nom)}) self.imagesOriginales.update({piece: PhotoImage(file=nom)})
except:
return False
def importerImages(self): def importerImages(self):
""" """
@ -329,7 +330,7 @@ class PlateauTk:
for y in range(0, self.logique.CASES_COTE): for y in range(0, self.logique.CASES_COTE):
piece = self.logique.grille[x][y] piece = self.logique.grille[x][y]
if self.logique.ePiece(piece): 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) self.coulCase(x, y, 2)
else: else:
self.coulCase(x, y, 3) self.coulCase(x, y, 3)
@ -452,4 +453,4 @@ class FenetreTk:
""" """
del self.plateau del self.plateau
self.plateau = PlateauTk( self.plateau = PlateauTk(
self.fen, self.can, self.statut, LogiqueEchecs()) self.fen, self.can, self.statut, LogiqueDames())

View file

@ -44,13 +44,13 @@ class Logique:
self.grille = [[self.PCE_VIDE for y in range(self.CASES_COTE)] \ self.grille = [[self.PCE_VIDE for y in range(self.CASES_COTE)] \
for x 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. Indique si la pièce est une pièce blanche.
""" """
return piece in self.BLANCS return piece in self.BLANCS
def ePieceNoir(self, piece): def ePieceNoire(self, piece):
""" """
Indique si la pièce est une pièce noire. 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. Indique si la pièce donnée est une pièce.
""" """
# return piece != self.PCE_VIDE # 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): def tPiece(self, piece):
""" """
Retourne le type de pièce de la pièce donnée. 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 return piece - self.DECALAGE_BLANCS
elif self.ePieceNoir(piece): elif self.ePieceNoire(piece):
return piece - self.DECALAGE_NOIRS return piece - self.DECALAGE_NOIRS
else: else:
return self.PCE_VIDE return self.PCE_VIDE
@ -78,12 +78,205 @@ class Logique:
""" """
Indique si la pièce donnée a le droit de jouer. Indique si la pièce donnée a le droit de jouer.
""" """
return (self.ePieceNoir(piece) and self.joueur == self.NOIR) or \ return (self.ePieceNoire(piece) and self.joueur == self.NOIR) or \
(self.ePieceBlanc(piece) and self.joueur == self.BLANC) (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): class LogiqueEchecs(Logique):
""" """
Logique du jeu d'Échecs Logique du jeu d'Échecs
""" """
@ -115,7 +308,7 @@ class LogiqueEchecs(Logique):
MVT_SELECTION = 'Mauvais tour' MVT_SELECTION = 'Mauvais tour'
MVT_SUR_PLACE = 'Immobile' MVT_SUR_PLACE = 'Immobile'
MVT_SAUT_AMI = 'Saut ami' MVT_SAUT_AMI = 'Saut ami'
MVT_PIECE_INC = 'Pièce inconnu' MVT_PIECE_INC = 'Pièce inconnue'
MVT_N_AUTORISE = 'Non-autorisé' MVT_N_AUTORISE = 'Non-autorisé'
MVT_OBSTRUCTION = 'Pièce en chemin' MVT_OBSTRUCTION = 'Pièce en chemin'
MVT_ECHEC = 'Échec au roi' MVT_ECHEC = 'Échec au roi'
@ -134,11 +327,11 @@ class LogiqueEchecs(Logique):
speciales = [self.PCE_TOUR, self.PCE_CAVALIER, speciales = [self.PCE_TOUR, self.PCE_CAVALIER,
self.PCE_FOU, self.PCE_ROI, self.PCE_DAME] self.PCE_FOU, self.PCE_ROI, self.PCE_DAME]
speciales += speciales[2::-1] speciales += speciales[2::-1]
for i in range(0, 8): for x in range(0, 8):
self.grille[i][0] = self.DECALAGE_NOIRS + speciales[i] self.grille[x][0] = self.DECALAGE_NOIRS + speciales[x]
self.grille[i][1] = self.DECALAGE_NOIRS + self.PCE_PION self.grille[x][1] = self.DECALAGE_NOIRS + self.PCE_PION
self.grille[i][6] = self.DECALAGE_BLANCS + self.PCE_PION self.grille[x][6] = self.DECALAGE_BLANCS + self.PCE_PION
self.grille[i][7] = self.DECALAGE_BLANCS + speciales[i] self.grille[x][7] = self.DECALAGE_BLANCS + speciales[x]
def deplPossiblePion(self, x1, y1, x2, y2): def deplPossiblePion(self, x1, y1, x2, y2):
""" """
@ -162,13 +355,13 @@ class LogiqueEchecs(Logique):
elif abs(x1 - x2) == 1: # Saut elif abs(x1 - x2) == 1: # Saut
if self.joueur: if self.joueur:
if y2 == y1 - 1 and \ if y2 == y1 - 1 and \
self.ePieceNoir(self.grille[x2][y2]): self.ePieceNoire(self.grille[x2][y2]):
return self.MVT_OK return self.MVT_OK
else: else:
return self.MVT_N_AUTORISE return self.MVT_N_AUTORISE
else: else:
if y2 == y1 + 1 and \ if y2 == y1 + 1 and \
self.ePieceBlanc(self.grille[x2][y2]): self.ePieceBlanche(self.grille[x2][y2]):
return self.MVT_OK return self.MVT_OK
else: else:
return self.MVT_N_AUTORISE return self.MVT_N_AUTORISE
@ -287,7 +480,7 @@ class LogiqueEchecs(Logique):
roi = [-1, -1] roi = [-1, -1]
for x in range(0, self.CASES_COTE): for x in range(0, self.CASES_COTE):
for y in range(0, self.CASES_COTE): for y in range(0, self.CASES_COTE):
mvtsPossiblesTousAdverses += copie.mvtsPossiblesSansEchec( mvtsPossiblesTousAdverses += copie.deplsPossibles(
x, y) x, y)
if copie.grille[x][y] == pieceRoi: if copie.grille[x][y] == pieceRoi:
roi = [x, y] roi = [x, y]
@ -299,7 +492,7 @@ class LogiqueEchecs(Logique):
else: else:
return test 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. Donne la liste des déplacements possible pour la pièce donnée.
""" """