2014-12-12 19:49:58 +01:00
|
|
|
import copy
|
|
|
|
|
2014-12-14 17:44:45 +01:00
|
|
|
|
2014-12-12 21:11:22 +01:00
|
|
|
class Logique:
|
2014-12-14 17:44:45 +01:00
|
|
|
|
2014-12-12 21:11:22 +01:00
|
|
|
"""
|
|
|
|
Logique des jeux sur damier
|
2014-12-14 17:44:45 +01:00
|
|
|
(Ne peut être utilisé seul)
|
2014-12-12 21:11:22 +01:00
|
|
|
"""
|
|
|
|
|
2014-12-14 17:44:45 +01:00
|
|
|
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
|
2014-12-12 21:11:22 +01:00
|
|
|
|
|
|
|
@staticmethod
|
2014-12-14 00:47:49 +01:00
|
|
|
def eCaseBlanche(x, y):
|
|
|
|
"""
|
|
|
|
Indique si la case aux coordonnées indiquée est blanche.
|
|
|
|
"""
|
|
|
|
return x % 2 == y % 2
|
2014-12-12 21:11:22 +01:00
|
|
|
|
|
|
|
def cGrille(self):
|
2014-12-14 00:47:49 +01:00
|
|
|
"""
|
|
|
|
Crée le tableau self.grille.
|
|
|
|
"""
|
2014-12-14 18:24:40 +01:00
|
|
|
self.grille = [[self.PCE_VIDE for y in range(self.CASES_COTE)] \
|
|
|
|
for x in range(self.CASES_COTE)]
|
2014-12-12 21:11:22 +01:00
|
|
|
|
2014-12-14 19:30:19 +01:00
|
|
|
def ePieceBlanche(self, piece):
|
2014-12-14 00:47:49 +01:00
|
|
|
"""
|
2014-12-14 17:44:45 +01:00
|
|
|
Indique si la pièce est une pièce blanche.
|
2014-12-14 00:47:49 +01:00
|
|
|
"""
|
2014-12-14 16:43:11 +01:00
|
|
|
return piece in self.BLANCS
|
2014-12-12 21:11:22 +01:00
|
|
|
|
2014-12-14 19:30:19 +01:00
|
|
|
def ePieceNoire(self, piece):
|
2014-12-14 00:47:49 +01:00
|
|
|
"""
|
|
|
|
Indique si la pièce est une pièce noire.
|
|
|
|
"""
|
2014-12-14 16:43:11 +01:00
|
|
|
return piece in self.NOIRS
|
2014-12-12 21:11:22 +01:00
|
|
|
|
|
|
|
def ePiece(self, piece):
|
2014-12-14 00:47:49 +01:00
|
|
|
"""
|
2014-12-14 17:44:45 +01:00
|
|
|
Indique si la pièce donnée est une pièce.
|
2014-12-14 00:47:49 +01:00
|
|
|
"""
|
2014-12-12 21:11:22 +01:00
|
|
|
# return piece != self.PCE_VIDE
|
2014-12-14 19:30:19 +01:00
|
|
|
return self.ePieceBlanche(piece) or self.ePieceNoire(piece)
|
2014-12-12 21:11:22 +01:00
|
|
|
|
|
|
|
def tPiece(self, piece):
|
2014-12-14 00:47:49 +01:00
|
|
|
"""
|
|
|
|
Retourne le type de pièce de la pièce donnée.
|
|
|
|
"""
|
2014-12-14 19:30:19 +01:00
|
|
|
if self.ePieceBlanche(piece):
|
2014-12-12 21:11:22 +01:00
|
|
|
return piece - self.DECALAGE_BLANCS
|
2014-12-14 19:30:19 +01:00
|
|
|
elif self.ePieceNoire(piece):
|
2014-12-12 21:11:22 +01:00
|
|
|
return piece - self.DECALAGE_NOIRS
|
|
|
|
else:
|
|
|
|
return self.PCE_VIDE
|
|
|
|
|
2014-12-14 16:43:11 +01:00
|
|
|
def aSonTour(self, piece):
|
2014-12-14 00:47:49 +01:00
|
|
|
"""
|
|
|
|
Indique si la pièce donnée a le droit de jouer.
|
|
|
|
"""
|
2014-12-14 19:30:19 +01:00
|
|
|
return (self.ePieceNoire(piece) and self.joueur == self.NOIR) or \
|
|
|
|
(self.ePieceBlanche(piece) and self.joueur == self.BLANC)
|
2014-12-12 21:11:22 +01:00
|
|
|
|
|
|
|
|
2014-12-14 19:30:19 +01:00
|
|
|
class LogiqueDames(Logique):
|
|
|
|
"""
|
2014-12-14 22:37:19 +01:00
|
|
|
Logique du jeu de Dames (International)
|
2014-12-14 19:30:19 +01:00
|
|
|
"""
|
|
|
|
CASES_COTE = 10
|
2014-12-14 22:19:44 +01:00
|
|
|
RANGEES = 4
|
2014-12-14 19:30:19 +01:00
|
|
|
|
|
|
|
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'
|
2014-12-14 20:44:29 +01:00
|
|
|
MVT_SAUT = 'Saut'
|
2014-12-14 19:30:19 +01:00
|
|
|
MVT_SELECTION = 'Mauvais tour'
|
|
|
|
MVT_SUR_PLACE = 'Immobile'
|
|
|
|
MVT_N_AUTORISE = 'Non-autorisé'
|
|
|
|
MVT_CASE_BLANCHE = 'Case blanche'
|
2014-12-14 22:37:19 +01:00
|
|
|
MVT_PRISE_ARRIERE = 'Prise arrière'
|
2014-12-14 19:30:19 +01:00
|
|
|
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'
|
|
|
|
|
2014-12-14 22:37:19 +01:00
|
|
|
PRISE_ARRIERE = True
|
|
|
|
DEPL_LONG_DAME = True
|
|
|
|
|
2014-12-14 19:30:19 +01:00
|
|
|
def __init__(self):
|
|
|
|
"""
|
2014-12-14 22:37:19 +01:00
|
|
|
Constructeur de LogiqueDames
|
2014-12-14 19:30:19 +01:00
|
|
|
"""
|
|
|
|
Logique.__init__(self)
|
|
|
|
self.remplirGrille()
|
2014-12-14 20:58:43 +01:00
|
|
|
self.rafle = False
|
2014-12-14 19:30:19 +01:00
|
|
|
|
|
|
|
def remplirGrille(self):
|
|
|
|
"""
|
|
|
|
Remplis la grille avec les pièces nécessaire à une nouvelle partie.
|
|
|
|
"""
|
2014-12-14 22:19:44 +01:00
|
|
|
for y in range(0, self.RANGEES):
|
2014-12-14 19:30:19 +01:00
|
|
|
for x in range(0, self.CASES_COTE):
|
|
|
|
if not self.eCaseBlanche(x, y):
|
2014-12-14 20:58:43 +01:00
|
|
|
self.grille[x][y] = self.DECALAGE_NOIRS + self.PCE_PION
|
2014-12-14 22:19:44 +01:00
|
|
|
for y in range(self.CASES_COTE-self.RANGEES, self.CASES_COTE):
|
2014-12-14 19:30:19 +01:00
|
|
|
for x in range(0, self.CASES_COTE):
|
|
|
|
if not self.eCaseBlanche(x, y):
|
2014-12-14 20:58:43 +01:00
|
|
|
self.grille[x][y] = self.DECALAGE_BLANCS + self.PCE_PION
|
2014-12-14 19:30:19 +01:00
|
|
|
|
|
|
|
def deplPossiblePion(self, x1, y1, x2, y2):
|
|
|
|
"""
|
|
|
|
Vérifie si le déplacement est possible pour un pion.
|
|
|
|
"""
|
2014-12-14 20:58:43 +01:00
|
|
|
if abs(x2-x1) == 1 and abs(y2-y1) == 1 and not self.rafle:
|
2014-12-14 19:30:19 +01:00
|
|
|
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
|
2014-12-14 20:44:29 +01:00
|
|
|
elif abs(x2-x1) == 2 and abs(y2-y1) == 2:
|
|
|
|
xS = x1+(x2-x1)//2
|
|
|
|
yS = y1+(y2-y1)//2
|
|
|
|
if self.ePiece(self.grille[xS][yS]):
|
2014-12-14 22:37:19 +01:00
|
|
|
if not self.PRISE_ARRIERE and (self.joueur == self.BLANC and y1 < y2) or \
|
|
|
|
(self.joueur == self.NOIR and y1 > y2):
|
|
|
|
return self.MVT_PRISE_ARRIERE
|
2014-12-14 20:44:29 +01:00
|
|
|
if self.aSonTour(self.grille[xS][yS]):
|
|
|
|
return self.MVT_SAUT_AMI
|
|
|
|
else:
|
|
|
|
return self.MVT_SAUT
|
|
|
|
else:
|
|
|
|
return self.MVT_N_AUTORISE
|
|
|
|
else:
|
|
|
|
return self.MVT_N_AUTORISE
|
2014-12-14 19:30:19 +01:00
|
|
|
|
|
|
|
def deplPossibleDame(self, x1, y1, x2, y2):
|
|
|
|
"""
|
|
|
|
Vérifie si le déplacement est possible pour une dame.
|
|
|
|
"""
|
2014-12-14 22:37:19 +01:00
|
|
|
if self.DEPL_LONG_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 - 1 and not self.aSonTour(self.grille[x][y]):
|
|
|
|
return self.MVT_SAUT
|
|
|
|
else:
|
|
|
|
return self.MVT_OBSTRUCTION
|
|
|
|
if self.rafle:
|
|
|
|
return self.MVT_SOUFFLER
|
|
|
|
else:
|
|
|
|
return self.MVT_OK
|
2014-12-14 20:58:43 +01:00
|
|
|
else:
|
2014-12-14 22:37:19 +01:00
|
|
|
return self.MVT_N_AUTORISE
|
2014-12-14 19:30:19 +01:00
|
|
|
else:
|
2014-12-14 22:37:19 +01:00
|
|
|
if abs(x2-x1) == 1 and abs(y2-y1) == 1 and not self.rafle:
|
|
|
|
return self.MVT_OK
|
|
|
|
elif abs(x2-x1) == 2 and abs(y2-y1) == 2:
|
|
|
|
xS = x1+(x2-x1)//2
|
|
|
|
yS = y1+(y2-y1)//2
|
|
|
|
if self.ePiece(self.grille[xS][yS]):
|
|
|
|
if self.aSonTour(self.grille[xS][yS]):
|
|
|
|
return self.MVT_SAUT_AMI
|
|
|
|
else:
|
|
|
|
return self.MVT_SAUT
|
|
|
|
else:
|
|
|
|
return self.MVT_N_AUTORISE
|
|
|
|
else:
|
|
|
|
return self.MVT_N_AUTORISE
|
2014-12-14 19:30:19 +01:00
|
|
|
|
|
|
|
# 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:
|
2014-12-14 21:39:11 +01:00
|
|
|
if self.sautEstPossibleTous():
|
2014-12-14 19:30:19 +01:00
|
|
|
return self.MVT_SOUFFLER
|
|
|
|
else:
|
|
|
|
return test
|
|
|
|
else:
|
|
|
|
return test
|
2014-12-14 17:44:45 +01:00
|
|
|
|
2014-12-14 19:30:19 +01:00
|
|
|
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):
|
2014-12-14 20:44:29 +01:00
|
|
|
if self.deplPossible(x1, y1, x2, y2) == self.MVT_OK \
|
|
|
|
or self.mvtPossible(x1, y1, x2, y2) == self.MVT_SAUT:
|
2014-12-14 19:30:19 +01:00
|
|
|
tableau.append([x2, y2])
|
|
|
|
return tableau
|
|
|
|
|
2014-12-14 20:58:43 +01:00
|
|
|
def sautsPossibles(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):
|
2014-12-14 21:39:11 +01:00
|
|
|
if self.deplPossible(x1, y1, x2, y2) == self.MVT_SAUT:
|
2014-12-14 20:58:43 +01:00
|
|
|
tableau.append([x2, y2])
|
|
|
|
return tableau
|
|
|
|
|
2014-12-14 21:39:11 +01:00
|
|
|
def sautEstPossibleTous(self):
|
|
|
|
"""
|
|
|
|
Indique si le joueur peut faire un saut.
|
|
|
|
"""
|
|
|
|
for x in range(0, self.CASES_COTE):
|
|
|
|
for y in range(0, self.CASES_COTE):
|
|
|
|
if self.aSonTour(self.grille[x][y]):
|
|
|
|
if len(self.sautsPossibles(x, y)) > 0:
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
2014-12-14 19:30:19 +01:00
|
|
|
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):
|
2014-12-14 20:44:29 +01:00
|
|
|
if self.mvtPossible(x1, y1, x2, y2) == self.MVT_OK \
|
|
|
|
or self.mvtPossible(x1, y1, x2, y2) == self.MVT_SAUT:
|
2014-12-14 19:30:19 +01:00
|
|
|
tableau.append([x2, y2])
|
|
|
|
return tableau
|
|
|
|
|
|
|
|
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,
|
2014-12-14 22:19:44 +01:00
|
|
|
'ajouter': [], # Pièces à ajouter
|
2014-12-14 19:30:19 +01:00
|
|
|
'deplacer': [], # Pièces à déplacer
|
|
|
|
'supprimer': [], # Pièces à supprimer
|
|
|
|
}
|
2014-12-14 20:44:29 +01:00
|
|
|
if test in [self.MVT_OK, self.MVT_SAUT]:
|
|
|
|
if test == self.MVT_SAUT:
|
|
|
|
xS = x2-(x2-x1)//abs(x2-x1)
|
|
|
|
yS = y2-(y2-y1)//abs(y2-y1)
|
|
|
|
self.grille[xS][yS] = self.PCE_VIDE
|
|
|
|
retour['supprimer'].append([xS, yS])
|
2014-12-14 19:30:19 +01:00
|
|
|
retour['valide'] = True
|
|
|
|
retour['deplacer'].append([x1, y1, x2, y2])
|
2014-12-14 20:44:29 +01:00
|
|
|
self.grille[x1][y1], self.grille[x2][y2] = self.PCE_VIDE, self.grille[x1][y1]
|
2014-12-14 20:58:43 +01:00
|
|
|
if test == self.MVT_SAUT and len(self.sautsPossibles(x2, y2)) > 0:
|
|
|
|
self.rafle = True
|
|
|
|
else:
|
|
|
|
self.rafle = False
|
2014-12-14 22:19:44 +01:00
|
|
|
piece = self.grille[x2][y2]
|
|
|
|
if self.tPiece(piece) == self.PCE_PION and ((self.ePieceBlanche(piece) and \
|
|
|
|
y2 == 0) or (self.ePieceNoire(piece) and y2 == self.CASES_COTE - 1)):
|
|
|
|
self.grille[x2][y2] = (self.DECALAGE_BLANCS if self.ePieceBlanche(piece) else \
|
|
|
|
self.DECALAGE_NOIRS) + self.PCE_DAME
|
2014-12-14 23:20:52 +01:00
|
|
|
retour['deplacer'] = []
|
|
|
|
retour['supprimer'].append([x1, y1])
|
2014-12-14 22:19:44 +01:00
|
|
|
retour['ajouter'].append([x2, y2, self.grille[x2][y2]])
|
2014-12-14 20:58:43 +01:00
|
|
|
self.joueur = not self.joueur
|
2014-12-14 19:30:19 +01:00
|
|
|
self.vPartieFinie()
|
|
|
|
return retour
|
|
|
|
|
2014-12-14 22:37:19 +01:00
|
|
|
class LogiqueDamesAnglaises(LogiqueDames):
|
|
|
|
"""
|
|
|
|
Logique du jeu de Dames (Anglaises)
|
|
|
|
"""
|
|
|
|
CASES_COTE = 8
|
|
|
|
RANGEES = 3
|
|
|
|
PRISE_ARRIERE = False
|
|
|
|
DEPL_LONG_DAME = False
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
"""
|
|
|
|
Constructeur de LogiqueDamesAnglaises
|
|
|
|
"""
|
|
|
|
LogiqueDames.__init__(self)
|
|
|
|
|
2014-12-14 19:30:19 +01:00
|
|
|
class LogiqueEchecs(Logique):
|
2014-12-12 21:11:22 +01:00
|
|
|
"""
|
|
|
|
Logique du jeu d'Échecs
|
|
|
|
"""
|
2014-12-12 19:49:58 +01:00
|
|
|
|
2014-12-14 17:44:45 +01:00
|
|
|
CASES_COTE = 8 # Cases de coté
|
2014-12-12 19:49:58 +01:00
|
|
|
|
2014-12-14 00:47:49 +01:00
|
|
|
# Type de pièces
|
2014-12-12 21:11:22 +01:00
|
|
|
PCE_PION = 1
|
|
|
|
PCE_TOUR = 2
|
|
|
|
PCE_CAVALIER = 3
|
|
|
|
PCE_FOU = 4
|
|
|
|
PCE_DAME = 5
|
|
|
|
PCE_ROI = 6
|
|
|
|
|
2014-12-14 17:44:45 +01:00
|
|
|
# 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
|
2014-12-12 21:11:22 +01:00
|
|
|
|
2014-12-14 17:44:45 +01:00
|
|
|
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
|
2014-12-12 21:11:22 +01:00
|
|
|
|
2014-12-14 00:47:49 +01:00
|
|
|
# Codes d'erreur de mouvement
|
2014-12-12 19:49:58 +01:00
|
|
|
MVT_INCONNU = 'Cause inconnue'
|
|
|
|
MVT_OK = 'Valide'
|
|
|
|
MVT_ROQUE = 'Roque'
|
|
|
|
MVT_SELECTION = 'Mauvais tour'
|
|
|
|
MVT_SUR_PLACE = 'Immobile'
|
|
|
|
MVT_SAUT_AMI = 'Saut ami'
|
2014-12-14 19:30:19 +01:00
|
|
|
MVT_PIECE_INC = 'Pièce inconnue'
|
2014-12-12 19:49:58 +01:00
|
|
|
MVT_N_AUTORISE = 'Non-autorisé'
|
2014-12-14 16:43:11 +01:00
|
|
|
MVT_OBSTRUCTION = 'Pièce en chemin'
|
2014-12-12 19:49:58 +01:00
|
|
|
MVT_ECHEC = 'Échec au roi'
|
|
|
|
|
|
|
|
def __init__(self):
|
2014-12-14 00:47:49 +01:00
|
|
|
"""
|
|
|
|
Constructeur de LogiqueEchecs
|
|
|
|
"""
|
2014-12-14 17:44:45 +01:00
|
|
|
Logique.__init__(self)
|
2014-12-12 19:49:58 +01:00
|
|
|
self.remplirGrille()
|
|
|
|
|
|
|
|
def remplirGrille(self):
|
2014-12-14 00:47:49 +01:00
|
|
|
"""
|
|
|
|
Remplis la grille avec les pièces nécessaire à une nouvelle partie.
|
|
|
|
"""
|
2014-12-14 17:44:45 +01:00
|
|
|
speciales = [self.PCE_TOUR, self.PCE_CAVALIER,
|
|
|
|
self.PCE_FOU, self.PCE_ROI, self.PCE_DAME]
|
2014-12-13 23:04:54 +01:00
|
|
|
speciales += speciales[2::-1]
|
2014-12-14 19:30:19 +01:00
|
|
|
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]
|
2014-12-12 19:49:58 +01:00
|
|
|
|
2014-12-14 16:43:11 +01:00
|
|
|
def deplPossiblePion(self, x1, y1, x2, y2):
|
2014-12-14 00:47:49 +01:00
|
|
|
"""
|
|
|
|
Vérifie si le déplacement est possible pour un pion.
|
|
|
|
"""
|
2014-12-14 17:44:45 +01:00
|
|
|
if x1 == x2 and self.grille[x2][y2] <= 0: # Avance
|
2014-12-12 19:49:58 +01:00
|
|
|
if self.joueur:
|
|
|
|
if y2 == y1 - 1:
|
2014-12-12 21:11:22 +01:00
|
|
|
return self.MVT_OK
|
2014-12-12 19:49:58 +01:00
|
|
|
elif y1 == 6 and y2 == 4 and self.grille[x1][5] == 0:
|
2014-12-12 21:11:22 +01:00
|
|
|
return self.MVT_OK
|
2014-12-12 19:49:58 +01:00
|
|
|
else:
|
2014-12-12 21:11:22 +01:00
|
|
|
return self.MVT_N_AUTORISE
|
2014-12-12 19:49:58 +01:00
|
|
|
else:
|
|
|
|
if y2 == y1 + 1:
|
2014-12-12 21:11:22 +01:00
|
|
|
return self.MVT_OK
|
2014-12-12 19:49:58 +01:00
|
|
|
elif y1 == 1 and y2 == 3 and self.grille[x1][2] == 0:
|
2014-12-12 21:11:22 +01:00
|
|
|
return self.MVT_OK
|
2014-12-12 19:49:58 +01:00
|
|
|
else:
|
2014-12-12 21:11:22 +01:00
|
|
|
return self.MVT_N_AUTORISE
|
2014-12-14 17:44:45 +01:00
|
|
|
elif abs(x1 - x2) == 1: # Saut
|
2014-12-12 19:49:58 +01:00
|
|
|
if self.joueur:
|
|
|
|
if y2 == y1 - 1 and \
|
2014-12-14 19:30:19 +01:00
|
|
|
self.ePieceNoire(self.grille[x2][y2]):
|
2014-12-12 21:11:22 +01:00
|
|
|
return self.MVT_OK
|
2014-12-12 19:49:58 +01:00
|
|
|
else:
|
2014-12-12 21:11:22 +01:00
|
|
|
return self.MVT_N_AUTORISE
|
2014-12-12 19:49:58 +01:00
|
|
|
else:
|
|
|
|
if y2 == y1 + 1 and \
|
2014-12-14 19:30:19 +01:00
|
|
|
self.ePieceBlanche(self.grille[x2][y2]):
|
2014-12-12 21:11:22 +01:00
|
|
|
return self.MVT_OK
|
2014-12-12 19:49:58 +01:00
|
|
|
else:
|
2014-12-12 21:11:22 +01:00
|
|
|
return self.MVT_N_AUTORISE
|
2014-12-12 19:49:58 +01:00
|
|
|
else:
|
2014-12-12 21:11:22 +01:00
|
|
|
return self.MVT_N_AUTORISE
|
2014-12-12 19:49:58 +01:00
|
|
|
|
2014-12-14 16:43:11 +01:00
|
|
|
def deplPossibleTour(self, x1, y1, x2, y2):
|
2014-12-14 00:47:49 +01:00
|
|
|
"""
|
|
|
|
Vérifie si le déplacement est possible pour une tour.
|
|
|
|
"""
|
2014-12-12 19:49:58 +01:00
|
|
|
if y1 == y2:
|
2014-12-14 17:44:45 +01:00
|
|
|
sens = (x2 - x1) // abs(x2 - x1)
|
|
|
|
for x in range(x1 + sens, x2, sens):
|
2014-12-12 21:11:22 +01:00
|
|
|
if self.ePiece(self.grille[x][y1]):
|
|
|
|
return self.MVT_OBSTRUCTION
|
2014-12-12 19:49:58 +01:00
|
|
|
elif x1 == x2:
|
2014-12-14 17:44:45 +01:00
|
|
|
sens = (y2 - y1) // abs(y2 - y1)
|
|
|
|
for y in range(y1 + sens, y2, sens):
|
2014-12-12 21:11:22 +01:00
|
|
|
if self.ePiece(self.grille[x1][y]):
|
|
|
|
return self.MVT_OBSTRUCTION
|
2014-12-12 19:49:58 +01:00
|
|
|
else:
|
2014-12-12 21:11:22 +01:00
|
|
|
return self.MVT_N_AUTORISE
|
|
|
|
return self.MVT_OK
|
2014-12-12 19:49:58 +01:00
|
|
|
|
2014-12-14 16:43:11 +01:00
|
|
|
def deplPossibleFou(self, x1, y1, x2, y2):
|
2014-12-14 00:47:49 +01:00
|
|
|
"""
|
|
|
|
Vérifie si le déplacement est possible pour un fou.
|
|
|
|
"""
|
2014-12-14 17:44:45 +01:00
|
|
|
if abs(x2 - x1) == abs(y2 - y1):
|
|
|
|
sensX = (x2 - x1) // abs(x2 - x1)
|
|
|
|
sensY = (y2 - y1) // abs(y2 - y1)
|
2014-12-12 19:49:58 +01:00
|
|
|
x = x1
|
|
|
|
y = y1
|
|
|
|
dist = 0
|
2014-12-14 17:44:45 +01:00
|
|
|
distTot = abs(x2 - x1)
|
2014-12-12 19:49:58 +01:00
|
|
|
while dist < distTot:
|
|
|
|
dist += 1
|
|
|
|
x += sensX
|
|
|
|
y += sensY
|
2014-12-12 21:11:22 +01:00
|
|
|
if self.ePiece(self.grille[x][y]):
|
2014-12-12 19:49:58 +01:00
|
|
|
if dist == distTot:
|
2014-12-14 17:44:45 +01:00
|
|
|
return self.MVT_OK # Saut
|
2014-12-12 19:49:58 +01:00
|
|
|
else:
|
2014-12-12 21:11:22 +01:00
|
|
|
return self.MVT_OBSTRUCTION
|
2014-12-14 17:44:45 +01:00
|
|
|
return self.MVT_OK # Vide
|
2014-12-12 19:49:58 +01:00
|
|
|
else:
|
2014-12-12 21:11:22 +01:00
|
|
|
return self.MVT_N_AUTORISE
|
2014-12-12 19:49:58 +01:00
|
|
|
|
2014-12-14 16:43:11 +01:00
|
|
|
def deplPossibleCavalier(self, x1, y1, x2, y2):
|
2014-12-14 00:47:49 +01:00
|
|
|
"""
|
|
|
|
Vérifie si le déplacement est possible pour un cavalier.
|
|
|
|
"""
|
2014-12-14 17:44:45 +01:00
|
|
|
if (abs(x2 - x1) == 2 and abs(y2 - y1) == 1) or (abs(y2 - y1) == 2 and abs(x2 - x1) == 1):
|
2014-12-12 21:11:22 +01:00
|
|
|
return self.MVT_OK
|
2014-12-12 19:49:58 +01:00
|
|
|
else:
|
2014-12-12 21:11:22 +01:00
|
|
|
return self.MVT_N_AUTORISE
|
2014-12-12 19:49:58 +01:00
|
|
|
|
2014-12-14 18:24:40 +01:00
|
|
|
# TODO Utiliser la gestion d'erreurs de Python ?
|
2014-12-14 17:44:45 +01:00
|
|
|
def deplPossible(self, x1, y1, x2, y2):
|
2014-12-14 00:47:49 +01:00
|
|
|
"""
|
|
|
|
Vérifie si le déplacement est possible.
|
|
|
|
"""
|
2014-12-14 16:43:11 +01:00
|
|
|
piece = self.grille[x1][y1]
|
|
|
|
if self.aSonTour(piece):
|
2014-12-14 17:44:45 +01:00
|
|
|
if x1 != x2 or y1 != y2:
|
2014-12-12 19:49:58 +01:00
|
|
|
if not self.aSonTour(self.grille[x2][y2]):
|
2014-12-14 16:43:11 +01:00
|
|
|
tPiece = self.tPiece(piece)
|
2014-12-14 17:44:45 +01:00
|
|
|
if tPiece == self.PCE_PION: # Pion
|
2014-12-14 16:43:11 +01:00
|
|
|
return self.deplPossiblePion(x1, y1, x2, y2)
|
2014-12-14 17:44:45 +01:00
|
|
|
elif tPiece == self.PCE_TOUR: # Tour
|
2014-12-14 16:43:11 +01:00
|
|
|
return self.deplPossibleTour(x1, y1, x2, y2)
|
|
|
|
elif tPiece == self.PCE_CAVALIER:
|
|
|
|
return self.deplPossibleCavalier(x1, y1, x2, y2)
|
|
|
|
elif tPiece == self.PCE_FOU:
|
|
|
|
return self.deplPossibleFou(x1, y1, x2, y2)
|
|
|
|
elif tPiece == self.PCE_DAME:
|
|
|
|
tour = self.deplPossibleTour(x1, y1, x2, y2)
|
|
|
|
fou = self.deplPossibleFou(x1, y1, x2, y2)
|
2014-12-12 21:11:22 +01:00
|
|
|
if tour == self.MVT_OK or fou == self.MVT_OK:
|
|
|
|
return self.MVT_OK
|
|
|
|
elif tour == self.MVT_OBSTRUCTION or fou == self.MVT_OBSTRUCTION:
|
|
|
|
return self.MVT_OBSTRUCTION
|
2014-12-12 19:49:58 +01:00
|
|
|
else:
|
2014-12-14 17:44:45 +01:00
|
|
|
return self.MVT_N_AUTORISE
|
2014-12-14 16:43:11 +01:00
|
|
|
elif tPiece == self.PCE_ROI:
|
2014-12-14 17:44:45 +01:00
|
|
|
if abs(x2 - x1) <= 1 and abs(y2 - y1) <= 1:
|
|
|
|
return self.MVT_OK
|
2014-12-12 19:49:58 +01:00
|
|
|
else:
|
2014-12-12 21:11:22 +01:00
|
|
|
return self.MVT_N_AUTORISE
|
2014-12-12 19:49:58 +01:00
|
|
|
else:
|
2014-12-14 16:43:11 +01:00
|
|
|
return self.MVT_PIECE_INC
|
2014-12-12 19:49:58 +01:00
|
|
|
else:
|
2014-12-12 21:11:22 +01:00
|
|
|
return self.MVT_SAUT_AMI
|
2014-12-12 19:49:58 +01:00
|
|
|
else:
|
2014-12-12 21:11:22 +01:00
|
|
|
return self.MVT_SUR_PLACE
|
2014-12-12 19:49:58 +01:00
|
|
|
else:
|
2014-12-12 21:11:22 +01:00
|
|
|
return self.MVT_SELECTION
|
|
|
|
return self.MVT_INCONNU
|
2014-12-14 17:44:45 +01:00
|
|
|
|
2014-12-12 19:49:58 +01:00
|
|
|
def mvtPossible(self, x1, y1, x2, y2):
|
2014-12-14 00:47:49 +01:00
|
|
|
"""
|
|
|
|
Vérifie si le mouvement est possible.
|
|
|
|
Contrairement aux fonctions de vérification de déplacement, celle-ci
|
2014-12-14 17:44:45 +01:00
|
|
|
vérifie si le mouvement est réalisable si le roi est en échec.
|
2014-12-14 00:47:49 +01:00
|
|
|
"""
|
2014-12-14 16:43:11 +01:00
|
|
|
test = self.deplPossible(x1, y1, x2, y2)
|
2014-12-12 21:11:22 +01:00
|
|
|
if test == self.MVT_OK:
|
2014-12-14 17:44:45 +01:00
|
|
|
# On copie la partie actuelle pour tester le mouvement et vérifier
|
|
|
|
# l'échec
|
|
|
|
copie = copy.deepcopy(self)
|
2014-12-14 16:43:11 +01:00
|
|
|
copie.dPieceSansEchec(x1, y1, x2, y2)
|
2014-12-12 19:49:58 +01:00
|
|
|
mvtsPossiblesTousAdverses = []
|
2014-12-14 00:47:49 +01:00
|
|
|
# On cherche la position du roi
|
2014-12-14 17:44:45 +01:00
|
|
|
pieceRoi = self.PCE_ROI + \
|
|
|
|
self.DECALAGE_BLANCS if self.joueur else self.DECALAGE_NOIRS
|
2014-12-12 19:49:58 +01:00
|
|
|
roi = [-1, -1]
|
2014-12-12 21:11:22 +01:00
|
|
|
for x in range(0, self.CASES_COTE):
|
|
|
|
for y in range(0, self.CASES_COTE):
|
2014-12-14 19:30:19 +01:00
|
|
|
mvtsPossiblesTousAdverses += copie.deplsPossibles(
|
2014-12-14 17:44:45 +01:00
|
|
|
x, y)
|
2014-12-14 16:43:11 +01:00
|
|
|
if copie.grille[x][y] == pieceRoi:
|
2014-12-12 19:49:58 +01:00
|
|
|
roi = [x, y]
|
2014-12-14 17:44:45 +01:00
|
|
|
# Si le roi peut être sauté au tour adverse
|
|
|
|
if roi in mvtsPossiblesTousAdverses:
|
2014-12-12 21:11:22 +01:00
|
|
|
return self.MVT_ECHEC
|
2014-12-12 19:49:58 +01:00
|
|
|
else:
|
|
|
|
return test
|
|
|
|
else:
|
|
|
|
return test
|
2014-12-14 17:44:45 +01:00
|
|
|
|
2014-12-14 19:30:19 +01:00
|
|
|
def deplsPossibles(self, x1, y1):
|
2014-12-14 00:47:49 +01:00
|
|
|
"""
|
|
|
|
Donne la liste des déplacements possible pour la pièce donnée.
|
|
|
|
"""
|
2014-12-12 19:49:58 +01:00
|
|
|
tableau = []
|
2014-12-12 21:11:22 +01:00
|
|
|
for x2 in range(0, self.CASES_COTE):
|
|
|
|
for y2 in range(0, self.CASES_COTE):
|
2014-12-14 16:43:11 +01:00
|
|
|
if self.deplPossible(x1, y1, x2, y2) == self.MVT_OK:
|
2014-12-12 19:49:58 +01:00
|
|
|
tableau.append([x2, y2])
|
|
|
|
return tableau
|
|
|
|
|
|
|
|
def mvtsPossibles(self, x1, y1):
|
2014-12-14 00:47:49 +01:00
|
|
|
"""
|
|
|
|
Donne la liste des mouvements possible pour la pièce donnée.
|
|
|
|
"""
|
2014-12-12 19:49:58 +01:00
|
|
|
tableau = []
|
2014-12-12 21:11:22 +01:00
|
|
|
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:
|
2014-12-12 19:49:58 +01:00
|
|
|
tableau.append([x2, y2])
|
|
|
|
return tableau
|
|
|
|
|
2014-12-14 16:43:11 +01:00
|
|
|
def dPieceSansEchec(self, x1, y1, x2, y2):
|
2014-12-14 00:47:49 +01:00
|
|
|
"""
|
2014-12-14 16:43:11 +01:00
|
|
|
Déplace la pièce aux coordonnées 1 données aux coordonnées 2 données.
|
2014-12-14 00:47:49 +01:00
|
|
|
Ne vérifie pas si le mouvement peut conduire à une prise illégale du roi.
|
|
|
|
(Est utilisé dans pour cette détection)
|
|
|
|
"""
|
2014-12-14 16:43:11 +01:00
|
|
|
test = self.deplPossible(x1, y1, x2, y2)
|
2014-12-12 21:11:22 +01:00
|
|
|
if test == self.MVT_OK:
|
2014-12-14 17:44:45 +01:00
|
|
|
self.grille[x1][y1], self.grille[x2][
|
|
|
|
y2] = self.PCE_VIDE, self.grille[x1][y1]
|
2014-12-12 19:49:58 +01:00
|
|
|
self.joueur = not self.joueur
|
|
|
|
|
|
|
|
def vEchecMat(self):
|
|
|
|
"""
|
2014-12-14 00:47:49 +01:00
|
|
|
Vérifie si le joueur actuel est en échec et mat et déclenche
|
|
|
|
éventuellement la victoire
|
|
|
|
(Le "pat" est considiéré comme une victoire)
|
2014-12-12 19:49:58 +01:00
|
|
|
"""
|
2014-12-14 00:47:49 +01:00
|
|
|
# Vérifications si aucun mouvement pour aucune pièce n'est possible
|
2014-12-12 21:11:22 +01:00
|
|
|
for x in range(0, self.CASES_COTE):
|
|
|
|
for y in range(0, self.CASES_COTE):
|
2014-12-12 19:49:58 +01:00
|
|
|
if len(self.mvtsPossibles(x, y)) > 0:
|
|
|
|
return False
|
|
|
|
self.partieFinie = True
|
|
|
|
self.victorieux = not self.joueur
|
|
|
|
return True
|
|
|
|
|
2014-12-14 16:43:11 +01:00
|
|
|
def dPiece(self, x1, y1, x2, y2):
|
2014-12-14 00:47:49 +01:00
|
|
|
"""
|
2014-12-14 16:43:11 +01:00
|
|
|
Déplace la pièce aux coordonnées 1 données aux coordonnées 2 données.
|
2014-12-14 00:47:49 +01:00
|
|
|
Renvoie les détails du mouvement.
|
|
|
|
"""
|
2014-12-12 19:49:58 +01:00
|
|
|
test = self.mvtPossible(x1, y1, x2, y2)
|
|
|
|
retour = {
|
|
|
|
'valide': False,
|
|
|
|
'message': test,
|
2014-12-14 23:20:52 +01:00
|
|
|
'ajouter': [], # Pièces à ajouter
|
2014-12-14 17:44:45 +01:00
|
|
|
'deplacer': [], # Pièces à déplacer
|
|
|
|
'supprimer': [], # Pièces à supprimer
|
2014-12-12 19:49:58 +01:00
|
|
|
}
|
2014-12-12 21:11:22 +01:00
|
|
|
if test == self.MVT_OK:
|
2014-12-12 19:49:58 +01:00
|
|
|
retour['valide'] = True
|
2014-12-12 21:11:22 +01:00
|
|
|
if self.ePiece(self.grille[x2][y2]):
|
2014-12-12 19:49:58 +01:00
|
|
|
retour['supprimer'].append([x2, y2])
|
|
|
|
retour['deplacer'].append([x1, y1, x2, y2])
|
2014-12-14 17:44:45 +01:00
|
|
|
self.grille[x1][y1], self.grille[x2][
|
|
|
|
y2] = self.PCE_VIDE, self.grille[x1][y1]
|
2014-12-12 19:49:58 +01:00
|
|
|
self.joueur = not self.joueur
|
|
|
|
self.vEchecMat()
|
2014-12-13 23:04:54 +01:00
|
|
|
return retour
|