Beispiel #1
0
class Partie:
    """La classe Partie contient les informations sur une partie d'échecs, c'est à dire un échiquier, puis
    un joueur actif (blanc ou noir). Des méthodes sont disponibles pour faire avancer la partie et interagir
    avec l'utilisateur.

    Attributes:
        joueur_actif (str): La couleur du joueur actif, 'blanc' ou 'noir'.
        echiquier (Echiquier): L'échiquier sur lequel se déroule la partie.

    """
    def __init__(self):
        # Le joueur débutant une partie d'échecs est le joueur blanc.
        self.joueur_actif = 'blanc'

        # Création d'une instance de la classe Echiquier, qui sera manipulée dans les méthodes de la classe.
        self.echiquier = Echiquier()

    def determiner_gagnant(self):
        """Détermine la couleur du joueur gagnant, s'il y en a un. Pour déterminer si un joueur est le gagnant,
        le roi de la couleur adverse doit être absente de l'échiquier.

        Returns:
            str: 'blanc' si le joueur blanc a gagné, 'noir' si c'est plutôt le joueur noir, et 'aucun' si aucun
                joueur n'a encore gagné.

        """

        if not self.echiquier.roi_de_couleur_est_dans_echiquier('noir'):
            return 'blanc'
        elif not self.echiquier.roi_de_couleur_est_dans_echiquier('blanc'):
            return 'noir'

        return 'aucun'

    def partie_terminee(self):
        """Vérifie si la partie est terminée. Une partie est terminée si un gagnant peut être déclaré.

        Returns:
            bool: True si la partie est terminée, et False autrement.

        """
        toutes_les_position = [
            'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'b1', 'b2', 'b3',
            'b4', 'b5', 'b6', 'b7', 'b8', 'c1', 'c2', 'c3', 'c4', 'c5', 'c6',
            'c7', 'c8', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'e1',
            'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8', 'f1', 'f2', 'f3', 'f4',
            'f5', 'f6', 'f7', 'f8', 'g1', 'g2', 'g3', 'g4', 'g5', 'g6', 'g7',
            'g8', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'h7', 'h8'
        ]
        var = 0
        for i in toutes_les_position:
            if isinstance(
                    self.echiquier.recuperer_piece_a_position(i),
                    Pion) == True or isinstance(
                        self.echiquier.recuperer_piece_a_position(i),
                        Tour) == True or isinstance(
                            self.echiquier.recuperer_piece_a_position(i),
                            Fou) == True or isinstance(
                                self.echiquier.recuperer_piece_a_position(i),
                                Cavalier) == True or isinstance(
                                    self.echiquier.recuperer_piece_a_position(
                                        i), Dame) == True:
                var = 1
        if var == 0:
            return True
        else:
            return self.determiner_gagnant() != 'aucun'

    def demander_positions(self):
        """Demande à l'utilisateur d'entrer les positions de départ et d'arrivée pour faire un déplacement. Si les
        positions entrées sont valides (si le déplacement est valide), on retourne les deux positions. On doit
        redemander tant que l'utilisateur ne donne pas des positions valides.

        Returns:
            str, str: Deux chaînes de caractères représentant les deux positions valides fournies par l'utilisateurs.

        """
        while True:
            # On demande et valide la position source.
            while True:
                source = input("Entrez position source: ")
                if self.echiquier.position_est_valide(
                        source) and self.echiquier.couleur_piece_a_position(
                            source) == self.joueur_actif:
                    break

                print("Position invalide.\n")

            # On demande et valide la position cible.
            cible = input("Entrez position cible: ")
            if self.echiquier.deplacement_est_valide(source, cible):
                return source, cible

            print("Déplacement invalide.\n")

    def joueur_suivant(self):
        """Change le joueur actif: passe de blanc à noir, ou de noir à blanc, selon la couleur du joueur actif.

        """
        if self.joueur_actif == 'blanc':
            self.joueur_actif = 'noir'
        else:
            self.joueur_actif = 'blanc'

    def jouer(self):
        """Tant que la partie n'est pas terminée, joue la partie. À chaque tour :
            - On affiche l'échiquier.
            - On demande les deux positions.
            - On fait le déplacement sur l'échiquier.
            - On passe au joueur suivant.

        Une fois la partie terminée, on félicite le joueur gagnant!

        """
        while not self.partie_terminee():
            print(self.echiquier)
            print("\nAu tour du joueur {}".format(self.joueur_actif))
            source, cible = self.demander_positions()
            self.echiquier.deplacer(source, cible)
            self.joueur_suivant()

        print(self.echiquier)
        print("\nPartie terminée! Le joueur {} a gagné".format(
            self.determiner_gagnant()))
Beispiel #2
0
class Partie:
    """La classe Partie contient les informations sur une partie d'échecs, c'est à dire un échiquier, puis
    un joueur actif (blanc ou noir). Des méthodes sont disponibles pour faire avancer la partie et interagir
    avec l'utilisateur.

    Attributes:
        joueur_actif (str): La couleur du joueur actif, 'blanc' ou 'noir'.
        echiquier (Echiquier): L'échiquier sur lequel se déroule la partie.

    """
    def __init__(self):
        # Le joueur débutant une partie d'échecs est le joueur blanc.
        self.joueur_actif = 'blanc'

        # Création d'une instance de la classe Echiquier, qui sera manipulée dans les méthodes de la classe.
        self.echiquier = Echiquier()

    def determiner_gagnant(self):
        """Détermine la couleur du joueur gagnant, s'il y en a un. Pour déterminer si un joueur est le gagnant,
        le roi de la couleur adverse doit être absente de l'échiquier.

        Returns:
            str: 'blanc' si le joueur blanc a gagné, 'noir' si c'est plutôt le joueur noir, et 'aucun' si aucun
                joueur n'a encore gagné.

        """
        if not self.echiquier.roi_de_couleur_est_dans_echiquier('noir'):
            return 'blanc'
        elif not self.echiquier.roi_de_couleur_est_dans_echiquier('blanc'):
            return 'noir'

        return 'aucun'

    def partie_terminee(self):
        """Vérifie si la partie est terminée. Une partie est terminée si un gagnant peut être déclaré.

        Returns:
            bool: True si la partie est terminée, et False autrement.

        """
        return self.determiner_gagnant() != 'aucun'

    def demander_positions(self):
        """Demande à l'utilisateur d'entrer les positions de départ et d'arrivée pour faire un déplacement. Si les
        positions entrées sont valides (si le déplacement est valide), on retourne les deux positions. On doit
        redemander tant que l'utilisateur ne donne pas des positions valides.

        Returns:
            str, str: Deux chaînes de caractères représentant les deux positions valides fournies par l'utilisateurs.

        """
        while True:
            # On demande et valide la position source.
            while True:
                source = input("Entrez position source: ")
                if self.echiquier.position_est_valide(
                        source) and self.echiquier.couleur_piece_a_position(
                            source) == self.joueur_actif:
                    break

                print("Position invalide.\n")

            # On demande et valide la position cible.
            cible = input("Entrez position cible: ")
            if self.echiquier.deplacement_est_valide(source, cible):
                return source, cible

            print("Déplacement invalide.\n")

    def deplacer(self, position_source, position_cible):

        piece = self.echiquier.recuperer_piece_a_position(position_source)
        print("la piece est", piece)

        if piece is None:

            raise AucunePieceAPosition('Aucune pièce à cet emplacement')
        elif piece.couleur != self.joueur_actif:
            raise MauvaiseCouleurPiece(
                "La pièce source n'appartient pas au joueur actif")

        self.echiquier.deplacer(position_source, position_cible)
        self.joueur_suivant()

    def joueur_suivant(self):
        """Change le joueur actif: passe de blanc à noir, ou de noir à blanc, selon la couleur du joueur actif.

        """
        if self.joueur_actif == 'blanc':
            self.joueur_actif = 'noir'

        else:
            self.joueur_actif = 'blanc'

    def jouer(self):
        """Tant que la partie n'est pas terminée, joue la partie. À chaque tour :
            - On affiche l'échiquier.
            - On demande les deux positions.
            - On fait le déplacement sur l'échiquier.
            - On passe au joueur suivant.

        Une fois la partie terminée, on félicite le joueur gagnant!

        """
        while not self.partie_terminee():
            print(self.echiquier)
            print("\nAu tour du joueur {}".format(self.joueur_actif))
            source, cible = self.demander_positions()
            self.echiquier.deplacer(source, cible)
            self.joueur_suivant()

        print(self.echiquier)
        print("\nPartie terminée! Le joueur {} a gagné".format(
            self.determiner_gagnant()))
Beispiel #3
0
class Partie:
    """La classe Partie contient les informations sur une partie d'échecs, c'est à dire un échiquier, puis
    un joueur actif (blanc ou noir). Des méthodes sont disponibles pour faire avancer la partie et interagir
    avec l'utilisateur.

    Attributes:
        joueur_actif (str): La couleur du joueur actif, 'blanc' ou 'noir'.
        echiquier (Echiquier): L'échiquier sur lequel se déroule la partie.

    """
    def __init__(self):
        # Le joueur débutant une partie d'échecs est le joueur blanc.
        self.joueur_actif = 'blanc'

        # Création d'une instance de la classe Echiquier, qui sera manipulée dans les méthodes de la classe.
        self.echiquier = Echiquier()

    def determiner_gagnant(self):
        """Détermine la couleur du joueur gagnant, s'il y en a un. Pour déterminer si un joueur est le gagnant,
        le roi de la couleur adverse doit être absente de l'échiquier.

        Returns:
            str: 'blanc' si le joueur blanc a gagné, 'noir' si c'est plutôt le joueur noir, et 'aucun' si aucun
                joueur n'a encore gagné.

        """
        if not self.echiquier.roi_de_couleur_est_dans_echiquier('noir'):
            return 'blanc'
        elif not self.echiquier.roi_de_couleur_est_dans_echiquier('blanc'):
            return 'noir'

        return 'aucun'

    def partie_terminee(self):
        """Vérifie si la partie est terminée. Une partie est terminée si un gagnant peut être déclaré.

        Returns:
            bool: True si la partie est terminée, et False autrement.

        """
        return self.determiner_gagnant() != 'aucun'

    def demander_positions(self):
        """Demande à l'utilisateur d'entrer les positions de départ et d'arrivée pour faire un déplacement. Si les
        positions entrées sont valides (si le déplacement est valide), on retourne les deux positions. On doit
        redemander tant que l'utilisateur ne donne pas des positions valides.

        Returns:
            str, str: Deux chaînes de caractères représentant les deux positions valides fournies par l'utilisateurs.

        """
        while True:
            # On demande et valide la position source.
            while True:
                source = input("Entrez position source: ")
                if self.echiquier.position_est_valide(source) and self.echiquier.couleur_piece_a_position(source) == self.joueur_actif:
                    break

                print("Position invalide.\n")

            # On demande et valide la position cible.
            cible = input("Entrez position cible: ")
            if self.echiquier.deplacement_est_valide(source, cible):
                return source, cible

            print("Déplacement invalide.\n")

    def joueur_suivant(self):
        """Change le joueur actif: passe de blanc à noir, ou de noir à blanc, selon la couleur du joueur actif.

        """
        if self.joueur_actif == 'blanc':
            self.joueur_actif = 'noir'
        else:
            self.joueur_actif = 'blanc'

    def jouer(self):
        """Tant que la partie n'est pas terminée, joue la partie. À chaque tour :
            - On affiche l'échiquier.
            - On demande les deux positions.
            - On fait le déplacement sur l'échiquier.
            - On passe au joueur suivant.

        Une fois la partie terminée, on félicite le joueur gagnant!

        """
        while not self.partie_terminee():
            print(self.echiquier)
            print("\nAu tour du joueur {}".format(self.joueur_actif))
            source, cible = self.demander_positions()
            self.echiquier.deplacer(source, cible)
            self.joueur_suivant()

        print(self.echiquier)
        print("\nPartie terminée! Le joueur {} a gagné".format(self.determiner_gagnant()))
Beispiel #4
0
class CanvasEchiquier(Canvas):
    """Classe héritant d'un Canvas, et affichant un échiquier qui se redimensionne automatique lorsque
    la fenêtre est étirée.

    """
    def __init__(self,
                 parent,
                 n_pixels_par_case,
                 store_filename='annulerdeplacement.txt'):
        # Nombre de lignes et de colonnes.
        self.n_lignes = 8
        self.n_colonnes = 8

        # Noms des lignes et des colonnes.
        self.chiffres_rangees = ['1', '2', '3', '4', '5', '6', '7', '8']
        self.lettres_colonnes = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']

        # Nombre de pixels par case, variable.
        self.n_pixels_par_case = n_pixels_par_case

        # Appel du constructeur de la classe de base (Canvas).
        # La largeur et la hauteur sont déterminés en fonction du nombre de cases.
        super().__init__(parent,
                         width=self.n_lignes * n_pixels_par_case,
                         height=self.n_colonnes * self.n_pixels_par_case)

        # On fait en sorte que le redimensionnement du canvas redimensionne son contenu. Cet événement étant également
        # généré lors de la création de la fenêtre, nous n'avons pas à dessiner les cases et les pièces dans le
        # constructeur.
        self.bind('<Configure>', self.redimensionner)

        # Importation de Échequier et partie et Fenetre
        self.echequier = Echiquier()
        self.partie = Partie()
        self.fenetre = Fenetre

        # Dictionnaire contenant les pièces. Vous devinerez, si vous réutilisez cette classe dans votre TP4,
        # qu'il fandra adapter ce code pour plutôt utiliser la classe Echiquier.
        self.pieces = self.echequier.dictionnaire_pieces

        # Les variables nécessaires pour la fonction déplacement
        self.selectionner = 0
        self.case_source = ""
        self.case_cible = ""

        # Déterminer le gagnant
        self.gagnant_noir = False
        self.gagnant_blanc = False

        # Enregistrement des coups
        self.texte = ""

        # Fichier text annuler déplacement
        self.store_filename = os.path.join(BASE_DIR, store_filename)

        self.t = 0

    def dessiner_cases(self):
        """Méthode qui dessine les cases de l'échiquier.

        """

        for i in range(self.n_lignes):
            for j in range(self.n_colonnes):
                debut_ligne = i * self.n_pixels_par_case
                fin_ligne = debut_ligne + self.n_pixels_par_case
                debut_colonne = j * self.n_pixels_par_case
                fin_colonne = debut_colonne + self.n_pixels_par_case
                position = self.obtenir_position_a_partir_de_coordonnes(i, j)
                position_selectione = self.case_source

                # Les couleurs
                if position == position_selectione:
                    couleur = "yellow"
                elif (i + j) % 2 == 0:
                    couleur = 'white'
                else:
                    couleur = 'gray'

                # On dessine le rectangle. On utilise l'attribut "tags" pour être en mesure de récupérer les éléments
                # par la suite.
                self.create_rectangle(debut_colonne,
                                      debut_ligne,
                                      fin_colonne,
                                      fin_ligne,
                                      fill=couleur,
                                      tags='case')

    def dessiner_pieces(self):
        # Caractères unicode représentant les pièces. Vous avez besoin de la police d'écriture DejaVu.
        caracteres_pieces = {
            'PB': '\u2659',
            'PN': '\u265f',
            'TB': '\u2656',
            'TN': '\u265c',
            'CB': '\u2658',
            'CN': '\u265e',
            'FB': '\u2657',
            'FN': '\u265d',
            'RB': '\u2654',
            'RN': '\u265a',
            'DB': '\u2655',
            'DN': '\u265b'
        }

        # Pour tout paire position, pièce:

        for position, piece in self.echequier.dictionnaire_pieces.items():
            # On dessine la pièce dans le canvas, au centre de la case. On utilise l'attribut "tags" pour être en
            # mesure de récupérer les éléments dans le canvas.
            coordonnee_y = (
                self.n_lignes - self.chiffres_rangees.index(position[1]) -
                1) * self.n_pixels_par_case + self.n_pixels_par_case // 2
            coordonnee_x = self.lettres_colonnes.index(position[
                0]) * self.n_pixels_par_case + self.n_pixels_par_case // 2
            self.create_text(coordonnee_x,
                             coordonnee_y,
                             text=[piece],
                             font=('Deja Vu', self.n_pixels_par_case // 2),
                             tags='piece')

    def redimensionner(self, event):
        # Nous recevons dans le "event" la nouvelle dimension dans les attributs width et height. On veut un damier
        # carré, alors on ne conserve que la plus petite de ces deux valeurs.
        nouvelle_taille = min(event.width, event.height)

        # Calcul de la nouvelle dimension des cases.
        self.n_pixels_par_case = nouvelle_taille // self.n_lignes

        # On supprime les anciennes cases et on ajoute les nouvelles.
        self.delete('case')
        self.dessiner_cases()

        # On supprime les anciennes pièces et on ajoute les nouvelles.
        self.delete('piece')
        self.dessiner_pieces()

    def obtenir_position_a_partir_de_coordonnes(self, i, j):
        position = "{}{}".format(
            self.lettres_colonnes[j],
            int(self.chiffres_rangees[self.n_lignes - i - 1]))
        return position

    def deplacer(self, source, cible):
        self.echequier.deplacer(source, cible)
        self.rafraichir()
        self.echequier.dictionnaire_pieces.update()

    def rafraichir(self):

        # On supprimer les anciennes cases et on ajouter les nouvelles.
        self.delete("case")
        self.dessiner_cases()

        # On supprimer les anciennes pièces et on ajoute les nouvelles.
        self.delete("piece")
        self.dessiner_pieces()

    def jouer(self, event):
        x, y = event.x, event.y
        ligne = y // self.n_pixels_par_case
        colonne = x // self.n_pixels_par_case
        position = "{}{}".format(
            self.lettres_colonnes[colonne],
            int(self.chiffres_rangees[self.n_lignes - ligne - 1]))

        if self.selectionner == 1:
            self.case_cible = position

            try:

                self.deplacer(self.case_source, self.case_cible)
                if self.echequier.roi_de_couleur_est_dans_echiquier(
                        "blanc") is False:
                    messagebox.showinfo("Félicitation!",
                                        "Le joueur noir a gagné la partie!")
                    self.unbind("<Button-1>"), self.jouer
                elif self.echequier.roi_de_couleur_est_dans_echiquier(
                        "noir") is False:
                    messagebox.showinfo("Félicitation!",
                                        "Le joueur blanc a gagné la partie!")
                    self.unbind("<Button-1>"), self.jouer
                elif self.echequier.recuperer_piece_a_position(
                        self.case_source) is None:
                    self.partie.joueur_suivant()
                    self.unbind("<Button-1>"), self.jouer
                elif self.echequier.deplacement_est_valide(self.case_source, self.case_cible) is False and \
                        self.echequier.recuperer_piece_a_position(self.case_cible) is None:
                    raise DeplacementImpossible
                elif self.echequier.deplacement_est_valide(self.case_source, self.case_cible) is False and \
                        self.echequier.recuperer_piece_a_position(self.case_cible) is not None:
                    if self.echequier.couleur_piece_a_position(
                            self.case_cible
                    ) == self.echequier.couleur_piece_a_position(
                            self.case_source):
                        pass
                    else:
                        raise PriseImpossible

                self.texte += "{} {} à {} \n".format(
                    self.echequier.recuperer_piece_a_position(self.case_cible),
                    self.case_source, self.case_cible)

            except DeplacementImpossible:
                messagebox.showinfo("Erreur", "Déplacement impossible")
            except PriseImpossible:
                messagebox.showinfo("Erreur", "Prise impossible")

            self.case_source = ""
            self.case_cible = ""
            self.selectionner = 0
            self.rafraichir()

        elif self.selectionner == 0:

            try:
                if self.echequier.couleur_piece_a_position(
                        position) == self.partie.joueur_actif:
                    self.case_source = position
                    self.rafraichir()
                    self.selectionner += 1
                elif self.echequier.couleur_piece_a_position(position) != self.partie.joueur_actif and \
                        self.echequier.recuperer_piece_a_position(position) is not None:
                    raise SelectionMauvaisePiece

            except SelectionMauvaisePiece:
                messagebox.showinfo(
                    "Erreur",
                    "Selection impossible: c'est au tour du joueur {}".format(
                        self.partie.joueur_actif))

        else:
            self.selectionner = 0
            self.case_source = ""
            self.case_cible = ""

    def sauvegarder(self, filename):
        with open(filename, 'wb') as f:
            pickle.dump(self.echequier.dictionnaire_pieces, f)

    def charger(self, filename):

        with open(filename, 'rb') as f:
            data = pickle.load(f)
            f.close()
            self.echequier.dictionnaire_pieces = data
        self.rafraichir()

    def nouvelle_partie(self):
        self.echequier.initialiser_echiquier_depart()
        if self.partie.joueur_actif == "noir":
            self.partie.joueur_actif = "blanc"
        self.texte = ""
        self.rafraichir()

    def sauvegarder_mouvement(self, filename):
        with open(filename, 'wb') as f:
            pickle.dump(self.texte, f)

    def charger_mouvement(self, filename):
        with open(filename, 'rb') as f:
            data = pickle.load(f)
            f.close()
            self.texte = data
        self.rafraichir()

    def annuler_mouvement(self):
        derniere_ligne = self.texte[-9:]
        case_cible_avec = derniere_ligne[-4:]
        case_cible = case_cible_avec[0:2]
        case_source = derniere_ligne[0:3]
        self.echequier.deplacement_absolue(case_cible, case_source)
        self.rafraichir()
        self.texte = self.texte[0:-11]

    def revoir_une_partie(self, filename):
        self.nouvelle_partie()
        with open(filename, 'rb') as f:
            data = pickle.load(f)
            f.close()
            self.texte = data

        partie_en_text = self.texte
        Nombre_de_ligne = len(partie_en_text) // 11
        while Nombre_de_ligne > 0:
            ligne = partie_en_text[2:11]
            case_source = ligne[0:2]
            case_cible = ligne[-4:]
            self.echequier.deplacement_absolue(case_source, case_cible)
            Nombre_de_ligne -= 1
            partie_en_text = partie_en_text[11:]
            self.rafraichir()
            self.update()
            self.after(1500)
        pass
Beispiel #5
0
class Partie:
    """
    La classe Partie contient les informations sur une partie d'échecs, c'est à dire un échiquier, puis
    un joueur actif (blanc ou noir). Des méthodes sont disponibles pour faire avancer la partie et interagir
    avec l'utilisateur.

    Attributes:
        joueur_actif (str): La couleur du joueur actif, 'blanc' ou 'noir'.
        echiquier (Echiquier): L'échiquier sur lequel se déroule la partie.
    """
    def __init__(self):
        # Le joueur débutant une partie d'échecs est le joueur blanc.
        self.joueur_actif = 'blanc'

        # Création d'une instance de la classe Echiquier, qui sera manipulée dans les méthodes de la classe.
        self.echiquier = Echiquier()

        #intialisation de deux listes qui permettront d'afficher les derniers déplacements
        self.listeDeplacements = []
        self.dernierDeplacement = []

        self.hist = []

        self.nom_fichier_sauvegarde = 'sauvegarde'

    def determiner_gagnant(self):
        """Détermine la couleur du joueur gagnant, s'il y en a un. Pour déterminer si un joueur est le gagnant,
        le roi de la couleur adverse doit être absente de l'échiquier.

        Returns:
            str: 'blanc' si le joueur blanc a gagné, 'noir' si c'est plutôt le joueur noir, et 'aucun' si aucun
                joueur n'a encore gagné.

        """
        if not self.echiquier.roi_de_couleur_est_dans_echiquier('noir'):
            return 'blanc'
        elif not self.echiquier.roi_de_couleur_est_dans_echiquier('blanc'):
            return 'noir'

        return 'aucun'

    def partie_terminee(self):
        """Vérifie si la partie est terminée. Une partie est terminée si un gagnant peut être déclaré.

        Returns:
            bool: True si la partie est terminée, et False autrement.

        """
        return self.determiner_gagnant() != 'aucun'

    def annulerDernierMouvement(self):
        """
        Permet d'annuler le dernier mouvement et de rafraichir les pieces blanches et noires qui restent.
        Un premier scénario ou la liste a 2 ou moins historique d'échiquier.
        Un deuxième scénario dans le cas contraire.
        """

        if len(self.echiquier.listeDesEchiquiers) <= 2:
            self.echiquier.initialiser_echiquier_depart()
            self.joueur_actif = 'blanc'

        else:
            del self.echiquier.listeDesEchiquiers[-1]
            self.echiquier.dictionnaire_pieces = self.echiquier.listeDesEchiquiers[
                -1]
            self.joueur_suivant()

        self.resteBlanc = set()
        self.resteNoir = set()
        for i in self.echiquier.dictionnaire_pieces.values():
            if i.est_blanc():
                self.resteBlanc.add(i)
            else:
                self.resteNoir.add(i)
        self.gapBlanc = list(self.echiquier.setBlanc - self.resteBlanc)
        self.gapNoir = list(self.echiquier.setNoir - self.resteNoir)

    def roque_est_valide(self, position_source, position_cible):
        """
            Identifie si le Roi peut effectuer un Roque.
            Pour pouvoir effectuer un Roque, il faut que:
            1. La pièece à la position_cible soit une Tour
            2. La pièce à la position_source soit un Roi
            3. Ni le Roi ni la Tour n'aient effectué de mouvement depuis le début de la partie.
            4. La voie doit être libre (aucune pièce) entre le Roi et la Tour.
            5. Aucune case entre le Roi et la Tour ne soit menacée par l'adversaire.
            6. Le roi ne soit pas en échec.
            7. La tour ne soit pas menacée.

            Args:
                position_source (str): Position du Roi
                position_cible (str): Position de la Tour

            Returns:
                bool: True si le Roi peut Roquer, et False autrement.
        """
        couleur_adversaire = 'blanc'
        rangee_origine = '8'

        piece = self.echiquier.recuperer_piece_a_position(position_source)
        piece_cible = self.echiquier.recuperer_piece_a_position(position_cible)

        if piece.couleur == 'blanc':
            couleur_adversaire = 'noir'
            rangee_origine = '1'
        #critères de 1 à 3
        if isinstance(piece, Roi) and isinstance(piece_cible, Tour) and\
                piece.couleur == piece_cible.couleur and\
                self.echiquier.recuperer_piece_a_position(position_source) not in self.hist and \
                self.echiquier.recuperer_piece_a_position(position_cible) not in self.hist:
            if position_cible[0] == 'a':  #Grand Roque
                for colonne in self.echiquier.lettres_colonnes[0:5]:
                    #critères 5 à 7
                    if self.echiquier.case_est_menacee_par(
                            colonne + rangee_origine, couleur_adversaire):
                        return False
                return True
            else:  #Petit Roque
                for colonne in self.echiquier.lettres_colonnes[4:]:
                    # critères 5 à 7
                    if self.echiquier.case_est_menacee_par(
                            colonne + rangee_origine, couleur_adversaire):
                        return False
                return True

    def roquer(self, position_source, position_cible):
        """
            Effectue le mouvement de Roque si celui-ce est valide dans l'échiquier.

            Args:
                position_source (str): position du Roi dans l'échiquier
                position_cible (str): position de la Tour dans l'échiquier.
        """

        self.joueur_suivant()
        if ord(position_source[0]) > ord(position_cible[0]):
            position_roi = 'c' + position_source[1]
            self.echiquier.dictionnaire_pieces[position_roi] = \
                self.echiquier.recuperer_piece_a_position(position_source)
            del self.echiquier.dictionnaire_pieces[position_source]

            position_tour = 'd' + position_cible[1]
            self.echiquier.dictionnaire_pieces[position_tour] = \
                self.echiquier.recuperer_piece_a_position(position_cible)
            del self.echiquier.dictionnaire_pieces[position_cible]
        else:
            position_roi = 'g' + position_source[1]
            self.echiquier.dictionnaire_pieces[position_roi] = \
                self.echiquier.recuperer_piece_a_position(position_source)
            del self.echiquier.dictionnaire_pieces[position_source]

            position_tour = 'f' + position_cible[1]
            self.echiquier.dictionnaire_pieces[position_tour] = \
                self.echiquier.recuperer_piece_a_position(position_cible)
            del self.echiquier.dictionnaire_pieces[position_cible]

        #Trucs a Thierry
        piece = self.echiquier.recuperer_piece_a_position(position_source)
        self.dernierDeplacement = [
            "(" + self.joueur_actif + ")" + position_source + "->" +
            position_cible
        ]
        self.listeDeplacements.append(self.dernierDeplacement)

        echiquierCopy = dict(self.echiquier.dictionnaire_pieces)
        self.echiquier.listeDesEchiquiers.append(echiquierCopy)

        self.resteBlanc = set()
        self.resteNoir = set()
        for i in self.echiquier.dictionnaire_pieces.values():
            if (i.est_blanc()):
                self.resteBlanc.add(i)
            else:
                self.resteNoir.add(i)

        self.gapBlanc = list(self.echiquier.setBlanc - self.resteBlanc)
        self.gapNoir = list(self.echiquier.setNoir - self.resteNoir)

    def deplacer(self, position_source, position_cible):
        """
            Permet de d'appeler le mouvement à la méthode déplacer du module Échiquier.
            Permet aussi de recalculer les pièces mangées qui sert dans le visuel du jeux.
            En même temps, sert à écrire ce qui sera communiquer au joueur sur la liste des déplacements
            dans le Listbox du jeux.

            Args:
                position_source (str): Position de source de la pièce
                position_cible (str): Position cible de la pièce

        """
        piece = self.echiquier.recuperer_piece_a_position(position_source)

        #Pour le roque
        if self.echiquier.deplacement_est_valide(position_source,
                                                 position_cible):
            self.hist.append(piece)

        self.echiquier.deplacer(position_source, position_cible)

        self.joueur_suivant()
        self.dernierDeplacement = [
            "(" + piece.couleur + ")" + position_source + "->" + position_cible
        ]
        self.listeDeplacements.append(self.dernierDeplacement)

        echiquierCopy = dict(self.echiquier.dictionnaire_pieces)
        self.echiquier.listeDesEchiquiers.append(echiquierCopy)

        self.dictionnaire_pieces_initial = {
            'a1': Tour('blanc'),
            'b1': Cavalier('blanc'),
            'c1': Fou('blanc'),
            'd1': Dame('blanc'),
            'e1': Roi('blanc'),
            'f1': Fou('blanc'),
            'g1': Cavalier('blanc'),
            'h1': Tour('blanc'),
            'a2': Pion('blanc'),
            'b2': Pion('blanc'),
            'c2': Pion('blanc'),
            'd2': Pion('blanc'),
            'e2': Pion('blanc'),
            'f2': Pion('blanc'),
            'g2': Pion('blanc'),
            'h2': Pion('blanc'),
            'a7': Pion('noir'),
            'b7': Pion('noir'),
            'c7': Pion('noir'),
            'd7': Pion('noir'),
            'e7': Pion('noir'),
            'f7': Pion('noir'),
            'g7': Pion('noir'),
            'h7': Pion('noir'),
            'a8': Tour('noir'),
            'b8': Cavalier('noir'),
            'c8': Fou('noir'),
            'd8': Dame('noir'),
            'e8': Roi('noir'),
            'f8': Fou('noir'),
            'g8': Cavalier('noir'),
            'h8': Tour('noir'),
        }

        self.setBlanc = set()
        self.setNoir = set()
        for i in self.dictionnaire_pieces_initial.values():
            if i.est_blanc():
                self.setBlanc.add(i)
            else:
                self.setNoir.add(i)

        self.resteBlanc = set()
        self.resteNoir = set()
        for i in self.echiquier.dictionnaire_pieces.values():
            if i.est_blanc():
                self.resteBlanc.add(i)
            else:
                self.resteNoir.add(i)

        self.gapBlanc = list(self.echiquier.setBlanc - self.resteBlanc)
        self.gapNoir = list(self.echiquier.setNoir - self.resteNoir)

    def joueur_suivant(self):
        """Change le joueur actif: passe de blanc à noir, ou de noir à blanc, selon la couleur du joueur actif.

        """
        if self.joueur_actif == 'blanc':
            self.joueur_actif = 'noir'
        else:
            self.joueur_actif = 'blanc'

    def position_mon_roi(self, couleur_joueur_actif):
        """
            Identifie ou se trouve le roi de la couleur entrée en argument dans l'échiquier.

            Args:
                couleur_joueur_actif (str): couleur du joueur dont on souhaite connaître la position du Roi.
            Returns:
                str: Retourne la position du roi dans l'échiquier.
        """
        for position in self.echiquier.dictionnaire_pieces.keys():
            if isinstance(self.echiquier.dictionnaire_pieces[position], Roi) \
                    and self.echiquier.dictionnaire_pieces[position].couleur == couleur_joueur_actif:
                return position

    def mon_roi_en_echec(self):
        """
            Identifie si le Roi du joueur actif est en échec.
            Par en échec on entend que sa case est menacée par le joueur adverse.
            Si le joueur actif ne réagit pas à la menace, il perdra la partie au prochain tour.

            Returns:
                bool: True si le Roi du joueur actif est en échec, false autrement.
        """
        position_roi = self.position_mon_roi(self.joueur_actif)
        if self.joueur_actif == 'blanc':
            autre_couleur = 'noir'
        else:
            autre_couleur = 'blanc'

        if self.partie_terminee():
            return False
        return self.echiquier.case_est_menacee_par(position_roi, autre_couleur)

    def sauvegarder_partie(self):
        """
        Permet de sauver la partie.
        """
        with open(self.nom_fichier_sauvegarde, "wb") as f:
            pickle.dump(self.echiquier.dictionnaire_pieces, f)

    def charger_partie(self):
        """
        Permet de charger une partie sauvegarder avec la méthode sauvergarder_partie
        """
        with open(self.nom_fichier_sauvegarde, "rb") as f:
            self.echiquier.dictionnaire_pieces = pickle.load(f)