From 246f65993e9e72ff80281b60414b1e52c4998e3b Mon Sep 17 00:00:00 2001 From: Geoffrey Frogeye Date: Fri, 12 Dec 2014 19:49:58 +0100 Subject: [PATCH] =?UTF-8?q?S=C3=A9paration=20en=20diff=C3=A9rents=20fichie?= =?UTF-8?q?rs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Il faut désormais lancer app.py - Nettoyage des fichiers inutiles --- S1/Echecs/README.md | 3 +- S1/Echecs/app.py | 5 + S1/Echecs/echecs.py | 559 ----------------------- S1/Echecs/guiTk.py | 307 +++++++++++++ S1/Echecs/logique.py | 251 ++++++++++ S1/Echecs/sprites/Martin_p.gif | Bin 13910 -> 0 bytes S1/Echecs/sprites/flamand-rose-67ef4.gif | Bin 9271 -> 0 bytes S1/Echecs/sprites/tstimg.py | 19 - S1/Echecs/tests.py | 345 -------------- S1/Echecs/testsQt.py | 222 --------- S1/Echecs/tkResize.py | 37 ++ 11 files changed, 602 insertions(+), 1146 deletions(-) create mode 100644 S1/Echecs/app.py delete mode 100755 S1/Echecs/echecs.py create mode 100644 S1/Echecs/guiTk.py create mode 100644 S1/Echecs/logique.py delete mode 100644 S1/Echecs/sprites/Martin_p.gif delete mode 100644 S1/Echecs/sprites/flamand-rose-67ef4.gif delete mode 100644 S1/Echecs/sprites/tstimg.py delete mode 100644 S1/Echecs/tests.py delete mode 100644 S1/Echecs/testsQt.py create mode 100644 S1/Echecs/tkResize.py diff --git a/S1/Echecs/README.md b/S1/Echecs/README.md index 5e33d84..ed3e971 100644 --- a/S1/Echecs/README.md +++ b/S1/Echecs/README.md @@ -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) diff --git a/S1/Echecs/app.py b/S1/Echecs/app.py new file mode 100644 index 0000000..d654f27 --- /dev/null +++ b/S1/Echecs/app.py @@ -0,0 +1,5 @@ +from logique import LogiqueEchecs +from guiTk import PlateauTk + +p = PlateauTk(LogiqueEchecs()) + diff --git a/S1/Echecs/echecs.py b/S1/Echecs/echecs.py deleted file mode 100755 index 170ebdc..0000000 --- a/S1/Echecs/echecs.py +++ /dev/null @@ -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('', 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) diff --git a/S1/Echecs/guiTk.py b/S1/Echecs/guiTk.py new file mode 100644 index 0000000..87dfa37 --- /dev/null +++ b/S1/Echecs/guiTk.py @@ -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('', 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) \ No newline at end of file diff --git a/S1/Echecs/logique.py b/S1/Echecs/logique.py new file mode 100644 index 0000000..5a4d331 --- /dev/null +++ b/S1/Echecs/logique.py @@ -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 \ No newline at end of file diff --git a/S1/Echecs/sprites/Martin_p.gif b/S1/Echecs/sprites/Martin_p.gif deleted file mode 100644 index 85d788406c71f7994d72a5fbeb7821f2e17a3af1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13910 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 diff --git a/S1/Echecs/sprites/flamand-rose-67ef4.gif b/S1/Echecs/sprites/flamand-rose-67ef4.gif deleted file mode 100644 index 0408938835499bea359fa4111539887190c0bbdb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9271 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 diff --git a/S1/Echecs/sprites/tstimg.py b/S1/Echecs/sprites/tstimg.py deleted file mode 100644 index 1298297..0000000 --- a/S1/Echecs/sprites/tstimg.py +++ /dev/null @@ -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() diff --git a/S1/Echecs/tests.py b/S1/Echecs/tests.py deleted file mode 100644 index 2e1a100..0000000 --- a/S1/Echecs/tests.py +++ /dev/null @@ -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('', 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() diff --git a/S1/Echecs/testsQt.py b/S1/Echecs/testsQt.py deleted file mode 100644 index 249a223..0000000 --- a/S1/Echecs/testsQt.py +++ /dev/null @@ -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('', 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() diff --git a/S1/Echecs/tkResize.py b/S1/Echecs/tkResize.py new file mode 100644 index 0000000..c881e7d --- /dev/null +++ b/S1/Echecs/tkResize.py @@ -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() \ No newline at end of file