From 42e98e2b9de67a42fbd6117028924cefa3269c15 Mon Sep 17 00:00:00 2001 From: Geoffrey Frogeye Date: Fri, 14 Nov 2014 08:51:44 +0100 Subject: [PATCH] Ajout TP 7 et avancement sur Echecs avant POO --- S1/Echecs/sprites/{cavB.gif => cavalierB.gif} | Bin S1/Echecs/sprites/{cavN.gif => cavalierN.gif} | Bin S1/Echecs/sprites/{reineB.gif => dameB.gif} | Bin S1/Echecs/sprites/{reineN.gif => dameN.gif} | Bin S1/Echecs/sprites/{TourB.gif => tourB.gif} | Bin S1/Echecs/sprites/{TourN.gif => tourN.gif} | Bin S1/Echecs/tests.py | 235 ++++++++--- S1/TP 7/chaines.py | 396 ++++++++++++++++++ 8 files changed, 575 insertions(+), 56 deletions(-) rename S1/Echecs/sprites/{cavB.gif => cavalierB.gif} (100%) rename S1/Echecs/sprites/{cavN.gif => cavalierN.gif} (100%) rename S1/Echecs/sprites/{reineB.gif => dameB.gif} (100%) rename S1/Echecs/sprites/{reineN.gif => dameN.gif} (100%) rename S1/Echecs/sprites/{TourB.gif => tourB.gif} (100%) rename S1/Echecs/sprites/{TourN.gif => tourN.gif} (100%) create mode 100644 S1/TP 7/chaines.py diff --git a/S1/Echecs/sprites/cavB.gif b/S1/Echecs/sprites/cavalierB.gif similarity index 100% rename from S1/Echecs/sprites/cavB.gif rename to S1/Echecs/sprites/cavalierB.gif diff --git a/S1/Echecs/sprites/cavN.gif b/S1/Echecs/sprites/cavalierN.gif similarity index 100% rename from S1/Echecs/sprites/cavN.gif rename to S1/Echecs/sprites/cavalierN.gif diff --git a/S1/Echecs/sprites/reineB.gif b/S1/Echecs/sprites/dameB.gif similarity index 100% rename from S1/Echecs/sprites/reineB.gif rename to S1/Echecs/sprites/dameB.gif diff --git a/S1/Echecs/sprites/reineN.gif b/S1/Echecs/sprites/dameN.gif similarity index 100% rename from S1/Echecs/sprites/reineN.gif rename to S1/Echecs/sprites/dameN.gif diff --git a/S1/Echecs/sprites/TourB.gif b/S1/Echecs/sprites/tourB.gif similarity index 100% rename from S1/Echecs/sprites/TourB.gif rename to S1/Echecs/sprites/tourB.gif diff --git a/S1/Echecs/sprites/TourN.gif b/S1/Echecs/sprites/tourN.gif similarity index 100% rename from S1/Echecs/sprites/TourN.gif rename to S1/Echecs/sprites/tourN.gif diff --git a/S1/Echecs/tests.py b/S1/Echecs/tests.py index 249a223..2e1a100 100644 --- a/S1/Echecs/tests.py +++ b/S1/Echecs/tests.py @@ -1,3 +1,5 @@ +# pylint: disable=W0603 + # INFOS # Pièces : @@ -32,7 +34,7 @@ from random import randint CASES_COTE = 8 j_grille = None -auxBlancs = None +j_joueur = True def j_eNoir(xD, yD): # TODO Peut être considérablement amélioré i = 1 @@ -48,21 +50,23 @@ def j_cGrille(): 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) + colonne.append(0) j_grille.append(colonne) def j_remplirGrille(): global j_grille - j_grille[2][2] = 5 + 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 auxBlancs - auxBlancs = True + global j_joueur + j_joueur = True def j_cPion(x, y, piece): """ @@ -70,30 +74,62 @@ 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): - # 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.') - + 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 @@ -102,6 +138,14 @@ 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() @@ -119,14 +163,49 @@ def g_fen(): def g_statut(texte, delai=0): chaine.config(text=texte) - print(texte) - # TODO Timeout effacer si parametre + # 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 = 'black' + couleur = '#D18B47' else: - couleur = 'white' + couleur = '#FFCE9E' return can.create_rectangle(x*COTE_CASE, y*COTE_CASE, \ (x+1)*COTE_CASE, (y+1)*COTE_CASE, fill=couleur) @@ -143,32 +222,39 @@ 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') + 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): - 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) + # 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_grillePions[x2][y2] = pion + g_dPionAnim() + # g_dPionFinal() def g_cGrille(): global g_grillePions @@ -185,9 +271,33 @@ def g_remplirGrille(j_grilleF): 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 -def f_cPion(x, y, piece): + +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 @@ -198,10 +308,12 @@ 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): + 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(): @@ -210,13 +322,24 @@ def f_nvPartie(): 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_cPion(x, y, 1) + f_dClic(x, y) -# MAIN -g_fen() -f_nvPartie() +f_init() diff --git a/S1/TP 7/chaines.py b/S1/TP 7/chaines.py new file mode 100644 index 0000000..50b41a0 --- /dev/null +++ b/S1/TP 7/chaines.py @@ -0,0 +1,396 @@ +# VAN DEN BERGE Manon - PeiP 12 - 2014/2015 +# PREUD'HOMME BONTOUX Geoffrey - PeiP 12 - 2014/2015 +# TP n°7 donné le 7/11/2014 - Exercices sur les chaînes de caractère +# http://www.fil.univ-lille1.fr/~wegrzyno/portail/Info/Doc/HTML/seq4_chaines_caracteres.html#exercices + +import doctest + + +# Exercice 30 lignes vides + +# Comment en utilisant print une seule fois peut-on imprimer 30 lignes +# vides ? (boucles pour et tant que interdites) + +# En utilisant l'opérateur de répétition + +# print("\n"*30, end='') + + +# Exercice Impression verticale + +# Réalisez une fonction imprimer_vertical qui imprime un à un les +# caractères de la chaîne qu’on lui donne en paramètre les uns au dessus +# des autres. + +def imprimer_vertical(chaine): + """ + Imprime un à un les caractères de la chaîne donnée en paramètre les uns au + dessus des autres. + str → ∅ + CU : chaine du type str + """ + assert(type(chaine) is str), "chaine doit être du type str" + + for i in chaine: + print(i) + +# >>> imprimer_vertical('Timoleon') +# T +# i +# m +# o +# l +# e +# o +# n + + +# Exercice Impression à l’envers + +# Réalisez d’au moins deux façons différentes une fonction imprimer_envers +# qui imprime la chaîne qu’on lui donne en paramètre en inversant l’ordre +# des caractères. + +# Avertissement Utilisez le paramètre optionnel end de la fonction print pour +# éviter les passages à la ligne non désirés. + +def imprimer_envers1(chaine): + """ + Imprime la chaîne donnée en paramètre en inversant l’ordre des caractères. + str → ∅ + CU : chaine du type str + """ + assert(type(chaine) is str), "chaine doit être du type str" + + affichage = '' + for i in chaine: + affichage = i + affichage + print(affichage) + +# >>> imprimer_envers1('Timoleon') +# noelomiT +# >>> imprimer_envers1('') +# + +def imprimer_envers2(chaine): + """ + Imprime la chaîne donnée en paramètre en inversant l’ordre des caractères. + str → ∅ + CU : chaine du type str + """ + assert(type(chaine) is str), "chaine doit être du type str" + + affichage = '' + if len(chaine) > 0: + for i in range(-1, -len(chaine)-1, -1): + print(i, chaine[i]) + affichage += chaine[i] + print(affichage) + +# >>> imprimer_envers2('Timoleon') +# noelomiT +# >>> imprimer_envers2('') +# + + +# Exercice Miroir + +# Réalisez une fonction miroir qui renvoie une chaîne contenant les +# caractères de la chaîne qu’on lui donne en paramètre dans l’ordre +# inverse. + +def miroir(chaine): + """ + Renvoie une chaîne contenant les caractères de la chaîne donnés en paramètre + dans l’ordre inverse. + str → str + CU : chaine du type str + + >>> miroir ('Timoleon') + 'noelomiT' + >>> miroir ('') + '' + """ + assert(type(chaine) is str), "chaine doit être du type str" + + retour = '' + if len(chaine) > 0: + for i in range(-1, -len(chaine)-1, -1): + retour += chaine[i] + return retour + +# Exercice Palindrome + +# Un palindrome est un mot qui se lit de la même façon de gauche à droite +# et de droite à gauche. Par exemple, ICI, ELLE et RADAR sont des +# palindromes. + +# Par extension, une chaîne de caractères est dite palindromique si la +# liste de ses caractères parcourus de gauche à droite est la même que +# celle de ses caractères parcourus de droite à gauche. Par exemple, la +# chaîne 'A, 1 b+b 1 ,A' est palindromique + +# Le but est de réaliser un prédicat est_palindromique qui renvoie + +# True si la chaîne passée en paramètre est palindromique +# False dans le cas contraire. +# >>> est_palindromique ('Timoleon') +# False +# >>> est_palindromique ('RADAR') +# True +# >>> est_palindromique ('A, 1 b+b 1 ,A') +# True + +# Réalisez ce prédicat en utilisant la fonction miroir de l’exercice précédent. + +def est_palindromique1(chaine): + """ + Indique si la chaîne passée en paramètre est palindromique + str → bool + CU : mot est du type str + + >>> est_palindromique1('Timoleon') + False + >>> est_palindromique1('A, 1 b+b 1 ,A') + True + >>> est_palindromique1('') + True + """ + assert(type(chaine) is str), "chaine doit être du type str" + + return chaine == miroir(chaine) + +# Réalisez une autre version sans utiliser la fonction miroir. + +def est_palindromique2(chaine): + """ + Indique si la chaîne passée en paramètre est palindromique + str → bool + CU : mot est du type str + + >>> est_palindromique1('Timoleon') + False + >>> est_palindromique1('A, 1 b+b 1 ,A') + True + >>> est_palindromique1('') + True + """ + assert(type(chaine) is str), "chaine doit être du type str" + + longueur = len(chaine) # On crée une variable pour éviter + # de trop appeler len() + if longueur > 0: + for i in range(longueur): + if chaine[longueur-i-1] != chaine[i]: + return False + return True + + +# Exercice Longueur d’une chaîne + +# La fonction len renvoie la longueur de la chaîne de caractères qu’on lui +# passe en paramètre. + +# Sans utiliser cette fonction, réalisez une fonction qui fait exactement +# la même chose. + +def my_len(chaine): + """ + Renvoie la longueur de la chaîne de caractères passée en paramètre. + str → int + CU : chaine est du type str + + >>> my_len ('') + 0 + >>> my_len ('abcd') + 4 + >>> my_len ('esope reste ici et se repose') + 28 + """ + assert(type(chaine) is str), "chaine doit être du type str" + + a = 0 + for i in chaine[:]: + a += 1 + return a + + +# Exercice Suppression d’un caractère + +# Réalisez une fonction qui renvoie une chaîne obtenue en supprimant le +# caractère d’indice i d’une chaîne s, l’indice et la chaîne s étant +# passés en paramètres. + +def sauf(s, i): + """ + Renvoie une chaîne obtenue en supprimant le caractère d’indice + i d’une chaîne s, l’indice et la chaîne s étant passés en paramètres. + (str, int) → str + CU : s du type str et 0 ≤ i < len(s) + + >>> sauf('Timoleon', 3) + 'Timleon' + """ + assert(type(s) is str), "s doit être du type str" + assert(i >= 0 and i < len(s)), "i doit être dans l'intervalle [0, len(s)[" + + return s[:i] + s[i + 1:] + +# Vous pourrez supposer que l’indice est un entier positif ou nul. + +# >>> s = 'Timoleon' +# >>> for i in range(len(s)): +# ... print(sauf(s, i)) +# ... +# imoleon +# Tmoleon +# Tioleon +# Timleon +# Timoeon +# Timolon +# Timolen +# Timoleo + + +# Que renvoie votre fonction si l’indice passé en paramètre est négatif ? + +# En premier test, la fonction déclenche une erreur d'assertion. +# En enlevant les assertions, l'instruction sauf(s, -i) (pour i positif) + + +# Exercice Nombre d’occurrences + +# Réalisez une fonction qui renvoie le nombre d’occurrences d’un caractère +# dans une chaîne, le caractère et la chaîne étant passés en paramètre. + +def nbre_occurrences(caractere, chaine): + """ + Renvoie le nombre d’occurrences d’un caractère dans une chaîne, le caractère + et la chaîne étant passés en paramètre. + (str, str) → int + CU : caractere de type str de taille 1 et chaine de type str + + >>> nbre_occurrences ('o', 'Timoleon') + 2 + >>> nbre_occurrences ('y', 'Timoleon') + 0 + >>> nbre_occurrences (' ', 'esope reste ici et se repose') + 5 + """ + assert(type(caractere) is str and len(caractere) == 1), \ + "caractere doit être du type str et de taille 1" + assert(type(chaine) is str), "chaine doit être du type str" + + nombre = 0 + for i in chaine: + if i == caractere: + nombre += 1 + return nombre + + +# Exercice Suppression des occurences d’un caractère + +# Réalisez une fonction qui renvoie une chaîne obtenue en supprimant +# toutes les occurrences d’un caractère dans une chaîne, ce caractère et +# cette chaîne étant passés en paramètres. + +def supprime_car(caractere, chaine): + """ + Renvoie une chaîne obtenue en supprimant toutes les occurrences d’un + caractère dans une chaîne, ce caractère et cette chaîne étant passés en + paramètres. + (str, str) → str + CU : caractere de type str de taille 1 et chaine de type str + + >>> supprime_car ('o', 'Timoleon') + 'Timlen' + >>> supprime_car ('y', 'Timoleon') + 'Timoleon' + """ + assert(type(caractere) is str and len(caractere) == 1), \ + "caractere doit être du type str et de taille 1" + assert(type(chaine) is str), "chaine doit être du type str" + + retour = '' + for i in chaine: + if i != caractere: + retour += i + return retour + + +# La phrase esope reste ici et se repose n’est pas un palindrome au sens +# donné dans l’exercice ci-dessus. Mais si on ne regarde que les lettres, +# c’est un palindrome. + +# Comment vérifier ce point avec les fonctions supprime_car et +# est_palindromique ? + +# On peut utiliser la composée des deux fonctions de la façon suivante +# (chaine étant la chaine dont on souhaite vérifier si elle est palindromique) + +# est_palindromique(supprime_car(' ', chaine)) + +# On peut même enlever les points, les virgules et toute autre ponctuation +# génante + +# est_palindromique(supprime_car(' ', supprime_car(',', supprime_car('.', \ +# supprime_car('!', supprime_car('?', chaine)))))) + +# Cependant, créer une nouvelle fonction qui supprime tous les caractères d'une +# contenus dans une liste serait plus approprié dans ce cas. + + +# Exercice Remplacement d’un caractère + +# Réalisez une fonction qui remplace le caractère d’un indice donné d’une +# chaîne de caractères par une autre chaîne de caractères. + +def remplace_indice(chaine, indice, remplacement): + """ + Remplace le caractère d’un indice donné d’une chaîne de caractères par une + autre chaîne de caractères. + (str, int, str) → str + CU : chaine de type str et indice de type int et remplacement de type str + + >>> remplace_indice ('Timileon',3,'o') + 'Timoleon' + >>> remplace_indice ('Tixleon',2,'mo') + 'Timoleon' + """ + assert(type(chaine) is str), "chaine doit être du type str" + assert(type(indice) is int), "indice doit être du type int" + assert(type(remplacement) is str), "remplacement doit être du type str" + + return chaine[:indice] + remplacement + chaine[indice + 1:] + +# Réalisez une fonction qui remplace dans une chaîne donnée toutes les +# occurences d’un caracère donné par une autre chaîne de caractères. + +def remplace_occurrences(chaine, caractere, remplacement): + """ + Remplace dans une chaîne donnée toutes les occurences d’un caracère donné + par une autre chaîne de caractères. + (str, str, str) → str + CU : chaine de type str et caractere du type str et de taille 1 et + remplacement de type str + + >>> remplace_occurrences ('@ 3 est le neveu de @ 1er.','@','Napoléon') + 'Napoléon 3 est le neveu de Napoléon 1er.' + """ + assert(type(chaine) is str), "chaine doit être du type str" + assert(type(caractere) is str and len(caractere) == 1), \ + "caractere doit être du type str et de taille 1" + assert(type(remplacement) is str), "remplacement doit être du type str" + + retour = '' + for i in chaine: + if i == caractere: + retour += remplacement + else: + retour += i + return retour + + + +def tester(): + doctest.testmod(verbose=True)