Corrections - chapitre 1 à 5
Comme j'ai dit lors de la présentation des exercices, il existe beaucoup de façon pour programmer.
Je vais donc corriger avec ma méthode mais si vous avez codé différemment et que vous avez le même
résultat, ne modifié pas votre code pour prendre le mien.
Le morpion
Bon pour ce jeu, j'ai décidé d'expliquer en séparant mon code. Je vous donne l'ensemble puis
je détaillerai le code en expliquant les fonctions une à une.
Voici donc l'ensemble du code (j'ai volontairement enlevé l'intérieur des fonctions pour que vous
voyez plus facilement le fonctionnement):
## morpion.py
## -------------
## Réaliser par ROMMY.P le 11/01/2009
## Pour le tutoriel du site ROMMY Production "http://rommyprod.com"
import string
# place le symbole du joueur sur la case demandée et retourne
# la valeur de tour (inchangée sauf si la case demandée
# est remplie)
def placer(tour, nom_j1, nom_j2):
...
# affiche le morpion
def affichage(A1,A2,A3,B1,B2,B3,C1,C2,C3):
...
# vérifie si 3 symboles identiques sont alignés
# et modifie "fini" si c'est le cas.
def verification(A1,A2,A3,B1,B2,B3,C1,C2,C3, nom_j1, nom_j2):
...
tour_joueur = 0
fini =
False
A1, A2, A3 = " ", " ", " "
B1, B2, B3 = " ", " ", " "
C1, C2, C3 = " ", " ", " "
case_remplie = 0
nom_joueur1 =
input(
"entrez le nom du 1er joueur, vous aurez les X: ")
nom_joueur2 =
input(
"entrez le nom du 2eme joueur, vous aurez les O: ")
affichage(A1,A2,A3,B1,B2,B3,C1,C2,C3)
while not fini :
tour_joueur = placer(tour_joueur, nom_joueur1, nom_joueur2)
tour_joueur += 1
affichage(A1,A2,A3,B1,B2,B3,C1,C2,C3)
verification(A1,A2,A3,B1,B2,B3,C1,C2,C3, nom_joueur1, nom_joueur2)
if case_remplie == 9
and not fini:
print (
"match nul")
fini =
True
Vous pouvez aussi télécharger
le code source
Le programme en lui-même
Voilà le temps d'approfondir est arrivé.
Je vais faire comme l'ordinateur, je vais commencer par le commencement.
Je vais vous montrer toutes les variables utiles et comment ce déroule le programme. Initialisé
les variables en début de programmes ou fonctions est une habitude que j'ai prise d'un autre langage.
Vous pouvez les déclarer plus tard mais bien sûr avant de les utiliser. Si vous faites ça, faites
très attention à la notion de variables globales et locales.
tour_joueur = 0
fini = False
A1, A2, A3 = " ", " ", " "
B1, B2, B3 = " ", " ", " "
C1, C2, C3 = " ", " ", " "
case_remplie = 0
nom_joueur1 = input("entrez le nom du 1er joueur, vous aurez les X: ")
nom_joueur2 = input("entrez le nom du 2eme joueur, vous aurez les O: ")
affichage(A1,A2,A3,B1,B2,B3,C1,C2,C3)
while not fini :
tour_joueur = placer(tour_joueur, nom_joueur1, nom_joueur2)
tour_joueur += 1
affichage(A1,A2,A3,B1,B2,B3,C1,C2,C3)
verification(A1,A2,A3,B1,B2,B3,C1,C2,C3, nom_joueur1, nom_joueur2)
if case_remplie == 9 and not fini:
print ("match nul")
fini = True
- "tour_joueur" sert à savoir à qui est le tour. (on va s'en servir dans la fonction "placer").
- "fini" sert à savoir si on à fini. Elle vaut Vrai(True) ou Faux(False).
- A1, ..., C3 correspondent aux 9 cases. Elles sont initialisées avec la valeur " " pour dire
quelles sont vides, puis prendront soit la valeur "X", soit "O".
- "case_remplie" sert à savoir combien de case on était remplie.
- "nom_joueur" sert à connaître le nom du joueur.
Ensuite on affiche une première fois le morpion où toutes les cases sont vides.
C'est à partir de ce moment que le programme commence vraiment car on entre dans la boucle.
Que fait cette boucle ?
Et bien en fait, elle nous dit que tant que nous n'avons pas fini, elle continuera le
programme. Donc tant que l'on n'aura pas mis "fini" à True, le jeu continuera.
Le programme consiste à
placer le symbole grâce à la fonction "placer", je vous expliquerai en
détail pourquoi j'ai mis "tour_joueur = placer..." quand je vous décrirai cette fonction. Ne faites
donc pas attention, cette fonction sert à placer un symbole. Cette fonction fera aussi augmenter
la valeur de "case_remplie"
Ensuite on
ajoute 1 à tour_joueur pour dire que c'est au suivant. Pour savoir quel est le
joueur, on regarde si cette valeur est paire ou non (ça aussi je l'expliquerai dans la fonction
"placer").
Ensuite on
affiche le morpion avec le symbole ajouté.
Puis on
vérifie si 3 symboles sont alignés avec la procédure "vérification". Si c'est le cas, la
variable fini sera changée en True.
Et on termine en testant si
toutes les cases sont remplies, et que l'on à pas fini (réussi à
aligner). Pour dire que c'est un match nul et terminer le jeu car on ne peut plus rien placer.
La fonction placer
Maintenant nous allons aller dans les entrailles de la fonction placer, je vous expliquerai le
pourquoi de "tour_joueur = ..." (en fait, j'aurai pu faire autrement mais je voulais absolument vous
montrer une fonction.
# place le symbole du joueur sur la case demandée et retourne
# la valeur de tour (inchangée sauf si la case demandée
# est remplie)
def placer(tour, nom_j1, nom_j2):
global A1, A2, A3, B1, B2, B3
global C1, C2, C3, case_remplie
# on regarde c'est le tour de quel joueur.
if tour%2 == 0:
symbole = "X"
nom = nom_j1
else :
symbole = "O"
nom = nom_j2
texte = nom + ", où voulez vous placer (ex: A1) : "
case = input(texte)
case = case.upper()
# on place le symbole à la case demandée
if case == "A1" and A1 == " ":
A1 = symbole
case_remplie += 1
elif case == "A2" and A2 == " ":
A2 = symbole
case_remplie += 1
elif case == "A3" and A3 == " ":
A3 = symbole
case_remplie += 1
elif case == "B1 and B1 == " ":
B1 = symbole
case_remplie += 1
elif case == "B2" and B2 == " ":
B2 = symbole
case_remplie += 1
elif case == "B3" and B3 == " ":
B3 = symbole
case_remplie += 1
elif case == "C1" and C1 == " ":
C1 = symbole
case_remplie += 1
elif case == "C2" and C2 == " ":
C2 = symbole
case_remplie += 1
elif case == "C3" and C3 == " ":
C3 = symbole
case_remplie += 1
else :
print ("la case est déjà remplie, ou vous n'avez pas tapez une case valide.")
tour -= 1
return tour
Tout d'abord, cette fonction à trois paramètres, qui sont : le nombre de tours et les noms des deux
joueurs. J'ai fait exprès de mettre des noms différents pour que vous ne croyiez pas que ce soit les
mêmes variables. Je vous dis,
ne mettez pas les mêmes noms car c'est ce que j'ai malheureusement
l'habitude de faire et ça me crée bien des problèmes de confusion. Je vous rappelle que les paramètres
sont des copies, ici "tour" est une copie de "tour_joueur", etc...
Les variables A1, ..., C3 et case_remplie peuvent être vu par la fonction et celle-ci pourra les
modifier car on a transformé ces variables en variables globales grâce à "global".
Ensuite
on regarde à qui est le tour pour savoir quel symbole on va mettre. Vous avez vu au
début que j'ajoutais 1 à chaque tour. On ne sait donc pas à qui est le tour. Pour ça, je vais tester si
le tour est pair ou non. Si c'est pair, c'est le joueur 1 sinon le 2.
Pour tester la parité, on regarde si le reste de la division par 2 vaut 0.
Donc 0, 2, 4 ... sont des chiffres pairs et 1, 3, 5 ... impair (ex : 4/2 donne 2 puis 2/2 donne 0, il
n'y a donc pas de reste. Par contre 5/2 a un reste de 1 donc 5 est impair.)
Maintenant que l'on sait à qui est le tour, on peut lui attribuer son symbole.
Je vous avais donné lors de l'énoncé une autre méthode plus simple mais je voulais que vous ayez vu
au moins une fois comment on se sert de la parité).
Ensuite
on demande au joueur où il veut placer son symbole. On le transforme en majuscule pour
faire moins de tests. (je vous l'avais expliqué lors de l'énoncé.)
Puis on teste si la case demandée existe (par exemple A4 n'existe pas), et si la case est vide.
Si ce n'est pas le cas, on dit que la case est remplie et on redonne le tour au joueur. J'ai donc
enlevé un point au tour car il sera augmenter à la sortie de la fonction, ainsi tour_joueur n'aura
pas changé et on sera toujours au même joueurs.
Et on finit par renvoyé "tour" qui aura été modifie ou non. On a vu que c'est tour_joueur qui récupère
cette valeur.
L'affichage
Maintenant on va attaquer la procédure "affichage". Bien sûr vous pouvez changer l'affichage si
celui-ci ne vous plait pas.
# affiche le morpion
def affichage(A1,A2,A3,B1,B2,B3,C1,C2,C3):
print ("\n A B C")
print ("#############")
print ("#", A1, "|", B1, "|", C1, "# 1")
print ("#---+---+---#")
print ("#", A2, "|", B2, "|", C2, "# 2")
print ("#---+---+---#")
print ("#", A3, "|", B3, "|", C3, "# 3")
print ("#############\n")
On a besoin que des variables représentant les cases, c'est pour cela qu'il n'y a pas d'autres
paramètres.
Chaque "print" représente une ligne, donc on commence par afficher comment nommée les colonnes.
Le caractère \n veut dire "aller à la ligne". Je vous rappelle qu'à chaque print, il y a une nouvelle
ligne (sauf s'il y a une virgule en fin du print précedent). Donc on va à la ligne grâce au "print"
puis on va de nouveau à la ligne avec le "\n" ce qui fait que l'on a maintenant une ligne vide avant
d'afficher " A B C ", ce qui permet d'éclaircir l'affichage.
Ensuite on affiche le contour du haut. Puis on affiche les cases correspondant à la ligne 1. Puis une
ligne séparatrice, la ligne 2, une ligne séparatrice, la ligne trois et pour finir le contour du bas.
Vous pouvez voir que là aussi j'ai mis "\n" car je veux aussi qu'il y ait une ligne d'espace en
dessous du morpion.
La procédure "vérification"
Et pour finir, je vais vous expliquer comment déterminer le vainqueur.
# vérifie si 3 symboles identiques sont alignés
# et modifie "fini" si c'est le cas.
def verification(A1,A2,A3,B1,B2,B3,C1,C2,C3, nom_j1, nom_j2):
global fini
if ((A1 == A2 and A1 == A3) or (A1 == B1 and A1 == C1) or (A1 == B2 and A1 == C3)) and A1 != " ":
if A1 == "X":
print ("Bravo", nom_j1, "vous avez gagné")
else :
print ("Bravo", nom_j2, "vous avez gagné")
fini = True
elif ((B1 == B2 and B2 == B3) or (A2 == B2 and B2 == C2) or (A3 == B2 and B2 == C1)) and B2 != " ":
if B2 == "X":
print ("Bravo", nom_j1, "vous avez gagné")
else :
print ("Bravo", nom_j2, "vous avez gagné")
fini = True
elif ((C1 == C3 and C2 == C3) or (A3 == C3 and B3 == C3)) and C3 != " ":
if C3 == "X":
print ("Bravo", nom_j1, "vous avez gagné")
else :
print ("Bravo", nom_j2, "vous avez gagné")
fini = True
On aura besoin de modifier "fini" au cas où 3 symboles seraient alignés, donc on utilise "global".
Puis on commence les testent pour voir si les 3 symboles sont identiques (on teste si la valeur des
trois cases est identique).
Le premier "if" teste :
- La première ligne avec "A1 == B1 and A1 == C1". Ca teste si la case A1 est identique à B1
et si c'est identique à C1. Si l'une des deux conditions est fausse, le if n'est pas
réalisé. De ces deux tests, on en conclue que B1 est identique à C1 ou non.
- La première colonne avec "A1 == A2 and A1 == A3", même chose avec la colonne A.
- La diagonale descendante avec "A1 == B2 and A1 == C3", même chose avec la diagonale.
Vous pouvez voir que chaque test est compris entre paranthèse car c'est soit la 1ère ligne, soit
la 1ère colonne, soit la diagonale. Par contre il y a un test qui est en dehors de la parenthèse
regroupant ces trois tests car c'est l'une des trois conditions plus la quatrième.
Donc si l'une des trois conditions est vraie
et que A1 est non vide (and A1 != " "), on peut
dire au joueur qu'il a gagné.
J'ai pris A1 pour tester si la case était vide car comme vous pouvez le remarquer, c'est le point
commun entre les trois tests (cette case est présente partout).
Le premier "elif" teste :
- La deuxième colonne avec "B1 == B2 and B2 == B3".
- La deuxième ligne avec "A2 == B2 and B2 == C2".
- La diagonale ascendante avec "A3 == B2 and B2 == C1".
Et on teste si B2 n'est pas vide car c'est le point commun.
Le deuxième "elif" teste :
- La troisième colonne avec "C1 == C3 and C2 == C3".
- La troisième ligne avec "A3 == C3 and B3 == C3".
Et on teste si C3 n'est pas vide car c'est le point commun.
J'ai volontairement oublié de vous expliqué comment savoir qui est le gagnant car je ne voulais pas
vous interrompre dans votre lancé.
Etant à l'intérieur du if, cela veut dire que les conditions sont vraies. Donc les cases sont
identiques au point commun de tous les tests. On va donc tester cette case en particulier.
On teste la valeur de la case. Si c'est "X", ça correspond au joueur 1 sinon au 2. Faites attention,
il faut que les paramètres soit les mêmes que pour la fonction placer. Je m'explique, si vous avez
donné au joueur 1 les "X" (c'est le cas ici) et que vous mettez son nom pour le paramètre nom_j2, il
y aura une inversion et le gagnant ne sera pas le bon.
Si vous avez fait "tour_joueur = placer(tour_joueur,nom_joueur1,nom_joueur2)" et qu'après vous
mettez "verification(A1,A2,A3,B1,B2,B3,C1,C2,C3,
nom_joueur2,nom_joueur1)" à la place de
"verification(A1,A2,A3,B1,B2,B3,C1,C2,C3,
nom_joueur1,nom_joueur2)", le gagnant sera en fait
le perdant. A moins que vous ayez aussi inversé à l'intérieur de la fonction.