Séparation en différents fichiers
- Il faut désormais lancer app.py - Nettoyage des fichiers inutiles
This commit is contained in:
parent
f0959596df
commit
246f65993e
|
@ -8,8 +8,9 @@ Jeu d'Échec programmé dans le cadre d'un TP alternatif pour l'enseignement Inf
|
|||
* tk
|
||||
|
||||
##Lancement
|
||||
Dans le dossier racine du projet :
|
||||
```bash
|
||||
python echecs.py
|
||||
python app.py
|
||||
```
|
||||
|
||||
(en supposant que `python` est dans la variable d'environnement `path` (ou `$PATH` sous Windows) et point vers l'éxecutable de Python 3)
|
||||
|
|
5
S1/Echecs/app.py
Normal file
5
S1/Echecs/app.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
from logique import LogiqueEchecs
|
||||
from guiTk import PlateauTk
|
||||
|
||||
p = PlateauTk(LogiqueEchecs())
|
||||
|
|
@ -1,559 +0,0 @@
|
|||
import copy
|
||||
|
||||
CASES_COTE = 8
|
||||
|
||||
MVT_INCONNU = 'Cause inconnue'
|
||||
MVT_OK = 'Valide'
|
||||
MVT_ROQUE = 'Roque'
|
||||
MVT_SELECTION = 'Mauvais tour'
|
||||
MVT_SUR_PLACE = 'Immobile'
|
||||
MVT_SAUT_AMI = 'Saut ami'
|
||||
MVT_PION_INC = 'Pion inconnu'
|
||||
MVT_N_AUTORISE = 'Non-autorisé'
|
||||
MVT_OBSTRUCTION = 'Pion en chemin'
|
||||
MVT_ECHEC = 'Échec au roi'
|
||||
|
||||
class LogiqueEchecs:
|
||||
|
||||
def __init__(self):
|
||||
self.grille = []
|
||||
self.cGrille()
|
||||
self.remplirGrille()
|
||||
self.joueur = True
|
||||
self.partieFinie = False
|
||||
self.victorieux = None
|
||||
|
||||
@staticmethod
|
||||
def eNoir(xD, yD):
|
||||
return xD % 2 != yD % 2
|
||||
|
||||
def cGrille(self):
|
||||
for x in range(CASES_COTE):
|
||||
colonne = []
|
||||
for y in range(CASES_COTE):
|
||||
colonne.append(0)
|
||||
self.grille.append(colonne)
|
||||
|
||||
def remplirGrille(self):
|
||||
speciales = [2, 3, 4, 6, 5, 4, 3, 2]
|
||||
for i in range(0, 8):
|
||||
self.grille[i][0] = speciales[i] + 10
|
||||
self.grille[i][1] = 11
|
||||
self.grille[i][6] = 1
|
||||
self.grille[i][7] = speciales[i]
|
||||
|
||||
def cPion(self, x, y, piece):
|
||||
"""
|
||||
"""
|
||||
self.grille[x][y] = piece
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def ePionBlanc(pion):
|
||||
return pion in range(1, 7)
|
||||
|
||||
@staticmethod
|
||||
def ePionNoir(pion):
|
||||
return pion in range(11, 17)
|
||||
|
||||
|
||||
def aSonTour(self, pion):
|
||||
return (self.ePionNoir(pion) and self.joueur == False) or \
|
||||
(self.ePionBlanc(pion) and self.joueur == True)
|
||||
|
||||
def mvtPossibleSansEchecPion(self, x1, y1, x2, y2):
|
||||
if x1 == x2 and self.grille[x2][y2] <= 0: # Avance
|
||||
if self.joueur:
|
||||
if y2 == y1 - 1:
|
||||
return MVT_OK
|
||||
elif y1 == 6 and y2 == 4 and self.grille[x1][5] == 0:
|
||||
return MVT_OK
|
||||
else:
|
||||
return MVT_N_AUTORISE
|
||||
else:
|
||||
if y2 == y1 + 1:
|
||||
return MVT_OK
|
||||
elif y1 == 1 and y2 == 3 and self.grille[x1][2] == 0:
|
||||
return MVT_OK
|
||||
else:
|
||||
return MVT_N_AUTORISE
|
||||
elif abs(x1-x2) == 1: # Saut
|
||||
if self.joueur:
|
||||
if y2 == y1 - 1 and \
|
||||
self.ePionNoir(self.grille[x2][y2]):
|
||||
return MVT_OK
|
||||
else:
|
||||
return MVT_N_AUTORISE
|
||||
else:
|
||||
if y2 == y1 + 1 and \
|
||||
self.ePionBlanc(self.grille[x2][y2]):
|
||||
return MVT_OK
|
||||
else:
|
||||
return MVT_N_AUTORISE
|
||||
else:
|
||||
return MVT_N_AUTORISE
|
||||
|
||||
def mvtPossibleSansEchecTour(self, x1, y1, x2, y2):
|
||||
if y1 == y2:
|
||||
sens = (x2-x1)//abs(x2-x1)
|
||||
for x in range(x1+sens, x2, sens):
|
||||
if self.grille[x][y1] > 0:
|
||||
return MVT_OBSTRUCTION
|
||||
elif x1 == x2:
|
||||
sens = (y2-y1)//abs(y2-y1)
|
||||
for y in range(y1+sens, y2, sens):
|
||||
if self.grille[x1][y] > 0:
|
||||
return MVT_OBSTRUCTION
|
||||
else:
|
||||
return MVT_N_AUTORISE
|
||||
return MVT_OK
|
||||
|
||||
def mvtPossibleSansEchecFou(self, x1, y1, x2, y2):
|
||||
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.grille[x][y] > 0:
|
||||
if dist == distTot:
|
||||
return MVT_OK # Saut
|
||||
else:
|
||||
return MVT_OBSTRUCTION
|
||||
return MVT_OK # Vide
|
||||
else:
|
||||
return MVT_N_AUTORISE
|
||||
|
||||
def mvtPossibleSansEchecCavalier(self, x1, y1, x2, y2):
|
||||
if (abs(x2-x1) == 2 and abs(y2-y1) == 1) or (abs(y2-y1) == 2 and abs(x2-x1) == 1):
|
||||
return MVT_OK
|
||||
else:
|
||||
return MVT_N_AUTORISE
|
||||
|
||||
def mvtPossibleSansEchec(self, x1, y1, x2, y2):
|
||||
pion = self.grille[x1][y1]
|
||||
if self.aSonTour(pion):
|
||||
if (x1 != x2 or y1 != y2):
|
||||
if not self.aSonTour(self.grille[x2][y2]):
|
||||
tPion = pion % 10
|
||||
if tPion == 1: # Pion
|
||||
return self.mvtPossibleSansEchecPion(x1, y1, x2, y2)
|
||||
elif tPion == 2: # Tour
|
||||
return self.mvtPossibleSansEchecTour(x1, y1, x2, y2)
|
||||
elif tPion == 3: # Cavalier
|
||||
return self.mvtPossibleSansEchecCavalier(x1, y1, x2, y2)
|
||||
elif tPion == 4: # Fou
|
||||
return self.mvtPossibleSansEchecFou(x1, y1, x2, y2)
|
||||
elif tPion == 5: # Dame
|
||||
tour = self.mvtPossibleSansEchecTour(x1, y1, x2, y2)
|
||||
fou = self.mvtPossibleSansEchecFou(x1, y1, x2, y2)
|
||||
if tour == MVT_OK or fou == MVT_OK:
|
||||
return MVT_OK
|
||||
elif tour == MVT_OBSTRUCTION or fou == MVT_OBSTRUCTION:
|
||||
return MVT_OBSTRUCTION
|
||||
else:
|
||||
return MVT_N_AUTORISE
|
||||
elif tPion == 6: # Roi
|
||||
if abs(x2-x1) <= 1 and abs(y2-y1) <= 1:
|
||||
return MVT_OK
|
||||
else:
|
||||
return MVT_N_AUTORISE
|
||||
else:
|
||||
return MVT_PION_INC
|
||||
else:
|
||||
return MVT_SAUT_AMI
|
||||
else:
|
||||
return MVT_SUR_PLACE
|
||||
else:
|
||||
return MVT_SELECTION
|
||||
return MVT_INCONNU
|
||||
|
||||
def mvtPossible(self, x1, y1, x2, y2):
|
||||
test = self.mvtPossibleSansEchec(x1, y1, x2, y2)
|
||||
if test == MVT_OK:
|
||||
# On copie la partie actuelle pour tester le mouvement et vérifier l'échec
|
||||
copie = copy.deepcopy(self);
|
||||
copie.dPionSansEchec(x1, y1, x2, y2)
|
||||
mvtsPossiblesTousAdverses = []
|
||||
pionRoi = 6
|
||||
if not self.joueur:
|
||||
pionRoi += 10
|
||||
roi = [-1, -1]
|
||||
for x in range(0, CASES_COTE):
|
||||
for y in range(0, CASES_COTE):
|
||||
mvtsPossiblesTousAdverses += copie.mvtsPossiblesSansEchec(x, y)
|
||||
if copie.grille[x][y] == pionRoi:
|
||||
roi = [x, y]
|
||||
if roi in mvtsPossiblesTousAdverses:
|
||||
return MVT_ECHEC
|
||||
else:
|
||||
return test
|
||||
else:
|
||||
return test
|
||||
|
||||
def mvtsPossiblesSansEchec(self, x1, y1):
|
||||
tableau = []
|
||||
for x2 in range(0, CASES_COTE):
|
||||
for y2 in range(0, CASES_COTE):
|
||||
if self.mvtPossibleSansEchec(x1, y1, x2, y2) == MVT_OK:
|
||||
tableau.append([x2, y2])
|
||||
return tableau
|
||||
|
||||
def mvtsPossibles(self, x1, y1):
|
||||
tableau = []
|
||||
for x2 in range(0, CASES_COTE):
|
||||
for y2 in range(0, CASES_COTE):
|
||||
if self.mvtPossible(x1, y1, x2, y2) == MVT_OK:
|
||||
tableau.append([x2, y2])
|
||||
return tableau
|
||||
|
||||
def dPionSansEchec(self, x1, y1, x2, y2):
|
||||
test = self.mvtPossibleSansEchec(x1, y1, x2, y2)
|
||||
if test == MVT_OK:
|
||||
self.grille[x1][y1], self.grille[x2][y2] = 0, self.grille[x1][y1]
|
||||
self.joueur = not self.joueur
|
||||
|
||||
def vEchecMat(self):
|
||||
"""
|
||||
Vérifie si le joueur actuel est en échec et mat et prend les mesures nécessiares.
|
||||
(CÀD Le joueur actuel ne peut effectuer aucun mouvement)
|
||||
"""
|
||||
for x in range(0, CASES_COTE):
|
||||
for y in range(0, CASES_COTE):
|
||||
if len(self.mvtsPossibles(x, y)) > 0:
|
||||
return False
|
||||
self.partieFinie = True
|
||||
self.victorieux = not self.joueur
|
||||
return True
|
||||
|
||||
def dPion(self, x1, y1, x2, y2):
|
||||
test = self.mvtPossible(x1, y1, x2, y2)
|
||||
retour = {
|
||||
'valide': False,
|
||||
'message': test,
|
||||
'deplacer': [], # Pions à déplacer
|
||||
'supprimer': [], # Pions à supprimer
|
||||
}
|
||||
if test == MVT_OK:
|
||||
retour['valide'] = True
|
||||
if self.grille[x2][y2] > 0:
|
||||
retour['supprimer'].append([x2, y2])
|
||||
retour['deplacer'].append([x1, y1, x2, y2])
|
||||
self.grille[x1][y1], self.grille[x2][y2] = 0, self.grille[x1][y1]
|
||||
self.joueur = not self.joueur
|
||||
self.vEchecMat()
|
||||
return retour
|
||||
|
||||
# GUI
|
||||
|
||||
from tkinter import *
|
||||
|
||||
DECX = 0
|
||||
DECY = 0
|
||||
COTE_CASE = 50
|
||||
MARGE_PIONS = 5
|
||||
TEMPS_ANIM = 200
|
||||
INTER_ANIM = 10
|
||||
|
||||
class PlateauTk:
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.fen = None
|
||||
self.can = None
|
||||
self.chaine = None
|
||||
self.grilleDamier = []
|
||||
self.imagesOriginales = []
|
||||
self.imagesRedim = []
|
||||
self.photos = []
|
||||
self.grillePions = []
|
||||
self.animations = []
|
||||
|
||||
self.dEtape = True
|
||||
self.dx1 = -1
|
||||
self.dy1 = -1
|
||||
self.dx2 = -1
|
||||
self.dy2 = -1
|
||||
self.mvtsPossibles = []
|
||||
self.logique = LogiqueEchecs()
|
||||
|
||||
self.creerFen()
|
||||
self.importerImages()
|
||||
self.redimImages()
|
||||
|
||||
self.cDamier()
|
||||
self.cGrille()
|
||||
self.remplirGrille(self.logique.grille)
|
||||
|
||||
def creerFen(self):
|
||||
self.fen = Tk()
|
||||
self.fen.title("Jeu d'Échecs")
|
||||
self.can = Canvas(self.fen, width=COTE_CASE * CASES_COTE,
|
||||
height=COTE_CASE * CASES_COTE, bg="ivory")
|
||||
self.can.grid(row=0, column=1, columnspan=3)
|
||||
self.can.bind('<Button-1>', self.clic)
|
||||
self.chaine = Label(self.fen, text="Aux blancs")
|
||||
self.chaine.grid(row=2, column=2, padx=3, pady=3)
|
||||
# Button(self.fen, text="Nv. Partie", command=f_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):
|
||||
self.chaine.config(text=texte)
|
||||
# TODO Timeout effacer si parametre / Liste
|
||||
|
||||
def importerImages(self):
|
||||
for piece in range(0, 21):
|
||||
nom = 'sprites/'
|
||||
if piece % 10 == 1:
|
||||
nom += 'pion'
|
||||
elif piece % 10 == 2:
|
||||
nom += 'tour'
|
||||
elif piece % 10 == 3:
|
||||
nom += 'cavalier'
|
||||
elif piece % 10 == 4:
|
||||
nom += 'fou'
|
||||
elif piece % 10 == 5:
|
||||
nom += 'dame'
|
||||
elif piece % 10 == 6:
|
||||
nom += 'roi'
|
||||
else:
|
||||
self.imagesOriginales.append('')
|
||||
continue
|
||||
if piece < 10:
|
||||
nom += 'B'
|
||||
else:
|
||||
nom += 'N'
|
||||
nom += '.gif'
|
||||
self.imagesOriginales.append(PhotoImage(file=nom))
|
||||
|
||||
def redimImages(self):
|
||||
sample = int(504 / (COTE_CASE - MARGE_PIONS))
|
||||
for piece in range(0, 21):
|
||||
if self.imagesOriginales[piece] != '':
|
||||
self.imagesRedim.append(self.imagesOriginales[piece].
|
||||
subsample(sample))
|
||||
else:
|
||||
self.imagesRedim.append('')
|
||||
|
||||
# Dessin
|
||||
@staticmethod
|
||||
def caseCouleur(blanc, contexte):
|
||||
if contexte == 1: # Sélectionné
|
||||
return '#a0cefe' if blanc else '#478bd1'
|
||||
elif contexte == 2: # Possible
|
||||
return '#bafea0' if blanc else '#6ed147'
|
||||
elif contexte == 3: # Impossible
|
||||
return '#fea0ab' if blanc else '#d14758'
|
||||
else: # Normal
|
||||
return '#ffce9e' if blanc else '#d18b47'
|
||||
|
||||
def cCase(self, x, y):
|
||||
couleur = self.caseCouleur(not LogiqueEchecs.eNoir(x, y), 0)
|
||||
return self.can.create_rectangle(x * COTE_CASE, y * COTE_CASE, (x + 1) * COTE_CASE, (y + 1) * COTE_CASE)
|
||||
|
||||
def coulCase(self, x, y, contexte):
|
||||
couleur = self.caseCouleur(not self.logique.eNoir(x, y), contexte)
|
||||
self.can.itemconfig(self.grilleDamier[x][y], fill=couleur, outline=couleur)
|
||||
|
||||
def coulDamier(self):
|
||||
for x in range(0, CASES_COTE):
|
||||
for y in range(0, CASES_COTE):
|
||||
self.coulCase(x, y, 0)
|
||||
|
||||
def cDamier(self):
|
||||
self.grilleDamier = []
|
||||
for x in range(0, CASES_COTE):
|
||||
colonne = []
|
||||
for y in range(0, CASES_COTE):
|
||||
colonne.append(self.cCase(x + DECX, y + DECY))
|
||||
self.grilleDamier.append(colonne)
|
||||
self.coulDamier()
|
||||
|
||||
def cPion(self, x, y, piece):
|
||||
if piece > 0:
|
||||
self.grillePions[x][y] = self.can.create_image((x + .5) * COTE_CASE,
|
||||
(y + .5) * COTE_CASE, image=self.imagesRedim[piece])
|
||||
else:
|
||||
self.grillePions[x][y] = False
|
||||
|
||||
def cGrille(self):
|
||||
self.grillePions = []
|
||||
for x in range(0, CASES_COTE): # Crée self.grillePions
|
||||
colonne = []
|
||||
for y in range(0, CASES_COTE):
|
||||
colonne.append(False)
|
||||
self.grillePions.append(colonne)
|
||||
|
||||
def remplirGrille(self, j_grilleF):
|
||||
for x in range(0, CASES_COTE): # Remplis self.grillePions
|
||||
for y in range(0, CASES_COTE):
|
||||
self.cPion(x, y, j_grilleF[x][y])
|
||||
|
||||
# Interaction
|
||||
@staticmethod
|
||||
def nomJoueur(joueur, pluriel=True):
|
||||
if joueur:
|
||||
nom = 'blanc'
|
||||
else:
|
||||
nom = 'noir'
|
||||
if pluriel:
|
||||
nom += 's'
|
||||
return nom
|
||||
|
||||
def statutPrendre(self):
|
||||
self.statut('Prendre (' + self.nomJoueur(self.logique.joueur) + ')')
|
||||
|
||||
@staticmethod
|
||||
def animationDCoords(i):
|
||||
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):
|
||||
animationsNv = []
|
||||
for i in self.animations:
|
||||
if i['avancement'] < i['total']:
|
||||
if i['type'] == 'd':
|
||||
coords = self.animationDCoords(i)
|
||||
self.can.coords(i['pion'], coords[0], coords[1])
|
||||
# elif i['type'] == 'f':
|
||||
# TODO Opacité de i['pion']
|
||||
# elif i['type'] == 'c':
|
||||
# TODO Opacité de case
|
||||
i['avancement'] += INTER_ANIM
|
||||
animationsNv.append(i)
|
||||
else:
|
||||
if i['type'] == 'd':
|
||||
self.can.coords(i['pion'], i['x2'], i['y2'])
|
||||
elif i['type'] == 'f':
|
||||
self.can.delete(i['pion'])
|
||||
elif i['type'] == 'c':
|
||||
self.coulCase(i['x'], i['y'], 0)
|
||||
self.animations = animationsNv
|
||||
if len(animationsNv):
|
||||
self.fen.after(INTER_ANIM, self.animation)
|
||||
|
||||
def animer(self, animation):
|
||||
etaitVide = len(self.animations) < 1
|
||||
self.animations.append(animation)
|
||||
if etaitVide:
|
||||
self.animation()
|
||||
|
||||
def animerD(self, x1, y1, x2, y2, pion):
|
||||
if len(self.animations):
|
||||
for i in self.animations:
|
||||
if i['pion'] == pion: # Si une animation pour ce pion existe
|
||||
# déjà, on la reprend et on la modifie
|
||||
coords = self.animationDCoords(i)
|
||||
i['x1'] = coords[0]
|
||||
i['y1'] = coords[1]
|
||||
i['x2'] = x2
|
||||
i['y2'] = y2
|
||||
# i['total'] = i['total'] - i['avancement']
|
||||
i['total'] = TEMPS_ANIM
|
||||
i['avancement'] = 0
|
||||
return
|
||||
|
||||
animation = {
|
||||
'x1': x1,
|
||||
'y1': y1,
|
||||
'x2': x2,
|
||||
'y2': y2,
|
||||
'pion': pion,
|
||||
'type': 'd',
|
||||
'total': TEMPS_ANIM,
|
||||
'avancement': 0
|
||||
}
|
||||
self.can.tag_raise(pion) # Mise au premier plan
|
||||
self.animer(animation)
|
||||
|
||||
def animerF(self, pion): # Pion fade-out
|
||||
animation = {
|
||||
'pion': pion,
|
||||
'type': 'f',
|
||||
'total': TEMPS_ANIM,
|
||||
'avancement': 0
|
||||
}
|
||||
self.animer(animation)
|
||||
|
||||
def animerC(self, x ,y):
|
||||
animation = {
|
||||
'type': 'c',
|
||||
'x': x,
|
||||
'y': y,
|
||||
'total': TEMPS_ANIM,
|
||||
'avancement': 0
|
||||
}
|
||||
self.animer(animation)
|
||||
|
||||
def victoire(self):
|
||||
self.statut('Victoire des ' + self.nomJoueur(self.logique.victorieux) + ' !')
|
||||
self.coulDamier()
|
||||
for x in range(0, CASES_COTE):
|
||||
for y in range(0, CASES_COTE):
|
||||
pion = self.logique.grille[x][y]
|
||||
if pion > 0:
|
||||
if self.logique.ePionNoir(pion) ^ self.logique.victorieux:
|
||||
self.coulCase(x, y, 2)
|
||||
else:
|
||||
self.coulCase(x, y, 3)
|
||||
|
||||
def dPion(self, x1, y1, x2, y2):
|
||||
test = self.logique.dPion(x1, y1, x2, y2)
|
||||
if test['valide'] == True: # Si déplacement possible
|
||||
for s in test['supprimer']:
|
||||
self.animerF(self.grillePions[s[0]][s[1]])
|
||||
for d in test['deplacer']:
|
||||
self.grillePions[d[2]][d[3]], self.grillePions[d[0]][d[1]] = \
|
||||
self.grillePions[d[0]][d[1]], False
|
||||
self.animerD((d[0] + .5) * COTE_CASE, (d[1] + .5) * COTE_CASE, \
|
||||
(d[2] + .5) * COTE_CASE, (d[3] + .5) * COTE_CASE, \
|
||||
self.grillePions[d[2]][d[3]])
|
||||
|
||||
else:
|
||||
self.statut('Déplacment impossible ! (' + test['message'] + ')')
|
||||
return test['valide']
|
||||
|
||||
def dClic(self, x, y):
|
||||
if not self.logique.partieFinie:
|
||||
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.coulCase(i[0], i[1], 2)
|
||||
self.statut('Poser')
|
||||
self.dEtape = not self.dEtape
|
||||
else: # Si pas pssible jouer
|
||||
self.coulCase(self.dx1, self.dy1, 3)
|
||||
self.animerC(self.dx1, self.dy1)
|
||||
else: # Poser
|
||||
self.dx2, self.dy2 = x, y
|
||||
if self.dPion(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
|
||||
self.dEtape = not self.dEtape
|
||||
if self.logique.partieFinie:
|
||||
self.victoire()
|
||||
else:
|
||||
self.statutPrendre()
|
||||
else: # Si mauvais déplacement
|
||||
self.coulCase(self.dx2, self.dy2, 3)
|
||||
self.animerC(self.dx2, self.dy2)
|
||||
|
||||
def clic(self, event):
|
||||
x = event.x // COTE_CASE
|
||||
y = event.y // COTE_CASE
|
||||
self.dClic(x, y)
|
||||
|
||||
p = PlateauTk()
|
||||
|
||||
# TODO Un jeu (canvas) et un frontend (fenetre)
|
307
S1/Echecs/guiTk.py
Normal file
307
S1/Echecs/guiTk.py
Normal file
|
@ -0,0 +1,307 @@
|
|||
from tkinter import *
|
||||
|
||||
class PlateauTk:
|
||||
|
||||
DECX = 0
|
||||
DECY = 0
|
||||
COTE_CASE = 50
|
||||
MARGE_PIONS = 5
|
||||
TEMPS_ANIM = 200
|
||||
INTER_ANIM = 10
|
||||
|
||||
def __init__(self, logique):
|
||||
|
||||
self.fen = None
|
||||
self.can = None
|
||||
self.chaine = None
|
||||
self.grilleDamier = []
|
||||
self.imagesOriginales = []
|
||||
self.imagesRedim = []
|
||||
self.photos = []
|
||||
self.grillePions = []
|
||||
self.animations = []
|
||||
|
||||
self.dEtape = True
|
||||
self.dx1 = -1
|
||||
self.dy1 = -1
|
||||
self.dx2 = -1
|
||||
self.dy2 = -1
|
||||
self.mvtsPossibles = []
|
||||
self.logique = logique
|
||||
|
||||
self.creerFen()
|
||||
self.importerImages()
|
||||
self.redimImages()
|
||||
|
||||
self.cDamier()
|
||||
self.cGrille()
|
||||
self.remplirGrille(self.logique.grille)
|
||||
|
||||
self.fen.mainloop()
|
||||
|
||||
def creerFen(self):
|
||||
self.fen = Tk()
|
||||
self.fen.title("Jeu d'Échecs")
|
||||
self.can = Canvas(self.fen, width=PlateauTk.COTE_CASE * self.logique.CASES_COTE,
|
||||
height=PlateauTk.COTE_CASE * self.logique.CASES_COTE, bg="ivory")
|
||||
self.can.grid(row=0, column=1, columnspan=3)
|
||||
self.can.bind('<Button-1>', self.clic)
|
||||
self.chaine = Label(self.fen, text="Aux blancs")
|
||||
self.chaine.grid(row=2, column=2, padx=3, pady=3)
|
||||
# Button(self.fen, text="Nv. Partie", command=f_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):
|
||||
self.chaine.config(text=texte)
|
||||
# TODO Timeout effacer si parametre / Liste
|
||||
|
||||
def importerImages(self):
|
||||
for piece in range(0, 21):
|
||||
nom = 'sprites/'
|
||||
if piece % 10 == 1:
|
||||
nom += 'pion'
|
||||
elif piece % 10 == 2:
|
||||
nom += 'tour'
|
||||
elif piece % 10 == 3:
|
||||
nom += 'cavalier'
|
||||
elif piece % 10 == 4:
|
||||
nom += 'fou'
|
||||
elif piece % 10 == 5:
|
||||
nom += 'dame'
|
||||
elif piece % 10 == 6:
|
||||
nom += 'roi'
|
||||
else:
|
||||
self.imagesOriginales.append('')
|
||||
continue
|
||||
if piece < 10:
|
||||
nom += 'B'
|
||||
else:
|
||||
nom += 'N'
|
||||
nom += '.gif'
|
||||
self.imagesOriginales.append(PhotoImage(file=nom))
|
||||
|
||||
def redimImages(self):
|
||||
sample = int(504 / (PlateauTk.COTE_CASE - PlateauTk.MARGE_PIONS))
|
||||
for piece in range(0, 21):
|
||||
if self.imagesOriginales[piece] != '':
|
||||
self.imagesRedim.append(self.imagesOriginales[piece].
|
||||
subsample(sample))
|
||||
else:
|
||||
self.imagesRedim.append('')
|
||||
|
||||
# Dessin
|
||||
@staticmethod
|
||||
def caseCouleur(blanc, contexte):
|
||||
if contexte == 1: # Sélectionné
|
||||
return '#a0cefe' if blanc else '#478bd1'
|
||||
elif contexte == 2: # Possible
|
||||
return '#bafea0' if blanc else '#6ed147'
|
||||
elif contexte == 3: # Impossible
|
||||
return '#fea0ab' if blanc else '#d14758'
|
||||
else: # Normal
|
||||
return '#ffce9e' if blanc else '#d18b47'
|
||||
|
||||
def cCase(self, x, y):
|
||||
couleur = self.caseCouleur(not self.logique.eNoir(x, y), 0)
|
||||
return self.can.create_rectangle(x * PlateauTk.COTE_CASE, y * PlateauTk.COTE_CASE, (x + 1) * PlateauTk.COTE_CASE, (y + 1) * PlateauTk.COTE_CASE)
|
||||
|
||||
def coulCase(self, x, y, contexte):
|
||||
couleur = self.caseCouleur(not self.logique.eNoir(x, y), contexte)
|
||||
self.can.itemconfig(self.grilleDamier[x][y], fill=couleur, outline=couleur)
|
||||
|
||||
def coulDamier(self):
|
||||
for x in range(0, self.logique.CASES_COTE):
|
||||
for y in range(0, self.logique.CASES_COTE):
|
||||
self.coulCase(x, y, 0)
|
||||
|
||||
def cDamier(self):
|
||||
self.grilleDamier = []
|
||||
for x in range(0, self.logique.CASES_COTE):
|
||||
colonne = []
|
||||
for y in range(0, self.logique.CASES_COTE):
|
||||
colonne.append(self.cCase(x + PlateauTk.DECX, y + PlateauTk.DECY))
|
||||
self.grilleDamier.append(colonne)
|
||||
self.coulDamier()
|
||||
|
||||
def cPion(self, x, y, piece):
|
||||
if piece > 0:
|
||||
self.grillePions[x][y] = self.can.create_image((x + .5) * PlateauTk.COTE_CASE,
|
||||
(y + .5) * PlateauTk.COTE_CASE, image=self.imagesRedim[piece])
|
||||
else:
|
||||
self.grillePions[x][y] = False
|
||||
|
||||
def cGrille(self):
|
||||
self.grillePions = []
|
||||
for x in range(0, self.logique.CASES_COTE): # Crée self.grillePions
|
||||
colonne = []
|
||||
for y in range(0, self.logique.CASES_COTE):
|
||||
colonne.append(False)
|
||||
self.grillePions.append(colonne)
|
||||
|
||||
def remplirGrille(self, j_grilleF):
|
||||
for x in range(0, self.logique.CASES_COTE): # Remplis self.grillePions
|
||||
for y in range(0, self.logique.CASES_COTE):
|
||||
self.cPion(x, y, j_grilleF[x][y])
|
||||
|
||||
# Interaction
|
||||
@staticmethod
|
||||
def nomJoueur(joueur, pluriel=True):
|
||||
if joueur:
|
||||
nom = 'blanc'
|
||||
else:
|
||||
nom = 'noir'
|
||||
if pluriel:
|
||||
nom += 's'
|
||||
return nom
|
||||
|
||||
def statutPrendre(self):
|
||||
self.statut('Prendre (' + self.nomJoueur(self.logique.joueur) + ')')
|
||||
|
||||
@staticmethod
|
||||
def animationDCoords(i):
|
||||
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):
|
||||
animationsNv = []
|
||||
for i in self.animations:
|
||||
if i['avancement'] < i['total']:
|
||||
if i['type'] == 'd':
|
||||
coords = self.animationDCoords(i)
|
||||
self.can.coords(i['pion'], coords[0], coords[1])
|
||||
# elif i['type'] == 'f':
|
||||
# TODO Opacité de i['pion']
|
||||
# elif i['type'] == 'c':
|
||||
# TODO Opacité de case
|
||||
i['avancement'] += PlateauTk.INTER_ANIM
|
||||
animationsNv.append(i)
|
||||
else:
|
||||
if i['type'] == 'd':
|
||||
self.can.coords(i['pion'], i['x2'], i['y2'])
|
||||
elif i['type'] == 'f':
|
||||
self.can.delete(i['pion'])
|
||||
elif i['type'] == 'c':
|
||||
self.coulCase(i['x'], i['y'], 0)
|
||||
self.animations = animationsNv
|
||||
if len(animationsNv):
|
||||
self.fen.after(PlateauTk.INTER_ANIM, self.animation)
|
||||
|
||||
def animer(self, animation):
|
||||
etaitVide = len(self.animations) < 1
|
||||
self.animations.append(animation)
|
||||
if etaitVide:
|
||||
self.animation()
|
||||
|
||||
def animerD(self, x1, y1, x2, y2, pion):
|
||||
if len(self.animations):
|
||||
for i in self.animations:
|
||||
if i['pion'] == pion: # Si une animation pour ce pion existe
|
||||
# déjà, on la reprend et on la modifie
|
||||
coords = self.animationDCoords(i)
|
||||
i['x1'] = coords[0]
|
||||
i['y1'] = coords[1]
|
||||
i['x2'] = x2
|
||||
i['y2'] = y2
|
||||
# i['total'] = i['total'] - i['avancement']
|
||||
i['total'] = PlateauTk.TEMPS_ANIM
|
||||
i['avancement'] = 0
|
||||
return
|
||||
|
||||
animation = {
|
||||
'x1': x1,
|
||||
'y1': y1,
|
||||
'x2': x2,
|
||||
'y2': y2,
|
||||
'pion': pion,
|
||||
'type': 'd',
|
||||
'total': PlateauTk.TEMPS_ANIM,
|
||||
'avancement': 0
|
||||
}
|
||||
self.can.tag_raise(pion) # Mise au premier plan
|
||||
self.animer(animation)
|
||||
|
||||
def animerF(self, pion): # Pion fade-out
|
||||
animation = {
|
||||
'pion': pion,
|
||||
'type': 'f',
|
||||
'total': PlateauTk.TEMPS_ANIM,
|
||||
'avancement': 0
|
||||
}
|
||||
self.animer(animation)
|
||||
|
||||
def animerC(self, x ,y):
|
||||
animation = {
|
||||
'type': 'c',
|
||||
'x': x,
|
||||
'y': y,
|
||||
'total': PlateauTk.TEMPS_ANIM,
|
||||
'avancement': 0
|
||||
}
|
||||
self.animer(animation)
|
||||
|
||||
def victoire(self):
|
||||
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):
|
||||
pion = self.logique.grille[x][y]
|
||||
if pion > 0:
|
||||
if self.logique.ePionNoir(pion) ^ self.logique.victorieux:
|
||||
self.coulCase(x, y, 2)
|
||||
else:
|
||||
self.coulCase(x, y, 3)
|
||||
|
||||
def dPion(self, x1, y1, x2, y2):
|
||||
test = self.logique.dPion(x1, y1, x2, y2)
|
||||
if test['valide'] == True: # Si déplacement possible
|
||||
for s in test['supprimer']:
|
||||
self.animerF(self.grillePions[s[0]][s[1]])
|
||||
for d in test['deplacer']:
|
||||
self.grillePions[d[2]][d[3]], self.grillePions[d[0]][d[1]] = \
|
||||
self.grillePions[d[0]][d[1]], False
|
||||
self.animerD((d[0] + .5) * PlateauTk.COTE_CASE, (d[1] + .5) * PlateauTk.COTE_CASE, \
|
||||
(d[2] + .5) * PlateauTk.COTE_CASE, (d[3] + .5) * PlateauTk.COTE_CASE, \
|
||||
self.grillePions[d[2]][d[3]])
|
||||
|
||||
else:
|
||||
self.statut('Déplacment impossible ! (' + test['message'] + ')')
|
||||
return test['valide']
|
||||
|
||||
def dClic(self, x, y):
|
||||
if not self.logique.partieFinie:
|
||||
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.coulCase(i[0], i[1], 2)
|
||||
self.statut('Poser')
|
||||
self.dEtape = not self.dEtape
|
||||
else: # Si pas pssible jouer
|
||||
self.coulCase(self.dx1, self.dy1, 3)
|
||||
self.animerC(self.dx1, self.dy1)
|
||||
else: # Poser
|
||||
self.dx2, self.dy2 = x, y
|
||||
if self.dPion(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
|
||||
self.dEtape = not self.dEtape
|
||||
if self.logique.partieFinie:
|
||||
self.victoire()
|
||||
else:
|
||||
self.statutPrendre()
|
||||
else: # Si mauvais déplacement
|
||||
self.coulCase(self.dx2, self.dy2, 3)
|
||||
self.animerC(self.dx2, self.dy2)
|
||||
|
||||
def clic(self, event):
|
||||
x = event.x // PlateauTk.COTE_CASE
|
||||
y = event.y // PlateauTk.COTE_CASE
|
||||
self.dClic(x, y)
|
||||
|
||||
# TODO Un jeu (canvas) et un frontend (fenetre)
|
251
S1/Echecs/logique.py
Normal file
251
S1/Echecs/logique.py
Normal file
|
@ -0,0 +1,251 @@
|
|||
import copy
|
||||
|
||||
class LogiqueEchecs:
|
||||
|
||||
CASES_COTE = 8
|
||||
|
||||
MVT_INCONNU = 'Cause inconnue'
|
||||
MVT_OK = 'Valide'
|
||||
MVT_ROQUE = 'Roque'
|
||||
MVT_SELECTION = 'Mauvais tour'
|
||||
MVT_SUR_PLACE = 'Immobile'
|
||||
MVT_SAUT_AMI = 'Saut ami'
|
||||
MVT_PION_INC = 'Pion inconnu'
|
||||
MVT_N_AUTORISE = 'Non-autorisé'
|
||||
MVT_OBSTRUCTION = 'Pion en chemin'
|
||||
MVT_ECHEC = 'Échec au roi'
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.grille = []
|
||||
self.cGrille()
|
||||
self.remplirGrille()
|
||||
self.joueur = True
|
||||
self.partieFinie = False
|
||||
self.victorieux = None
|
||||
|
||||
@staticmethod
|
||||
def eNoir(xD, yD):
|
||||
return xD % 2 != yD % 2
|
||||
|
||||
def cGrille(self):
|
||||
for x in range(LogiqueEchecs.CASES_COTE):
|
||||
colonne = []
|
||||
for y in range(LogiqueEchecs.CASES_COTE):
|
||||
colonne.append(0)
|
||||
self.grille.append(colonne)
|
||||
|
||||
def remplirGrille(self):
|
||||
speciales = [2, 3, 4, 6, 5, 4, 3, 2]
|
||||
for i in range(0, 8):
|
||||
self.grille[i][0] = speciales[i] + 10
|
||||
self.grille[i][1] = 11
|
||||
self.grille[i][6] = 1
|
||||
self.grille[i][7] = speciales[i]
|
||||
|
||||
def cPion(self, x, y, piece):
|
||||
"""
|
||||
"""
|
||||
self.grille[x][y] = piece
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def ePionBlanc(pion):
|
||||
return pion in range(1, 7)
|
||||
|
||||
@staticmethod
|
||||
def ePionNoir(pion):
|
||||
return pion in range(11, 17)
|
||||
|
||||
|
||||
def aSonTour(self, pion):
|
||||
return (self.ePionNoir(pion) and self.joueur == False) or \
|
||||
(self.ePionBlanc(pion) and self.joueur == True)
|
||||
|
||||
def mvtPossibleSansEchecPion(self, x1, y1, x2, y2):
|
||||
if x1 == x2 and self.grille[x2][y2] <= 0: # Avance
|
||||
if self.joueur:
|
||||
if y2 == y1 - 1:
|
||||
return LogiqueEchecs.MVT_OK
|
||||
elif y1 == 6 and y2 == 4 and self.grille[x1][5] == 0:
|
||||
return LogiqueEchecs.MVT_OK
|
||||
else:
|
||||
return LogiqueEchecs.MVT_N_AUTORISE
|
||||
else:
|
||||
if y2 == y1 + 1:
|
||||
return LogiqueEchecs.MVT_OK
|
||||
elif y1 == 1 and y2 == 3 and self.grille[x1][2] == 0:
|
||||
return LogiqueEchecs.MVT_OK
|
||||
else:
|
||||
return LogiqueEchecs.MVT_N_AUTORISE
|
||||
elif abs(x1-x2) == 1: # Saut
|
||||
if self.joueur:
|
||||
if y2 == y1 - 1 and \
|
||||
self.ePionNoir(self.grille[x2][y2]):
|
||||
return LogiqueEchecs.MVT_OK
|
||||
else:
|
||||
return LogiqueEchecs.MVT_N_AUTORISE
|
||||
else:
|
||||
if y2 == y1 + 1 and \
|
||||
self.ePionBlanc(self.grille[x2][y2]):
|
||||
return LogiqueEchecs.MVT_OK
|
||||
else:
|
||||
return LogiqueEchecs.MVT_N_AUTORISE
|
||||
else:
|
||||
return LogiqueEchecs.MVT_N_AUTORISE
|
||||
|
||||
def mvtPossibleSansEchecTour(self, x1, y1, x2, y2):
|
||||
if y1 == y2:
|
||||
sens = (x2-x1)//abs(x2-x1)
|
||||
for x in range(x1+sens, x2, sens):
|
||||
if self.grille[x][y1] > 0:
|
||||
return LogiqueEchecs.MVT_OBSTRUCTION
|
||||
elif x1 == x2:
|
||||
sens = (y2-y1)//abs(y2-y1)
|
||||
for y in range(y1+sens, y2, sens):
|
||||
if self.grille[x1][y] > 0:
|
||||
return LogiqueEchecs.MVT_OBSTRUCTION
|
||||
else:
|
||||
return LogiqueEchecs.MVT_N_AUTORISE
|
||||
return LogiqueEchecs.MVT_OK
|
||||
|
||||
def mvtPossibleSansEchecFou(self, x1, y1, x2, y2):
|
||||
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.grille[x][y] > 0:
|
||||
if dist == distTot:
|
||||
return LogiqueEchecs.MVT_OK # Saut
|
||||
else:
|
||||
return LogiqueEchecs.MVT_OBSTRUCTION
|
||||
return LogiqueEchecs.MVT_OK # Vide
|
||||
else:
|
||||
return LogiqueEchecs.MVT_N_AUTORISE
|
||||
|
||||
def mvtPossibleSansEchecCavalier(self, x1, y1, x2, y2):
|
||||
if (abs(x2-x1) == 2 and abs(y2-y1) == 1) or (abs(y2-y1) == 2 and abs(x2-x1) == 1):
|
||||
return LogiqueEchecs.MVT_OK
|
||||
else:
|
||||
return LogiqueEchecs.MVT_N_AUTORISE
|
||||
|
||||
def mvtPossibleSansEchec(self, x1, y1, x2, y2):
|
||||
pion = self.grille[x1][y1]
|
||||
if self.aSonTour(pion):
|
||||
if (x1 != x2 or y1 != y2):
|
||||
if not self.aSonTour(self.grille[x2][y2]):
|
||||
tPion = pion % 10
|
||||
if tPion == 1: # Pion
|
||||
return self.mvtPossibleSansEchecPion(x1, y1, x2, y2)
|
||||
elif tPion == 2: # Tour
|
||||
return self.mvtPossibleSansEchecTour(x1, y1, x2, y2)
|
||||
elif tPion == 3: # Cavalier
|
||||
return self.mvtPossibleSansEchecCavalier(x1, y1, x2, y2)
|
||||
elif tPion == 4: # Fou
|
||||
return self.mvtPossibleSansEchecFou(x1, y1, x2, y2)
|
||||
elif tPion == 5: # Dame
|
||||
tour = self.mvtPossibleSansEchecTour(x1, y1, x2, y2)
|
||||
fou = self.mvtPossibleSansEchecFou(x1, y1, x2, y2)
|
||||
if tour == LogiqueEchecs.MVT_OK or fou == LogiqueEchecs.MVT_OK:
|
||||
return LogiqueEchecs.MVT_OK
|
||||
elif tour == LogiqueEchecs.MVT_OBSTRUCTION or fou == LogiqueEchecs.MVT_OBSTRUCTION:
|
||||
return LogiqueEchecs.MVT_OBSTRUCTION
|
||||
else:
|
||||
return LogiqueEchecs.MVT_N_AUTORISE
|
||||
elif tPion == 6: # Roi
|
||||
if abs(x2-x1) <= 1 and abs(y2-y1) <= 1:
|
||||
return LogiqueEchecs.MVT_OK
|
||||
else:
|
||||
return LogiqueEchecs.MVT_N_AUTORISE
|
||||
else:
|
||||
return LogiqueEchecs.MVT_PION_INC
|
||||
else:
|
||||
return LogiqueEchecs.MVT_SAUT_AMI
|
||||
else:
|
||||
return LogiqueEchecs.MVT_SUR_PLACE
|
||||
else:
|
||||
return LogiqueEchecs.MVT_SELECTION
|
||||
return LogiqueEchecs.MVT_INCONNU
|
||||
|
||||
def mvtPossible(self, x1, y1, x2, y2):
|
||||
test = self.mvtPossibleSansEchec(x1, y1, x2, y2)
|
||||
if test == LogiqueEchecs.MVT_OK:
|
||||
# On copie la partie actuelle pour tester le mouvement et vérifier l'échec
|
||||
copie = copy.deepcopy(self);
|
||||
copie.dPionSansEchec(x1, y1, x2, y2)
|
||||
mvtsPossiblesTousAdverses = []
|
||||
pionRoi = 6
|
||||
if not self.joueur:
|
||||
pionRoi += 10
|
||||
roi = [-1, -1]
|
||||
for x in range(0, LogiqueEchecs.CASES_COTE):
|
||||
for y in range(0, LogiqueEchecs.CASES_COTE):
|
||||
mvtsPossiblesTousAdverses += copie.mvtsPossiblesSansEchec(x, y)
|
||||
if copie.grille[x][y] == pionRoi:
|
||||
roi = [x, y]
|
||||
if roi in mvtsPossiblesTousAdverses:
|
||||
return LogiqueEchecs.MVT_ECHEC
|
||||
else:
|
||||
return test
|
||||
else:
|
||||
return test
|
||||
|
||||
def mvtsPossiblesSansEchec(self, x1, y1):
|
||||
tableau = []
|
||||
for x2 in range(0, LogiqueEchecs.CASES_COTE):
|
||||
for y2 in range(0, LogiqueEchecs.CASES_COTE):
|
||||
if self.mvtPossibleSansEchec(x1, y1, x2, y2) == LogiqueEchecs.MVT_OK:
|
||||
tableau.append([x2, y2])
|
||||
return tableau
|
||||
|
||||
def mvtsPossibles(self, x1, y1):
|
||||
tableau = []
|
||||
for x2 in range(0, LogiqueEchecs.CASES_COTE):
|
||||
for y2 in range(0, LogiqueEchecs.CASES_COTE):
|
||||
if self.mvtPossible(x1, y1, x2, y2) == LogiqueEchecs.MVT_OK:
|
||||
tableau.append([x2, y2])
|
||||
return tableau
|
||||
|
||||
def dPionSansEchec(self, x1, y1, x2, y2):
|
||||
test = self.mvtPossibleSansEchec(x1, y1, x2, y2)
|
||||
if test == LogiqueEchecs.MVT_OK:
|
||||
self.grille[x1][y1], self.grille[x2][y2] = 0, self.grille[x1][y1]
|
||||
self.joueur = not self.joueur
|
||||
|
||||
def vEchecMat(self):
|
||||
"""
|
||||
Vérifie si le joueur actuel est en échec et mat et prend les mesures nécessiares.
|
||||
(CÀD Le joueur actuel ne peut effectuer aucun mouvement)
|
||||
"""
|
||||
for x in range(0, LogiqueEchecs.CASES_COTE):
|
||||
for y in range(0, LogiqueEchecs.CASES_COTE):
|
||||
if len(self.mvtsPossibles(x, y)) > 0:
|
||||
return False
|
||||
self.partieFinie = True
|
||||
self.victorieux = not self.joueur
|
||||
return True
|
||||
|
||||
def dPion(self, x1, y1, x2, y2):
|
||||
test = self.mvtPossible(x1, y1, x2, y2)
|
||||
retour = {
|
||||
'valide': False,
|
||||
'message': test,
|
||||
'deplacer': [], # Pions à déplacer
|
||||
'supprimer': [], # Pions à supprimer
|
||||
}
|
||||
if test == LogiqueEchecs.MVT_OK:
|
||||
retour['valide'] = True
|
||||
if self.grille[x2][y2] > 0:
|
||||
retour['supprimer'].append([x2, y2])
|
||||
retour['deplacer'].append([x1, y1, x2, y2])
|
||||
self.grille[x1][y1], self.grille[x2][y2] = 0, self.grille[x1][y1]
|
||||
self.joueur = not self.joueur
|
||||
self.vEchecMat()
|
||||
return retour
|
Binary file not shown.
Before Width: | Height: | Size: 14 KiB |
Binary file not shown.
Before Width: | Height: | Size: 9.1 KiB |
|
@ -1,19 +0,0 @@
|
|||
from tkinter import *
|
||||
|
||||
|
||||
|
||||
|
||||
##### Programme principal : ############
|
||||
taille=600
|
||||
fen = Tk()
|
||||
can = Canvas(fen, width =taille, height =taille, bg ='ivory')
|
||||
img = PhotoImage(file ='./../sprites/reineN.gif')
|
||||
can.pack(side =TOP, padx =5, pady =5)
|
||||
i = img.subsample(2,2)
|
||||
can.create_image(150 ,150, image =i)
|
||||
j = img.subsample(4,4)
|
||||
can.create_image(300 ,300, image =j)
|
||||
k = img.subsample(8,8)
|
||||
can.create_image(400 ,400, image =k)
|
||||
|
||||
fen.mainloop()
|
|
@ -1,345 +0,0 @@
|
|||
# pylint: disable=W0603
|
||||
|
||||
# INFOS
|
||||
|
||||
# Pièces :
|
||||
|
||||
# [1-6] : Blancs
|
||||
# [11-6] : Noirs
|
||||
|
||||
# X1 : Pion
|
||||
# X2 : Tour
|
||||
# X3 : Cavalier
|
||||
# x4 : Fou
|
||||
# X5 : Dame
|
||||
# X6 : Roi
|
||||
|
||||
|
||||
# j_ jeu : le logique du jeu lui même
|
||||
# g_ GUI : l'interface graphique
|
||||
# f_ Frontend : ce qui associe les deux
|
||||
# _e : est
|
||||
# _c : crée
|
||||
# _d : déplace
|
||||
|
||||
|
||||
# IMPORTS
|
||||
from tkinter import *
|
||||
from random import randint
|
||||
|
||||
# FONCTIONS
|
||||
|
||||
|
||||
# Jeu
|
||||
CASES_COTE = 8
|
||||
|
||||
j_grille = None
|
||||
j_joueur = True
|
||||
|
||||
def j_eNoir(xD, yD): # TODO Peut être considérablement amélioré
|
||||
i = 1
|
||||
for x in range(0, CASES_COTE):
|
||||
i += 1
|
||||
for y in range(0, CASES_COTE):
|
||||
i += 1
|
||||
if x == xD and y == yD:
|
||||
return i%2
|
||||
def j_cGrille():
|
||||
global j_grille
|
||||
j_grille = []
|
||||
for x in range(CASES_COTE):
|
||||
colonne = []
|
||||
for y in range(CASES_COTE):
|
||||
colonne.append(0)
|
||||
j_grille.append(colonne)
|
||||
|
||||
def j_remplirGrille():
|
||||
global j_grille
|
||||
speciales = [2, 3, 4, 6, 5, 4, 3, 2]
|
||||
for i in range(0, 8):
|
||||
j_grille[i][0] = speciales[i] + 10
|
||||
j_grille[i][1] = 11
|
||||
j_grille[i][6] = 1
|
||||
j_grille[i][7] = speciales[i]
|
||||
|
||||
def j_nvPartie():
|
||||
j_cGrille()
|
||||
j_remplirGrille()
|
||||
global j_joueur
|
||||
j_joueur = True
|
||||
|
||||
def j_cPion(x, y, piece):
|
||||
"""
|
||||
"""
|
||||
j_grille[x][y] = piece
|
||||
return True
|
||||
|
||||
def j_mvtPossible(x1, y1, x2, y2):
|
||||
pion = j_grille[x1][y1]
|
||||
if (pion >= 10 and j_joueur == False) or (pion < 10 and j_joueur == True):
|
||||
if pion > 0 and j_grille[x2][y2] <= 0:
|
||||
tPion = pion%10
|
||||
if tPion == 1:
|
||||
if x1 == x2:
|
||||
if j_joueur:
|
||||
if y2 == y1-1:
|
||||
return True
|
||||
else:
|
||||
return -4
|
||||
else:
|
||||
if y2 == y1+1:
|
||||
return True
|
||||
else:
|
||||
return -4
|
||||
else:
|
||||
return -4
|
||||
elif tPion == 6:
|
||||
if x2 <= x1+1 and x2 >= x1-1 and y2 <= y1+1 and y2 >= y1-1 \
|
||||
and (x1 != x2 or y1 != y2):
|
||||
return True
|
||||
else:
|
||||
return -4
|
||||
else:
|
||||
return -3
|
||||
|
||||
return True
|
||||
else:
|
||||
return -2
|
||||
else:
|
||||
return -1
|
||||
|
||||
def j_dPion(x1, y1, x2, y2):
|
||||
test = j_mvtPossible(x1, y1, x2, y2)
|
||||
if test == True:
|
||||
global j_joueur, j_grille
|
||||
j_grille[x2][y2] = j_grille[x1][y1]
|
||||
j_grille[x1][y1] = 0
|
||||
# j_joueur = not j_joueur # DEBUG
|
||||
return True
|
||||
else:
|
||||
return test
|
||||
|
||||
# GUI
|
||||
DECX = 0
|
||||
DECY = 0
|
||||
COTE_CASE = 50
|
||||
MARGE_PIONS = 5
|
||||
TEMPS_ANIM = 200
|
||||
INTER_ANIM = 10
|
||||
|
||||
g_imagesOriginales = []
|
||||
g_imagesRedim = []
|
||||
|
||||
|
||||
g_grilleDamier = None
|
||||
g_grillePions = None
|
||||
g_photos = []
|
||||
fen = None
|
||||
can = None
|
||||
chaine = None
|
||||
|
||||
# Animation
|
||||
g_x1 = None
|
||||
g_y1 = None
|
||||
g_x2 = None
|
||||
g_y2 = None
|
||||
g_pion = None
|
||||
g_anim = None
|
||||
|
||||
def g_fen():
|
||||
global fen, can, chaine
|
||||
fen = Tk()
|
||||
fen.title("Jeu d'Échecs")
|
||||
can = Canvas(fen, width=COTE_CASE*CASES_COTE, height=COTE_CASE*CASES_COTE, \
|
||||
bg="ivory")
|
||||
can.grid(row=0, column=1, columnspan=3)
|
||||
can.bind('<Button-1>', f_clic)
|
||||
chaine = Label(fen, text="Aux blancs")
|
||||
chaine.grid(row=2, column=2, padx=3, pady=3)
|
||||
Button(fen, text="Nv. Partie", command=f_nvPartie).grid(row=2, column=1, \
|
||||
padx=3, pady=3)
|
||||
Button(fen, text="Quitter", command=fen.destroy).grid(row=2, column=3, \
|
||||
padx=3, pady=3)
|
||||
|
||||
def g_statut(texte, delai=0):
|
||||
chaine.config(text=texte)
|
||||
# TODO Timeout effacer si parametre / Liste
|
||||
|
||||
def g_importerImages():
|
||||
global g_imagesOriginales
|
||||
for piece in range(0, 21):
|
||||
nom = 'sprites/'
|
||||
if piece%10 == 1:
|
||||
nom += 'pion'
|
||||
elif piece%10 == 2:
|
||||
nom += 'tour'
|
||||
elif piece%10 == 3:
|
||||
nom += 'cavalier'
|
||||
elif piece%10 == 4:
|
||||
nom += 'fou'
|
||||
elif piece%10 == 5:
|
||||
nom += 'dame'
|
||||
elif piece%10 == 6:
|
||||
nom += 'roi'
|
||||
else:
|
||||
g_imagesOriginales.append('')
|
||||
continue
|
||||
if piece < 10:
|
||||
nom += 'B'
|
||||
else:
|
||||
nom += 'N'
|
||||
nom += '.gif'
|
||||
g_imagesOriginales.append(PhotoImage(file=nom))
|
||||
|
||||
def g_redimImages():
|
||||
global g_imagesRedim
|
||||
sample = int(504/(COTE_CASE-MARGE_PIONS))
|
||||
for piece in range(0, 21):
|
||||
if g_imagesOriginales[piece] != '':
|
||||
g_imagesRedim.append(g_imagesOriginales[piece].subsample(sample))
|
||||
else:
|
||||
g_imagesRedim.append('')
|
||||
|
||||
|
||||
def g_cCase(x, y):
|
||||
if j_eNoir(x, y):
|
||||
couleur = '#D18B47'
|
||||
else:
|
||||
couleur = '#FFCE9E'
|
||||
return can.create_rectangle(x*COTE_CASE, y*COTE_CASE, \
|
||||
(x+1)*COTE_CASE, (y+1)*COTE_CASE, fill=couleur)
|
||||
|
||||
def g_cDamier():
|
||||
global g_grilleDamier
|
||||
g_grilleDamier = []
|
||||
for x in range(0, CASES_COTE):
|
||||
colonne = []
|
||||
for y in range(0, CASES_COTE):
|
||||
colonne.append(g_cCase(x + DECX, y + DECY))
|
||||
g_grilleDamier.append(colonne)
|
||||
|
||||
def g_cPion(x, y, piece):
|
||||
global g_grillePions
|
||||
global g_photos
|
||||
if piece > 0:
|
||||
g_grillePions[x][y] = can.create_image((x+.5)*COTE_CASE, \
|
||||
(y+.5)*COTE_CASE, image=g_imagesRedim[piece])
|
||||
else:
|
||||
g_grillePions[x][y] = False
|
||||
|
||||
def g_dPionFinal():
|
||||
can.coords(g_pion, g_x2, g_y2)
|
||||
|
||||
def g_dPionAnim():
|
||||
global g_pion, g_anim
|
||||
x = g_x1 + (g_x2-g_x1) * (g_anim/TEMPS_ANIM)
|
||||
y = g_y1 + (g_y2-g_y1) * (g_anim/TEMPS_ANIM)
|
||||
can.coords(g_pion, x, y)
|
||||
g_anim += INTER_ANIM
|
||||
if g_anim < TEMPS_ANIM:
|
||||
fen.after(INTER_ANIM, g_dPionAnim)
|
||||
else:
|
||||
g_dPionFinal()
|
||||
|
||||
def g_dPion(x1, y1, x2, y2):
|
||||
# TODO Bloquer l'entrée pendant l'anim
|
||||
global g_grillePions, g_x1, g_y1, g_x2, g_y2, g_pion, g_anim
|
||||
g_x1 = (x1+.5)*COTE_CASE
|
||||
g_y1 = (y1+.5)*COTE_CASE
|
||||
g_x2 = (x2+.5)*COTE_CASE
|
||||
g_y2 = (y2+.5)*COTE_CASE
|
||||
g_pion = g_grillePions[x1][y1]
|
||||
g_anim = 0
|
||||
# can.coords(g_grillePions[x1][y1], (x2+.5)*COTE_CASE, (y2+.5)*COTE_CASE)
|
||||
g_grillePions[x2][y2] = g_grillePions[x1][y1]
|
||||
g_grillePions[x1][y1] = False
|
||||
g_dPionAnim()
|
||||
# g_dPionFinal()
|
||||
|
||||
def g_cGrille():
|
||||
global g_grillePions
|
||||
g_grillePions = []
|
||||
for x in range(0, CASES_COTE): # Crée g_grillePions
|
||||
colonne = []
|
||||
for y in range(0, CASES_COTE):
|
||||
colonne.append(False)
|
||||
g_grillePions.append(colonne)
|
||||
|
||||
def g_remplirGrille(j_grilleF):
|
||||
global g_grillePions
|
||||
for x in range(0, CASES_COTE): # Remplis g_grillePions
|
||||
for y in range(0, CASES_COTE):
|
||||
g_cPion(x, y, j_grilleF[x][y])
|
||||
|
||||
def g_init():
|
||||
g_fen()
|
||||
g_importerImages()
|
||||
g_redimImages()
|
||||
|
||||
# Frontend
|
||||
|
||||
f_origine = True
|
||||
f_x1 = -1
|
||||
f_y1 = -1
|
||||
f_x2 = -1
|
||||
f_y2 = -1
|
||||
|
||||
def f_statutPrendre():
|
||||
if j_joueur:
|
||||
joueur = 'blancs'
|
||||
else:
|
||||
joueur = 'noirs'
|
||||
g_statut('Prendre (' + joueur + ')')
|
||||
|
||||
def f_init():
|
||||
g_init()
|
||||
f_nvPartie()
|
||||
f_statutPrendre()
|
||||
|
||||
|
||||
def f_cPion(x, y, piece):
|
||||
if j_cPion(x, y, piece):
|
||||
g_cPion(x, y, piece)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def f_cPionAlea():
|
||||
g_cPion(randint(1, CASES_COTE), randint(1, CASES_COTE), 1)
|
||||
|
||||
def f_dPion(x1, y1, x2, y2):
|
||||
test = j_dPion(x1, y1, x2, y2)
|
||||
if test == True:
|
||||
g_dPion(x1, y1, x2, y2)
|
||||
return True
|
||||
else:
|
||||
g_statut('Impossible ! ('+str(test)+')') # TODO Messages corrects
|
||||
return False
|
||||
|
||||
def f_nvPartie():
|
||||
j_nvPartie()
|
||||
g_cDamier()
|
||||
g_cGrille()
|
||||
g_remplirGrille(j_grille)
|
||||
|
||||
def f_dClic(x, y):
|
||||
global f_origine, f_x1, f_y1, f_x2, f_y2
|
||||
if f_origine:
|
||||
f_x1, f_y1 = x, y
|
||||
# TODO Colorer case
|
||||
g_statut('Poser')
|
||||
else:
|
||||
f_x2, f_y2 = x, y
|
||||
f_dPion(f_x1, f_y1, f_x2, f_y2)
|
||||
f_statutPrendre()
|
||||
f_origine = not f_origine
|
||||
|
||||
|
||||
def f_clic(event):
|
||||
x = event.x//COTE_CASE
|
||||
y = event.y//COTE_CASE
|
||||
f_dClic(x, y)
|
||||
|
||||
|
||||
|
||||
f_init()
|
|
@ -1,222 +0,0 @@
|
|||
# INFOS
|
||||
|
||||
# Pièces :
|
||||
|
||||
# [1-6] : Blancs
|
||||
# [11-6] : Noirs
|
||||
|
||||
# X1 : Pion
|
||||
# X2 : Tour
|
||||
# X3 : Cavalier
|
||||
# x4 : Fou
|
||||
# X5 : Dame
|
||||
# X6 : Roi
|
||||
|
||||
|
||||
# j_ jeu : le logique du jeu lui même
|
||||
# g_ GUI : l'interface graphique
|
||||
# f_ Frontend : ce qui associe les deux
|
||||
# _e : est
|
||||
# _c : crée
|
||||
# _d : déplace
|
||||
|
||||
|
||||
# IMPORTS
|
||||
from tkinter import *
|
||||
from random import randint
|
||||
|
||||
# FONCTIONS
|
||||
|
||||
|
||||
# Jeu
|
||||
CASES_COTE = 8
|
||||
|
||||
j_grille = None
|
||||
auxBlancs = None
|
||||
|
||||
def j_eNoir(xD, yD): # TODO Peut être considérablement amélioré
|
||||
i = 1
|
||||
for x in range(0, CASES_COTE):
|
||||
i += 1
|
||||
for y in range(0, CASES_COTE):
|
||||
i += 1
|
||||
if x == xD and y == yD:
|
||||
return i%2
|
||||
def j_cGrille():
|
||||
global j_grille
|
||||
j_grille = []
|
||||
for x in range(CASES_COTE):
|
||||
colonne = []
|
||||
for y in range(CASES_COTE):
|
||||
if j_eNoir(x, y):
|
||||
colonne.append(0)
|
||||
else:
|
||||
colonne.append(-1)
|
||||
j_grille.append(colonne)
|
||||
|
||||
def j_remplirGrille():
|
||||
global j_grille
|
||||
j_grille[2][2] = 5
|
||||
|
||||
def j_nvPartie():
|
||||
j_cGrille()
|
||||
j_remplirGrille()
|
||||
global auxBlancs
|
||||
auxBlancs = True
|
||||
|
||||
def j_cPion(x, y, piece):
|
||||
"""
|
||||
"""
|
||||
j_grille[x][y] = piece
|
||||
return True
|
||||
|
||||
def j_dPion(x1, y1, x2, y2):
|
||||
# TODO Vérification du mouvement possible
|
||||
assert(j_grille[x1][y1] > 0), "ERR1"
|
||||
assert(j_grille[x2][y2] != 0), "ERR2"
|
||||
j_grille[x2][y2] = j_grille[x1][y1]
|
||||
return True
|
||||
|
||||
# def poserPion(x, y):
|
||||
# global auxBlancs
|
||||
# if j_grille[x][y] == 0:
|
||||
# j_grille[x][y] = 1
|
||||
# pion(x, y, auxBlancs)
|
||||
# auxBlancs = not auxBlancs
|
||||
# elif j_grille[x][y] == -1:
|
||||
# statut('On joue sur les cases noires !')
|
||||
# else:
|
||||
# statut('Il y a déjà quelque chose ici.')
|
||||
|
||||
|
||||
# GUI
|
||||
DECX = 0
|
||||
DECY = 0
|
||||
COTE_CASE = 50
|
||||
MARGE_PIONS = 5
|
||||
|
||||
g_grilleDamier = None
|
||||
g_grillePions = None
|
||||
g_photos = []
|
||||
fen = None
|
||||
can = None
|
||||
chaine = None
|
||||
|
||||
def g_fen():
|
||||
global fen, can, chaine
|
||||
fen = Tk()
|
||||
fen.title("Jeu d'Échecs")
|
||||
can = Canvas(fen, width=COTE_CASE*CASES_COTE, height=COTE_CASE*CASES_COTE, \
|
||||
bg="ivory")
|
||||
can.grid(row=0, column=1, columnspan=3)
|
||||
can.bind('<Button-1>', f_clic)
|
||||
chaine = Label(fen, text="Aux blancs")
|
||||
chaine.grid(row=2, column=2, padx=3, pady=3)
|
||||
Button(fen, text="Nv. Partie", command=f_nvPartie).grid(row=2, column=1, \
|
||||
padx=3, pady=3)
|
||||
Button(fen, text="Quitter", command=fen.destroy).grid(row=2, column=3, \
|
||||
padx=3, pady=3)
|
||||
|
||||
def g_statut(texte, delai=0):
|
||||
chaine.config(text=texte)
|
||||
print(texte)
|
||||
# TODO Timeout effacer si parametre
|
||||
|
||||
def g_cCase(x, y):
|
||||
if j_eNoir(x, y):
|
||||
couleur = 'black'
|
||||
else:
|
||||
couleur = 'white'
|
||||
return can.create_rectangle(x*COTE_CASE, y*COTE_CASE, \
|
||||
(x+1)*COTE_CASE, (y+1)*COTE_CASE, fill=couleur)
|
||||
|
||||
def g_cDamier():
|
||||
global g_grilleDamier
|
||||
g_grilleDamier = []
|
||||
for x in range(0, CASES_COTE):
|
||||
colonne = []
|
||||
for y in range(0, CASES_COTE):
|
||||
colonne.append(g_cCase(x + DECX, y + DECY))
|
||||
g_grilleDamier.append(colonne)
|
||||
|
||||
def g_cPion(x, y, piece):
|
||||
global g_grillePions
|
||||
global g_photos
|
||||
if piece > 0:
|
||||
nom = 'sprites/'
|
||||
if piece%10 == 5:
|
||||
nom += 'reine'
|
||||
else:
|
||||
nom += 'pion'
|
||||
if piece < 10:
|
||||
nom += 'B'
|
||||
else:
|
||||
nom += 'N'
|
||||
nom += '.gif'
|
||||
g_photos.append(PhotoImage(file=nom))
|
||||
sample = int(504/(COTE_CASE-MARGE_PIONS))
|
||||
g_photos[-1] = g_photos[-1].subsample(sample)
|
||||
g_grillePions[x][y] = can.create_image((x+.5)*COTE_CASE, (y+.5)*COTE_CASE, image=g_photos[-1])
|
||||
# g_grillePions[x][y] = can.create_oval(x*COTE_CASE+MARGE_PIONS, y*COTE_CASE+MARGE_PIONS, \
|
||||
# (x+1)*COTE_CASE-MARGE_PIONS, (y+1)*COTE_CASE-MARGE_PIONS, \
|
||||
# outline='gray', width=2, fill='white' if piece < 10 else 'black')
|
||||
else:
|
||||
g_grillePions[x][y] = False
|
||||
|
||||
def g_dPion(x1, y1, x2, y2):
|
||||
global g_grillePions
|
||||
pion = g_grillePions[x1][y1]
|
||||
can.coords(pion, x2*COTE_CASE+MARGE_PIONS, y2*COTE_CASE+MARGE_PIONS, (x2+1)*COTE_CASE-MARGE_PIONS, (y2+1)*COTE_CASE-MARGE_PIONS)
|
||||
g_grillePions[x1][y1] = False
|
||||
g_grillePions[x2][y2] = pion
|
||||
|
||||
def g_cGrille():
|
||||
global g_grillePions
|
||||
g_grillePions = []
|
||||
for x in range(0, CASES_COTE): # Crée g_grillePions
|
||||
colonne = []
|
||||
for y in range(0, CASES_COTE):
|
||||
colonne.append(False)
|
||||
g_grillePions.append(colonne)
|
||||
|
||||
def g_remplirGrille(j_grilleF):
|
||||
global g_grillePions
|
||||
for x in range(0, CASES_COTE): # Remplis g_grillePions
|
||||
for y in range(0, CASES_COTE):
|
||||
g_cPion(x, y, j_grilleF[x][y])
|
||||
|
||||
|
||||
# Frontend
|
||||
def f_cPion(x, y, piece):
|
||||
if j_cPion(x, y, piece):
|
||||
g_cPion(x, y, piece)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def f_cPionAlea():
|
||||
g_cPion(randint(1, CASES_COTE), randint(1, CASES_COTE), 1)
|
||||
|
||||
def f_dPion(x1, y1, x2, y2):
|
||||
if j_dPion(x1, y1, x2, y2):
|
||||
g_dPion(x1, y1, x2, y2)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def f_nvPartie():
|
||||
j_nvPartie()
|
||||
g_cDamier()
|
||||
g_cGrille()
|
||||
g_remplirGrille(j_grille)
|
||||
|
||||
def f_clic(event):
|
||||
x = event.x//COTE_CASE
|
||||
y = event.y//COTE_CASE
|
||||
f_cPion(x, y, 1)
|
||||
|
||||
|
||||
# MAIN
|
||||
|
||||
g_fen()
|
||||
f_nvPartie()
|
37
S1/Echecs/tkResize.py
Normal file
37
S1/Echecs/tkResize.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
import tkinter.ttk
|
||||
from tkinter.constants import *
|
||||
|
||||
class Application(tkinter.ttk.Frame):
|
||||
|
||||
@classmethod
|
||||
def main(cls):
|
||||
tkinter.NoDefaultRoot()
|
||||
root = tkinter.Tk()
|
||||
app = cls(root)
|
||||
app.grid(sticky=NSEW)
|
||||
root.grid_columnconfigure(0, weight=1)
|
||||
root.grid_rowconfigure(0, weight=1)
|
||||
root.resizable(True, True)
|
||||
root.mainloop()
|
||||
|
||||
def __init__(self, root):
|
||||
super().__init__(root)
|
||||
self.create_widgets()
|
||||
self.grid_widgets()
|
||||
self.grid_columnconfigure(0, weight=1)
|
||||
|
||||
def create_widgets(self):
|
||||
self.set_timer = tkinter.ttk.Entry(self, text="Dummy")
|
||||
self.start = tkinter.ttk.Button(self, text='Start')
|
||||
self.display1 = tkinter.ttk.Label(self, text='Dummy')
|
||||
self.display2 = tkinter.ttk.Label(self, text='Dummy')
|
||||
|
||||
def grid_widgets(self):
|
||||
options = dict(sticky=NSEW, padx=3, pady=4)
|
||||
self.set_timer.grid(column=0, row=0, **options)
|
||||
self.start.grid(column=0, row=1, **options)
|
||||
self.display1.grid(column=0, row=2, **options)
|
||||
self.display2.grid(column=0, row=3, **options)
|
||||
|
||||
if __name__ == '__main__':
|
||||
Application.main()
|
Reference in a new issue