En 2021 pour les cours de NSI nous avions un projet de fin d’année qui consistait, seul ou en groupe a trouver une idée de projet et le réaliser en python du début à la fin. Pour me donner un peu de défi pour cette fin d’année j’ai donc eu cette idée de projet à faire tout seul : un jeu d’échec en python.
Nous devions avant cela créer un cahier des charges de ce qu’on voulait faire. L’objectif était donc que 2 joueurs puissent jouer sur le même ordinateur, avec des affichages simples (des lettres, des espaces et des traits), et que pour l’instant il n’y ai pas la règle du rock, et que les échecs, et échecs et mat ne soit pas gérer automatiquement, si le roi est mangé cela fait gagné l’autre joueur, mais la règle de promotion et du mouvement de 2 cases des pions sont présentes.
Le projet est donc séparé en 4 fichiers que je vais détailler juste après :
- main.py
- mouvement.py
- jeu.py
- affichage.py
Affichage.py
Le fichier Affichage.py va gérer l’affichage de la grille de jeu aux joueurs. Il fallait donc l’afficher avec des caractères simple, des lettres pour les pions (“T” pour la tour, “Q” pour la reine, …) et pour la grille simplement des traits. Il fallait aussi veiller a respecter la notation des cases du jeu d’échecs (c’est à dire : de 1 à 8 pour la hauteur et de “a” à “h” pour la largeur)
Ensuite j’ai créé 2 grilles pour stocker la position des pions des deux joueurs. Pourquoi deux ? Pour pouvoir plus facilement colorer les pions du joueurs dont c’est le tour. J’utilise d’ailleurs la bibliothèque Colorama pour pouvoir colorer le texte dans la console
Je vérifie par la suite le contenu d’une troisième grille qui stocke les positions possible de mouvement de la pièce sélectionné, et qui note la position de la pièce sélectionné pour pouvoir la colorer d’une autre couleur
Ce qui nous donne :
def afiche(grille, grille2, grilleposs):
"""
affiche la grille de jeu ainsi que les pions des joueurs
"""
for j in range(len(grille)): #fait une boucle du nombre de ligne
""" Premiere case avec le numéro """
ligne = str(8-j) + Fore.WHITE + " |" #ajout du numero de la ligne
for i in range(len(grille[j])):#fait une boucle du nombre de colonne
if grille[j][i] != " ": #si la case ne contient pas d'espace :
if grilleposs[j][i] == "-": #si contient un "-"
ligne += str(Fore.BLUE + grille[j][i])+ Fore.WHITE + "|" #affiche la piece en bleu
elif grilleposs[j][i] == "x":
ligne += str(Fore.YELLOW + grille[j][i])+ Fore.WHITE + "|"
else:
ligne += str(grille[j][i])+ Fore.WHITE + "|" #ajoute la case avec le pions
else:
if grilleposs[j][i] == "-": # si la grille des possibilités contient un "-" et se trouve sur une case ennemi :
if grille2[j][i] == " ":#si aucune pieces dessus
ligne += str(Fore.BLUE + grilleposs[j][i])+ Fore.WHITE + "|" #affiche un "-"
else:
ligne += str(Fore.BLUE + grille2[j][i])+ Fore.WHITE + "|" #affiche la piece en bleu
elif grilleposs[j][i] == "x":
ligne += str(Fore.YELLOW + grille[j][i])+ Fore.WHITE + "|"
else:
ligne += str(Fore.RED + grille2[j][i])+ Fore.WHITE + "|" #sinon l'affiche en rouge
print(ligne) #affiche la ligne
print(" -a-b-c-d-e-f-g-h-")
print()
Mouvement.py
Le fichier Mouvement.py va permettre de définir les cases où peut se déplacer la pièce qui a été sélectionnée.
Pour cela nous allons compléter la grille des positions possible (vu plus haut) pour afficher des tirets bleu aux endroits où c’est possibles de se déplacer, ensuite nous afficherons en bleu les pièces que nous pouvons manger et nous affichons la pièce sélectionnée en jaune.
Pour afficher la pièce sélectionnée en jaune c’est très simple : nous ajoutons un “x” dans la grille des positions à la position de la pièce et dans le fichier d’affichage nous avons précisé que si à la position d’une pièce dans la grille des positions il y a un “x” nous le colorons en jaune (caseD étant les coordonnées de la case sélectionnée)
grilleposs[caseD[0]][caseD[1]] = "x" #ajoute sur la case du pion un "x" pour le colorer en jaune
Et dans le fichier affichage.py :
elif grilleposs[j][i] == "x":
ligne += str(Fore.YELLOW + grille[j][i])+ Fore.WHITE + "|"
Pour le mouvement d’une pièce La fonction parcours la grille d’échecs, examine la pièce à la position caseD
, et ajouter des indicateurs “-” sur la grille grilleposs
pour marquer les cases où cette pièce peut se déplacer. Le code est spécifique pour chaque type de pièce (pion, cavalier, tour, fou, reine, roi) et tient compte des règles de déplacement de chaque pièce.
prenons l’exemple du pion pour le joueur 1 :
if grille[caseD[0]][caseD[1]] == "p":
if caseD[0] != 6:
if grille[caseD[0] - 1][caseD[1]] == " " and grilleVS[caseD[0] -1][caseD[1]] == " ":
grilleposs[caseD[0] - 1][caseD[1]] = "-"
if caseD[1]> 0:
if grilleVS[caseD[0] - 1][caseD[1] - 1] != " ":
grilleposs[caseD[0] - 1][caseD[1] - 1] = "-"
if caseD[1]< 7:
if grilleVS[caseD[0] - 1][caseD[1] + 1] != " ":
grilleposs[caseD[0] - 1][caseD[1] + 1] = "-"
else:
if grille[caseD[0] - 1][caseD[1]] == " " and grilleVS[caseD[0] -1][caseD[1]] == " ":
grilleposs[caseD[0] - 2][caseD[1]] = "-"
if grille[caseD[0] - 2][caseD[1]] == " " and grilleVS[caseD[0] -2][caseD[1]] == " ":
grilleposs[caseD[0] - 1][caseD[1]] = "-"
if caseD[1]> 0:
if grilleVS[caseD[0] - 1][caseD[1] - 1] != " ":
grilleposs[caseD[0] - 1][caseD[1] - 1] = "-"
if caseD[1]< 7:
if grilleVS[caseD[0] - 1][caseD[1] + 1] != " ":
grilleposs[caseD[0] - 1][caseD[1] + 1] = "-"
Le premier if permet de regarder si le pion c’est déjà déplacé ou non, car si il n’a pas bougé il a la possibilité de se déplacer de 2 cases. Dans le cas où il as bougé on regarde la première case devant lui et on vérifie si il y a une pièce ou non (pour savoir si il peut avancer) si il y en a pas on peut ajouter un tiret à cette case. Ensuite on regarde les cases en diagonales pour voir si il y a des pièces ennemi et on ajoute un tiret pour prévenir qu’on peut les manger.
Et nous faisons pareil dans le cas ou elle n’as pas bougé (sauf que nous vérifions d’abord une première fois si il peut avancer sur la case devant lui avant de vérifier qu’il peut aller sur la case encore plus loin
Jeu.py
L’avant dernier fichier est le plus important car c’est lui qui met en place les tours de jeu.
Un tour se déroule comme ceci :
- On vide la grille des positions possibles avec les tirets
- On met à jour la grille affiché
- On demande la pièce que le joueur veut bouger
- On vérifie qu’il n’y a pas d’erreur et que la pièce existe bien
- On appelle le fichier mouvement pour voir les possibilité de la pièce sélectionné
- On demande ensuite la case d’arriver de la pièce
- On vérifie que la case existe bien et qu’il peut se déplacer la bas
- On le déplace
- Si c’est un pion qui atteint le bord adverse du plateau on le transforme en reine
- On vérifie si il y a un roi mangé (et si c’est le cas déclarons la victoire a l’autre joueur)
- On vérifie que il n’y a pas que les 2 rois en jeu (sinon égalité)
- A la fin nous renvoyons l’état du tour (victoire / égalité / rien (si le jeu continue))
Et voilà nous avons notre tour de jeu, l’affichage de la grille et la gestion des mouvement plus qu’à relié tout ça dans le main pour avoir notre jeu fonctionnel.
Main.py
Le fichier main est le fichier principal du projet, il va lancer le tutoriel, puis lancer le jeu et appeler les autres fichier pour récupérer leur contenu et fonctions et faire que tout fonctionne bien les uns avec les autres.
Tout d’abord au début du jeu le main créer 2 grille pour chaque joueur avec leurs pièces aux bons endroits
grilleJ2 = [ # grille des pions du joueur 2
["T","C","F","Q","R","F","C","T"],
["P","P","P","P","P","P","P","P"],
[" "," "," "," "," "," "," "," "],
[" "," "," "," "," "," "," "," "],
[" "," "," "," "," "," "," "," "],
[" "," "," "," "," "," "," "," "],
[" "," "," "," "," "," "," "," "],
[" "," "," "," "," "," "," "," "]
]
grilleJ1 = [ # grille des pions du joueur 1
[" "," "," "," "," "," "," "," "],
[" "," "," "," "," "," "," "," "],
[" "," "," "," "," "," "," "," "],
[" "," "," "," "," "," "," "," "],
[" "," "," "," "," "," "," "," "],
[" "," "," "," "," "," "," "," "],
["p","p","p","p","p","p","p","p"],
["t","c","f","q","r","f","c","t"]
]
Ensuite nous lançons le tutoriel pour le joueur afin qu’il comprenne les différentes couleurs et commandes en utilisant la classe Fore
du module colorama
pour changer les couleurs dans la console, et nous attendons qu’il appuie sur “Entrée” pour lui lancer le jeu :
On lance le tour du joueur numéro 1 avec la fonction du fichier “Jeu.py”
On verifié ensuite que le jeu n’est pas en égalité ni en victoire de la part d’un des deux joueurs si c’est le cas nous stoppons le jeu :
if Jeu == "J1": #si le Jeu.tour() retourne J1 : victoire du joueur 1
os.system("clear")
affichage.afiche(grilleJ2,grilleJ1,grillePoss) #remet à jour la grille
print("Victoire J1")
break #sort de la boucle
elif Jeu == "Draw": #si renvoie Draw -> egalité
os.system("clear")
affichage.afiche(grilleJ2,grilleJ1,grillePoss)
print("Egalité")
break
On fait pareil pour le joueur numéro 2 et nous relançons un nouveau tour si il n’y a toujours pas de vainqueur ni d’égalité.
Conclusion
En conclusion ce projet m’as amener beaucoup. Il m’a permit de réaliser un projet de A à Z, de l’imagination du fonctionnement jusqu’au code et à la présentation de celui-ci devant la classe en fin d’année. Il m’a permit aussi de repousser mes limites en allant vers un projet où je ne savait pas au début si j’allais le réussir ou non mais qui en pratique fut beaucoup plus simple que ce que je pensais.
A vrai dire ce projet n’est pas 100% finis il reste quelque règles à ajouter (comme le rock ou la prise en passant), il reste aussi la vérification automatique des échecs et mat, les coups interdits ( c’est à dire bouger une pièce qui permettrai directement à l’adversaire de prendre le roi) ou encore une petite IA contre qui jouer.
Ce sera peut être pour une prochaine fois (même si en réobservant ce projet 1 an plus tard je pense que si je devais le refaire ce serait pas de la même manière (notamment pas avec deux grille différentes)