Ejemplo n.º 1
0
    def __init__(self):
        super().__init__()

        self.protocol("WM_DELETE_WINDOW", self.fermeture)

        # Nom de la fenêtre.
        self.title("Échiquier")

        #Initialisation d'une partie
        self.partie = Partie()

        # Truc pour le redimensionnement automatique des éléments de la fenêtre.
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        # Création du canvas échiquier.
        self.canvas_echiquier = CanvasEchiquier(self, 60, self.partie)
        self.canvas_echiquier.grid(sticky=NSEW)

        # Ajout d'une étiquette d'information.
        self.messages = Label(self)
        self.messages.grid()

        # Ajout d'une étiquette qui indique le joueur actif.
        self.messages_joueur_actif = Label(self)
        self.messages_joueur_actif['text'] = (
            "C'est au joueur blanc de commencer! ")
        self.messages_joueur_actif['foreground'] = 'blue'
        self.messages_joueur_actif.grid()

        # On lie un clic sur le CanvasEchiquier à une méthode.
        self.canvas_echiquier.bind('<Button-1>', self.selectionner)

        # Ajout d'un cadre pour regrouper les boutons
        frame_boutons = Frame(self)
        frame_boutons.grid(row=0, column=1)

        #Bouton pour annuler le dernier mouvement.
        bouton_dernier_mouvement = bouton_sauvegarder = Button(
            frame_boutons,
            text="Annuler le dernier mouvement",
            command=self.charger_dernier_mouvement)
        bouton_dernier_mouvement.grid()

        #Ajout des boutons pour sauvegarder et charger une partie.
        bouton_sauvegarder = Button(frame_boutons,
                                    text="Sauvegarder la partie",
                                    command=self.sauvegarder_partie)
        bouton_charger = Button(frame_boutons,
                                text="Charger la partie",
                                command=self.charger_partie)
        bouton_sauvegarder.grid()
        bouton_charger.grid()

        #Ajout d'un bouton pour commencer une nouvelle partie.
        bouton_nouvelle_partie = Button(frame_boutons,
                                        text="Nouvelle partie",
                                        command=self.nouvelle_partie)
        bouton_nouvelle_partie.grid()
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    def __init__(self, parent, n_pixels_par_case):
        # Nombre de lignes et de colonnes.
        self.n_lignes = 8
        self.n_colonnes = 8

        # Création d'une partie d'échec dans le Canvas
        self.partie = Partie()

        # 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 utilise le dictionnaire de pièces intégré dans l'échiquier
        self.pieces = self.partie.echiquier.dictionnaire_pieces

        # Couleur d'arrière plan de l'échiquier (Avec le blanc)
        self.couleur_theme = 'grey'

        # 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)
Ejemplo n.º 4
0
    def nouvelle_partie(self):
        self.canvas_echiquier.partie = Partie()
        self.partie = self.canvas_echiquier.partie

        self.canvas_echiquier.rafraichir()

        self.mise_a_jour_message_joueur_actif()
        self.messages['text'] = ""
    def __init__(self):
        super().__init__()

        self.partie = Partie()

        self.title("Jeu d'échec")
        self.piece_selectionner = None
        self.nombre_déplacement = 0

        self.grid_columnconfigure(1, weight = 1)
        self.grid_rowconfigure(0, weight = 1)

        self.Canvas_echiquier = Canvas_echiquier(self, 80, self.partie)

        self.Canvas_echiquier.grid(sticky=NSEW,column = 1 ,row=0)

        self.creation_frame_rangee()
        self.affiche_liste_rangee.grid(column= 0,row =0 )

        self.creation_frame_colonne()
        self.affiche_liste_colonne.grid(column= 1,row =2 )

        self.messages_joueur = Label(self, font=('Deja Vu', 12))
        self.messages_joueur['text'] = "C'est au tour du joueur {}".format(self.partie.joueur_actif)
        self.messages_joueur.grid(column = 1, row = 3)

        self.messages= Label(self,font=('Deja Vu', 13))
        self.messages.grid( column= 1, row=4, rowspan=2)

        self.messages_piece = Label(self,font=('Deja Vu', 11))
        self.messages_piece['text'] = "Pièces qui on été mangées:"
        self.messages_piece.grid(column= 1,row =6)

        self.messages_piece_blanc = Label(self,font=('Deja Vu', 10))
        self.messages_piece_blanc['text'] = "Pièces blanches:"
        self.messages_piece_blanc.grid(column= 1, row=7)
        self.messages_piece_noir = Label(self, font=('Deja Vu', 10))
        self.messages_piece_noir['text'] = "Pièces noirs:"
        self.messages_piece_noir.grid(column= 1,row =8)

        self.creation_frame_droite()
        self.frame.grid(column = 2, row=0, rowspan=8, sticky = NSEW)

        self.Canvas_echiquier.bind('<Button-1>', self.selectionner_piece)
        self.Canvas_echiquier.bind('<Button-3>', self.deselectionner_piece)

        self.menu_bar_principal()
Ejemplo n.º 6
0
    def __init__(self):
        super().__init__()

        # Nom de la fenêtre.
        self.title("Chess")

        # quelques attributs à utiliser plustard
        self.position_source = None
        self.option_indice = 0
        self.protocol(
            'WM_DELETE_WINDOW', self.demander
        )  # cette instruction fait appel a une fonction si le joueur
        # click sur le bouton fermé de la fenetre tk

        # Création du canvas échiquier.
        self.canvas_echiquier = CanvasEchiquier(self, 50)
        self.canvas_echiquier.grid(padx=0,
                                   pady=0,
                                   sticky=NSEW,
                                   row=0,
                                   column=0,
                                   rowspan=2)

        # Redimensionnement automatique du canvas.
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        # Label pour les infos sur la partie, voir les paramètres 'text=...' pour avoir plus de détails sur chaque sous-fram
        self.frame_infos = LabelFrame(self,
                                      borderwidth=3,
                                      relief=RIDGE,
                                      text="Information sur la partie")
        self.frame_infos.grid(row=0, column=1, sticky=N)

        self.mon_label_info = Label(self.frame_infos,
                                    font=("DejaVu Sans", 16),
                                    text="C'est au tour du joueur blanc")
        self.mon_label_info.grid(columnspan=4)

        self.prises_blanc = Label(self.frame_infos,
                                  borderwidth=2,
                                  relief=RIDGE,
                                  font=("DejaVu Sans", 8),
                                  text="Prises du\njoueur blanc")
        self.prises_blanc.grid(row=1, column=0, sticky=N + W)

        self.prises_noir = Label(self.frame_infos,
                                 borderwidth=2,
                                 relief=RIDGE,
                                 font=("DejaVu Sans", 8),
                                 text="Prises du\njoueur noir")
        self.prises_noir.grid(row=1, column=1, sticky=N + E)

        self.depla_blanc = Label(self.frame_infos,
                                 borderwidth=2,
                                 relief=RIDGE,
                                 font=("DejaVu Sans", 8),
                                 text="Liste des déplacements\njoueur blanc")
        self.depla_blanc.grid(row=1, column=2, sticky=N + W)

        self.depla_noir = Label(self.frame_infos,
                                borderwidth=2,
                                relief=RIDGE,
                                font=("DejaVu Sans", 8),
                                text="Liste des déplacements\njoueur noir")
        self.depla_noir.grid(row=1, column=3, sticky=N + E)

        # Label pour le menu (contenant des bouton) de la partie, voir les paramètres 'text=...' pour avoir plus de
        # détails sur cache bouton: chaque bouton envoi vers une fonction voir les paramètres 'command=...'
        self.frame_menu = LabelFrame(self,
                                     borderwidth=3,
                                     relief=RIDGE,
                                     text="Menu de la partie")
        self.frame_menu.grid(row=1, column=1, sticky=NSEW, padx=10, pady=0)

        self.nouvelle = Button(self.frame_menu,
                               text="Nouvelle partie",
                               command=self.nouvelle_partie)
        self.nouvelle.grid(sticky=NSEW, row=0, column=0)

        self.sauv = Button(self.frame_menu,
                           text="Sauvegarder la partie",
                           command=self.save)
        self.sauv.grid(sticky=NSEW, row=1, column=0)

        self.load = Button(self.frame_menu,
                           text="Charger une partie",
                           command=self.load)
        self.load.grid(sticky=NSEW, row=2, column=0)

        self.infos = Button(self.frame_menu,
                            text="Informations sur le jeu",
                            command=self.infos_et_règles)
        self.infos.grid(sticky=NSEW, row=3, column=0)

        self.annul = Button(self.frame_menu,
                            text="Annuler le dernier déplacement",
                            command=self.annuler)
        self.annul.grid(sticky=NSEW, row=4, column=0)

        self.o = Button(self.frame_menu,
                        text="Passez la main à l'ordi",
                        command=self.ordi)
        self.o.grid(sticky=N + E + W, row=0, column=1)

        self.o_h_a = Checkbutton(
            self.frame_menu,
            text="Activer cette case puis faites un\nclick droit sur la piece "
            "voulu\npour voir les possibilitées\nqui s'offrent à "
            "vous",
            command=self.activer_indice)
        self.o_h_a.grid(sticky=NSEW, row=1, column=1, rowspan=3)

        self.partie = Partie(self.canvas_echiquier.echiquier)

        # Ajout d'une étiquette d'information.
        self.messages = Label(self, font=("DejaVu Sans", 16))
        self.messages.grid(row=2, columnspan=2)

        # On lie un clic sur le CanvasEchiquier à une méthode.
        self.canvas_echiquier.bind('<Button-3>', self.option_hint)
        self.canvas_echiquier.bind('<Button-1>', self.selectionner_source)
        self.canvas_echiquier.bind('<ButtonRelease-1>',
                                   self.selectionner_cible)
Ejemplo n.º 7
0
    def __init__(self):
        super().__init__()

        # Nom de la fenêtre.
        self.title("Échiquier")

        self.partie = Partie()

        #Bouton X (pour quitter)
        self.protocol('WM_DELETE_WINDOW', self.message_quitter)

        # Truc pour le redimensionnement automatique des éléments de la fenêtre.
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        # Création du canvas échiquier.
        self.canvas_echiquier = CanvasEchiquier(self, 60, self.partie)
        self.canvas_echiquier.grid(sticky=NSEW)

        ##########################################################
        #                                                        #
        #                    VISUEL                              #
        #                                                        #
        ##########################################################
        # Étiquette d'information et de sélection des pièces
        self.messages = Label(self)
        self.messages['foreground'] = 'black'
        self.messages['text'] = "Bienvenue au super jeux d'échec!"
        self.messages.grid(row=1, sticky='w')

        # # Étiquette d'information sur le joueur courant
        self.messages1 = Label(self)
        self.messages1[
            'text'] = "Au tour du joueur: " + self.partie.joueur_actif.upper()
        self.messages1.grid(row=2, sticky='w')
        self.messages1['foreground'] = 'blue'

        # Création du frame a droite du canevas
        self.monFramePrincipal = Frame(self)
        self.monFramePrincipal.grid(row=0, column=1, sticky='n')

        # FRAME a DROITE: Fenetre pour afficher la liste des déplacements effectués
        self.mon_frame1 = LabelFrame(self.monFramePrincipal,
                                     text="Les déplacements ",
                                     borderwidth=2,
                                     relief=RIDGE,
                                     padx=5,
                                     pady=5)
        self.mon_frame1.grid(row=0, column=0, sticky='n')
        self.yScroll = Scrollbar(self.mon_frame1, orient=VERTICAL)
        self.yScroll.grid(row=0, column=1, sticky=N + S)
        #small_font = font(size=5)
        self.liste1 = Listbox(self.mon_frame1, yscrollcommand=self.yScroll.set)
        self.liste1 = Listbox(self.mon_frame1)
        self.liste1.grid(row=0, column=0)
        self.yScroll['command'] = self.liste1.yview

        # Creation d'un espace pour mettre les 2 fenetres de pièces mangées (un sous-Frame)
        self.monSousFrame = Frame(self.monFramePrincipal)
        self.monSousFrame.grid(row=1, column=0, sticky='n')

        # FRAME a DROITE: Fenetre pour afficher les pieces blanches mangées
        self.mon_frame2 = LabelFrame(self.monSousFrame,
                                     text="Les blancs\nmangés ",
                                     borderwidth=2,
                                     relief=RIDGE,
                                     padx=5,
                                     pady=5,
                                     width=7)
        self.mon_frame2.grid(row=0, column=0, sticky='n')
        self.yScroll = Scrollbar(self.mon_frame2, orient=VERTICAL)
        self.yScroll.grid(row=0, column=1, sticky=N + S)
        self.liste2 = Listbox(self.mon_frame2, yscrollcommand=self.yScroll.set)
        self.liste2 = Listbox(self.mon_frame2, width=7)
        self.liste2.grid(row=0, column=0)
        self.yScroll['command'] = self.liste2.yview

        # FRAME a DROITE: Fenetre pour afficher les pieces noires mangées
        self.mon_frame2 = LabelFrame(self.monSousFrame,
                                     text="Les noirs\nmangés ",
                                     borderwidth=2,
                                     relief=RIDGE,
                                     padx=5,
                                     pady=5,
                                     width=7)
        self.mon_frame2.grid(row=0, column=1, sticky='n')
        self.yScroll = Scrollbar(self.mon_frame2, orient=VERTICAL)
        self.yScroll.grid(row=0, column=1, sticky=N + S)
        self.liste3 = Listbox(self.mon_frame2, yscrollcommand=self.yScroll.set)
        self.liste3 = Listbox(self.mon_frame2, width=7)
        self.liste3.grid(row=0, column=0)
        self.yScroll['command'] = self.liste3.yview

        # FRAME a DROITE: Bouton pour se connecter au site web des intrusctions d'echec
        self.mon_frame3 = Frame(self.monFramePrincipal,
                                borderwidth=2,
                                relief=RIDGE,
                                padx=5,
                                pady=5)
        self.mon_frame3.grid(row=2, column=0, sticky='n')
        but1 = Button(self.mon_frame3,
                      text="Lien web pour accéder\naux règles du jeux!",
                      command=self.ouvrirURL).grid(row=0, column=0)

        # Frame pour les options de jeux en bas de l'échiquier
        self.mon_frame = LabelFrame(self,
                                    text="Options de partie",
                                    borderwidth=2,
                                    relief=RIDGE,
                                    padx=5,
                                    pady=5)
        self.mon_frame.grid(row=4, column=0, sticky='w')
        bouton_sauver = Button(self.mon_frame,
                               text="Sauvegarder",
                               command=self.sauvergarder).grid(row=0, column=0)
        bouton_charge = Button(self.mon_frame,
                               text="Charger",
                               command=self.message_charger).grid(row=0,
                                                                  column=1)
        bouton_demarrer = Button(self.mon_frame,
                                 text="Redémarrage",
                                 command=self.message_reinitialiser).grid(
                                     row=0, column=2)
        bouton_annuler = Button(self.mon_frame,
                                text="Annuler dernier mouvement",
                                command=self.annulerDernierMouvement).grid(
                                    row=0, column=3)

        # On lie un clic sur le CanvasEchiquier à une méthode.
        self.canvas_echiquier.bind('<Button-1>', self.selectionner)

        self.piece_a_deplacer = None
        self.position_piece_a_deplacer = None

        #Pour que x et y soient accessibles dans selectionner ET dans creer_carre_selection
        self.x = 1
        self.y = 1
class Fenetre(Tk,menu_global):

    def __init__(self):
        super().__init__()

        self.partie = Partie()

        self.title("Jeu d'échec")
        self.piece_selectionner = None
        self.nombre_déplacement = 0

        self.grid_columnconfigure(1, weight = 1)
        self.grid_rowconfigure(0, weight = 1)

        self.Canvas_echiquier = Canvas_echiquier(self, 80, self.partie)

        self.Canvas_echiquier.grid(sticky=NSEW,column = 1 ,row=0)

        self.creation_frame_rangee()
        self.affiche_liste_rangee.grid(column= 0,row =0 )

        self.creation_frame_colonne()
        self.affiche_liste_colonne.grid(column= 1,row =2 )

        self.messages_joueur = Label(self, font=('Deja Vu', 12))
        self.messages_joueur['text'] = "C'est au tour du joueur {}".format(self.partie.joueur_actif)
        self.messages_joueur.grid(column = 1, row = 3)

        self.messages= Label(self,font=('Deja Vu', 13))
        self.messages.grid( column= 1, row=4, rowspan=2)

        self.messages_piece = Label(self,font=('Deja Vu', 11))
        self.messages_piece['text'] = "Pièces qui on été mangées:"
        self.messages_piece.grid(column= 1,row =6)

        self.messages_piece_blanc = Label(self,font=('Deja Vu', 10))
        self.messages_piece_blanc['text'] = "Pièces blanches:"
        self.messages_piece_blanc.grid(column= 1, row=7)
        self.messages_piece_noir = Label(self, font=('Deja Vu', 10))
        self.messages_piece_noir['text'] = "Pièces noirs:"
        self.messages_piece_noir.grid(column= 1,row =8)

        self.creation_frame_droite()
        self.frame.grid(column = 2, row=0, rowspan=8, sticky = NSEW)

        self.Canvas_echiquier.bind('<Button-1>', self.selectionner_piece)
        self.Canvas_echiquier.bind('<Button-3>', self.deselectionner_piece)

        self.menu_bar_principal()


    #Création d'un frame à droit de l'échiquier pour avoir le temps joué des joueurs et la liste des déplacements effectués
    def creation_frame_droite(self):

        self.frame = Frame(self)

        self.messages_mouvement = Label(self.frame,font=('Deja Vu', 12))
        self.messages_mouvement['text'] = "Mouvement joué:"
        self.messages_mouvement.grid(column= 0,row=0 , columnspan= 2,padx= 110, pady= 15, sticky= N)

        self.creation_frame_mouvement()
        self.frame_mouvement.grid(column= 0,row=1, columnspan= 2,sticky= NSEW)

        self.bouton_annuler_dernier_coup = Button(self.frame,font=('Deja Vu', 11), text="Voir le\ndernier coup", command = self.voir_dernier_mouvement,width = 15)
        self.bouton_annuler_dernier_coup.grid(column = 0, row = 3, pady= 15)

        self.bouton_annuler_dernier_coup = Button(self.frame,font=('Deja Vu', 11), text="Annuler le\ndernier coup", command = self.annuler_mouvement,width = 15)
        self.bouton_annuler_dernier_coup.grid(column = 1, row = 3, pady= 15)

    # Création d'un frame pour pouvoir afficher la liste des mouvements effectués
    def creation_frame_mouvement(self):
        self.frame_mouvement = Frame(self.frame,width = 200,height= 450,padx= 20)

        self.scrollbar = Scrollbar(self.frame_mouvement, orient=VERTICAL)
        self.listbox_mouvement = Listbox(self.frame_mouvement, yscrollcommand=self.scrollbar.set,activestyle = 'none', height = 30)
        self.scrollbar.config(command=self.listbox_mouvement.yview)
        self.scrollbar.pack(side=RIGHT, fill=Y)
        self.listbox_mouvement.pack(side=LEFT, fill=BOTH, expand=1)

    # Création d'un frame pour pouvoir afficher les range de l'échiquier
    def creation_frame_rangee(self):
        self.affiche_liste_rangee = Frame(self)


        for rangee in self.Canvas_echiquier.chiffres_rangees_inverse:
            self.chiffres_rangees= Label(self.affiche_liste_rangee,width = 2,height= self.Canvas_echiquier.n_pixels_par_case//20)
            self.chiffres_rangees['text'] = rangee

            self.chiffres_rangees.grid()


    # Création d'un frame pour pouvoir afficher les colonnes de l'échiquier
    def creation_frame_colonne(self):
        self.affiche_liste_colonne = Frame(self)
        place_colonne = 0
        for element in self.Canvas_echiquier.partie.echiquier.lettres_colonnes:
            self.lettre_colonne= Label(self.affiche_liste_colonne,width= self.Canvas_echiquier.n_pixels_par_case//8)
            self.lettre_colonne['text'] = element

            self.lettre_colonne.grid(row= 0, column=place_colonne,sticky= N)
            place_colonne +=1


    # Méthode qui va permettre d'afficher le gagnant de la partie lorsque le Roi adverse a été "mangé".
    def annoncer_partie_gagner(self):
        self.popup_gagner = Toplevel()
        self.popup_gagner.title("Partie Terminer")
        self.messages_gagner = Label(self.popup_gagner,font=('Deja Vu', 12))
        self.messages_gagner['text'] = "Félicitation! \nLe joueur {} à gagné la partie!\n\n Voulez-vous jouer une nouvelle partie?".format(self.partie.joueur_actif)
        self.messages_gagner.grid(columnspan = 2)

        self.bouton_nouvelle = Button(self.popup_gagner,text="Oui", command =lambda:self.nouvelle_partie(),width = 10)
        self.bouton_quitter = Button(self.popup_gagner, text="Non, quitter", command = self.quit,width = 10)
        self.bouton_nouvelle.grid(column = 0, row = 1, pady= 10)
        self.bouton_quitter.grid(column = 1, row = 1, pady= 10)

    # Méthode qui lance le déselectionner pièce, donc supprimer la sélection de la pièce.
    def deselectionner_piece(self, event):
        self.piece_selectionner = None
        self.Canvas_echiquier.supprimer_selection()
        self.messages['text'] = ' '
        self.Canvas_echiquier.dessiner_case()
        self.Canvas_echiquier.dessiner_piece()

    # Méthode qui affiche la pièce sélectionner de l'échiquier
    def selectionner_piece(self, event):
        ligne = event.y // self.Canvas_echiquier.n_pixels_par_case
        colonne = event.x // self.Canvas_echiquier.n_pixels_par_case
        position = "{}{}".format(self.Canvas_echiquier.partie.echiquier.lettres_colonnes[colonne], int(self.Canvas_echiquier.partie.echiquier.chiffres_rangees[self.Canvas_echiquier.n_ligne- ligne - 1]))
        if self.piece_selectionner is None: # si une pièce est sélectionner, affichez la pièce sélectionner et la position.
            try:
                piece = self.Canvas_echiquier.partie.echiquier.dictionnaire_pieces[position]
                self.position_depart_selectionnee = position

                self.messages['foreground'] = 'blue'
                self.messages['text'] = 'Pièce séléctionné : {} {} à la position {}\nDéplacement valide en bleu.'.format(piece.__class__.__name__,piece.couleur, self.position_depart_selectionnee)
                self.couleur_piece_selectionner = self.Canvas_echiquier.partie.echiquier.couleur_piece_a_position(position)
                if self.couleur_piece_selectionner != self.partie.joueur_actif: # Message qui affiche si le joueur actif sélectionne une pièce du joueur adverse.
                    self.messages['foreground'] = 'red'
                    self.messages['text'] = "Vous essayer de jouer une pièce de l'autre joueur TRICHEUR!"
                    return None
                self.piece_selectionner = piece

                self.verifier_coup_valide(position, colonne, ligne)
            except KeyError: #Message d'erreur qui se lance lorsqu'il a aucune pièce sur la case sélectionné
                self.messages['foreground'] = 'red'
                self.messages['text'] = 'erreur aucune piece ici'

        #S'il y a une pièce déjà selectionné onva vers la fonction qui selectionne l'arriver
        else:
            self.selectionner_arriver(ligne, colonne)
    # Méthode qui permet d'afficher au joueur actif, les coups valides pour la pièce sélectionné
    def verifier_coup_valide(self, position_depart, colonne, ligne):
        self.Canvas_echiquier.dessiner_case()
        self.Canvas_echiquier.changer_couleur_position(colonne, ligne)
        self.Canvas_echiquier.dessiner_piece()

        for ligne in self.Canvas_echiquier.partie.echiquier.chiffres_rangees:
            for colonne in self.Canvas_echiquier.partie.echiquier.lettres_colonnes:
                position_arriver = "{}{}".format(colonne,ligne)
                if self.Canvas_echiquier.partie.echiquier.deplacement_est_valide(position_depart,position_arriver):

                    nom_case = "case{}{}".format(colonne,ligne)
                    case = self.Canvas_echiquier.find_withtag(nom_case)
                    self.Canvas_echiquier.itemconfig(case, fill = "sky blue1")

    # Méthode qui sélectionne la case d'arriver
    def selectionner_arriver(self, ligne, colonne):
        position = "{}{}".format(self.Canvas_echiquier.partie.echiquier.lettres_colonnes[colonne], int(self.Canvas_echiquier.partie.echiquier.chiffres_rangees[self.Canvas_echiquier.n_ligne- ligne - 1]))
        #cas s'il y a une pièce sur la case d'arriver
        if self.Canvas_echiquier.partie.echiquier.recuperer_piece_a_position(position) is not None:
            #si le joueur sélectionne une pièce de sa couleur on change la pièce sélectionné
            if self.couleur_piece_selectionner == self.Canvas_echiquier.partie.echiquier.couleur_piece_a_position(position):
                piece = self.Canvas_echiquier.partie.echiquier.dictionnaire_pieces[position]
                self.position_depart_selectionnee = position
                self.piece_selectionner = piece
                self.messages['text'] = 'Pièce séléctionné : {} {} à la position {}\nDéplacement valide en bleu.'.format(piece.__class__.__name__,piece.couleur, self.position_depart_selectionnee)

                self.verifier_coup_valide(position, colonne, ligne)

        self.position_arriver_selectionnee = position
        # si le déplacement est valide, nous allons faire appel au méthode, piece mangé, afficher dernier coup effectué, afficher la liste des mouvements,
        if self.partie.echiquier.deplacement_est_valide(self.position_depart_selectionnee,self.position_arriver_selectionnee) is True:

            self.piece_mange = self.Canvas_echiquier.partie.echiquier.recuperer_piece_a_position(self.position_arriver_selectionnee)

            self.Canvas_echiquier.dernier_mouvement_effectuer = [self.Canvas_echiquier.partie.joueur_actif,self.piece_selectionner,self.position_depart_selectionnee,self.position_arriver_selectionnee, self.piece_mange]

            self.Canvas_echiquier.liste_mouvement_effectuer += [self.Canvas_echiquier.dernier_mouvement_effectuer]


            self.message_mouvement(self.Canvas_echiquier.dernier_mouvement_effectuer)


            self.listbox_mouvement.see(END)


            self.partie.echiquier.deplacer(self.position_depart_selectionnee,self.position_arriver_selectionnee)


            # si la partie est terminé, appel à la méthode annoncer le gagnant.
            if self.Canvas_echiquier.partie.partie_terminee() == True:
                self.annoncer_partie_gagner()
            #promotion du pion s'il arrive à l'extremité de l'échiquier
            elif isinstance(self.piece_selectionner, Pion):
                if self.piece_selectionner.couleur == "blanc":
                    if ligne == 0:
                        self.menu_promotion(self.position_arriver_selectionnee, "blanc")

                if self.piece_selectionner.couleur == "noir":
                    if ligne == 7:
                        self.menu_promotion(self.position_arriver_selectionnee,"noir")

            self.changer_de_tour()
        #si le déplacement n'est pas valide on sort de la fonction
        else:
            return None

    #fenetre de la promotion du pion
    def menu_promotion(self,position, couleur):
        self.popup_promotion = Toplevel()
        self.popup_promotion.title("Promotion du pion")
        self.messages_promotion = Label(self.popup_promotion)
        self.messages_promotion['text'] = "Choisisez la pièce qui remplacera le pion"
        self.messages_promotion.grid(row= 0,columnspan = 2,padx= 10, pady= 10)

        self.bouton_reine = Button(self.popup_promotion,text="Reine",width=10, command =lambda :self.promotion(position, Dame, couleur))
        self.bouton_reine.grid(row= 1,column= 0,pady= 10)
        self.bouton_fou = Button(self.popup_promotion,text="Fou",width=10, command =lambda :self.promotion(position, Fou, couleur))
        self.bouton_fou.grid(row= 1,column= 1,pady= 10)
        self.bouton_cavalier = Button(self.popup_promotion,text="Cavalier",width=10, command =lambda :self.promotion(position, Cavalier, couleur))
        self.bouton_cavalier.grid(row= 2,column= 0,pady= 10)
        self.bouton_tour = Button(self.popup_promotion,text="Tour",width=10, command =lambda :self.promotion(position, Tour, couleur))
        self.bouton_tour.grid(row= 2,column= 1,pady= 10)

    #fonction de promotion on remplace le pion par la pièce désirer dans le dictionaire
    def promotion(self, position,piece, couleur):
        self.popup_promotion.destroy()
        self.Canvas_echiquier.partie.echiquier.dictionnaire_pieces[position]=piece(couleur)
        self.Canvas_echiquier.dessiner_case()
        self.Canvas_echiquier.dessiner_piece()

    #fonction qui change le joueur actif et qui remet la fenetre et la selection par défaut.
    def changer_de_tour(self):
        self.Canvas_echiquier.dessiner_case()
        self.Canvas_echiquier.dessiner_piece()
        self.piece_selectionner = None
        self.messages['text'] = ' '
        self.Canvas_echiquier.supprimer_selection()
        self.joueur_actif = self.partie.joueur_suivant()
        self.messages_joueur['text'] = "C'est au tour du joueur {}".format(self.partie.joueur_actif)

    #Méthode qui permet au joueur actif d'annuler le dernier mouvement effectué
    def annuler_mouvement(self):
        try:
            mouvement = self.Canvas_echiquier.liste_mouvement_effectuer[-1]
            self.nombre_déplacement -=1
            #cas s'il y avait une pièce de mangé
            if mouvement[4] is not None:
                self.Canvas_echiquier.partie.echiquier.dictionnaire_pieces[mouvement[3]]= mouvement[4]
                self.Canvas_echiquier.partie.echiquier.dictionnaire_pieces[mouvement[2]]= mouvement[1]

                #on enleve la pièce perdu de la liste des pièce perdu
                if mouvement[4].couleur == "blanc":
                    self.Canvas_echiquier.piece_blanc_perdu  = self.Canvas_echiquier.piece_blanc_perdu [:-1]
                    self.messages_piece_blanc['text'] = "Pièces blanches:" +self.Canvas_echiquier.piece_blanc_perdu


                if mouvement[4].couleur == "noir":
                    self.Canvas_echiquier.piece_noir_perdu = self.Canvas_echiquier.piece_noir_perdu [:-1]
                    self.messages_piece_noir['text']= "Pièces noirs:"+self.Canvas_echiquier.piece_noir_perdu
                #on change de tour et on enleve le mouvement de la liste
                self.changer_de_tour()
                del self.Canvas_echiquier.liste_mouvement_effectuer[-1]
                self.Canvas_echiquier.dernier_mouvement_effectuer = self.Canvas_echiquier.liste_mouvement_effectuer[-1]
                self.listbox_mouvement.delete(END)
                self.listbox_mouvement.delete(END)
                self.listbox_mouvement.delete(END)
                self.listbox_mouvement.delete(END)
                self.Canvas_echiquier.dessiner_piece()
            #cas s'il n'y a pas de pièce mangé
            else:
                self.Canvas_echiquier.partie.echiquier.dictionnaire_pieces[mouvement[2]]= mouvement[1]
                del self.Canvas_echiquier.partie.echiquier.dictionnaire_pieces[mouvement[3]]
                self.changer_de_tour()
                del self.Canvas_echiquier.liste_mouvement_effectuer[-1]
                self.listbox_mouvement.delete(END)
                self.listbox_mouvement.delete(END)
                self.listbox_mouvement.delete(END)
                self.Canvas_echiquier.dessiner_piece()
                vide = []
                #cas s'il n'y a pas d'autre mouvement à annuler
                if self.Canvas_echiquier.liste_mouvement_effectuer == vide:
                    self.Canvas_echiquier.dernier_mouvement_effectuer = vide
                else:
                    self.Canvas_echiquier.dernier_mouvement_effectuer = self.Canvas_echiquier.liste_mouvement_effectuer[-1]

        except (IndexError):    # Message d'erreur  lorsqu'il a aucun coup effectué
            self.messages['foreground'] = 'red'
            self.messages['text'] = "Il n'y a aucun coup de joué pour le moment."

    #Fonction qui crée les messages des mouvement et qui l'ajoute à la liste de la fenetre
    def message_mouvement(self,mouvement):
        couleur_piece_depart = mouvement[1].couleur

        self.nombre_déplacement += 1
        #cas s'il y a une pièce de manger
        if mouvement[4] is not None:
            couleur_piece_arriver = mouvement[4].couleur
            numero_deplacement = "Déplacement {}: Joueur {}".format(self.nombre_déplacement, mouvement[0])
            text_mouvement= "Le {} {} se déplace de la case {} à {}".format(mouvement[1].__class__.__name__,couleur_piece_depart,mouvement[2],mouvement[3])
            text_manger ="Puis, mange le {} {}".format(mouvement[4].__class__.__name__, couleur_piece_arriver)
            self.ajouter_piece_manger(mouvement[4])
            self.listbox_mouvement.insert(END,numero_deplacement)
            self.listbox_mouvement.itemconfig(END,fg= "blue")
            self.listbox_mouvement.insert(END, text_mouvement)
            self.listbox_mouvement.insert(END, text_manger)
            self.listbox_mouvement.itemconfig(END,fg= "red")
            self.listbox_mouvement.insert(END,"")
            self.listbox_mouvement.selection_clear(0, END)
        #cas s'il n'y a pas de pièce de manger
        else:

            numero_deplacement = "Déplacement {}: Joueur {}".format(self.nombre_déplacement,mouvement[0])
            text_mouvement= "Le {} {} se déplace de la case {} à {}".format(mouvement[1].__class__.__name__,couleur_piece_depart,mouvement[2],mouvement[3])
            self.listbox_mouvement.insert(END,numero_deplacement)
            self.listbox_mouvement.itemconfig(END,fg= "blue")
            self.listbox_mouvement.insert(END, text_mouvement)
            self.listbox_mouvement.insert(END, "")
            self.listbox_mouvement.selection_clear(0, END)

    # Méthode qui affiche tous les pièces "mangées" de l'échiquier
    def ajouter_piece_manger(self, piece_mange):
        #affiche les pièces blanche
        if piece_mange.couleur == "blanc":
            self.Canvas_echiquier.piece_blanc_perdu  += str(piece_mange)
            self.messages_piece_blanc['text'] = "Pièces blanches:" +self.Canvas_echiquier.piece_blanc_perdu
        #affiche les pièce noir
        elif piece_mange.couleur == "noir":
            self.Canvas_echiquier.piece_noir_perdu += str(piece_mange)
            self.messages_piece_noir['text'] = "Pièces noirs:"+self.Canvas_echiquier.piece_noir_perdu

    # Méthode qui va permettre aux joueurs de pouvoir voir le dernier mouvement joué avec l'aide d'un bouton.
    def voir_dernier_mouvement(self):
        try:
            print(self.Canvas_echiquier.liste_mouvement_effectuer)
            print(self.Canvas_echiquier.dernier_mouvement_effectuer)
            mouvement= self.Canvas_echiquier.dernier_mouvement_effectuer

            nom_case = "case{}".format(mouvement[2])
            case = self.Canvas_echiquier.find_withtag(nom_case)
            self.Canvas_echiquier.itemconfig(case, fill = "green yellow")

            nom_case = "case{}".format(mouvement[3])
            case = self.Canvas_echiquier.find_withtag(nom_case)
            self.Canvas_echiquier.itemconfig(case, fill = "medium orchid1")

            self.messages['foreground'] = 'blue'
            self.messages['text'] = "Dernier mouvement effectué:\ndéplacement de la case verte à la case mauve"

        except (IndexError): # Message d'erreur si aucun coup joué
            self.messages['foreground'] = 'red'
            self.messages['text'] = "Il n'y a aucun coup de joué pour le moment."
Ejemplo n.º 9
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
Ejemplo n.º 10
0
    def __init__(self,
                 store_filename='partie1.bin',
                 store_filename2='partie2.bin',
                 store_filename3="deplacements1.txt",
                 store_filename4='deplacements2.txt'):
        super().__init__()

        self.title("Échiquier")

        # Background de la fenêtre.
        self.config(bg="AntiqueWhite1")

        # La position sélectionnée.
        self.position_selectionnee = None

        # Truc pour le redimensionnement automatique des éléments de la fenêtre.
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        # Création du canvas échiquier.
        self.canvas_echiquier = CanvasEchiquier(self, 60)
        self.canvas_echiquier.grid(sticky=NSEW)

        # Ajout d'une étiquette d'information.
        self.messages = Label(self)
        self.messages.grid()

        # Ajout d'un message box
        self.message_alerte = messagebox

        # On lie un clic sur le CanvasEchiquier à une méthode.
        self.canvas_echiquier.bind('<Button-1>', self.canvas_echiquier.jouer)

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

        # Frame unique pour les autres fonctions
        self.cadre_fonctions = Frame(self, relief="groove")
        self.cadre_fonctions.grid(row=0, column=1, padx=10, pady=10, sticky=S)
        self.cadre_fonctions.config(bg="AntiqueWhite1")
        self.cadre_fonctions_partie = Frame(self, relief="groove")
        self.cadre_fonctions_partie.config(bg="AntiqueWhite1")
        self.cadre_fonctions_partie.grid(row=0,
                                         column=1,
                                         padx=10,
                                         pady=10,
                                         sticky=N)

        # On importe les fonctions de parties
        self.partie = Partie()

        # L'emplacement du file
        self.store_filename = os.path.join(BASE_DIR, store_filename)
        self.store_filename2 = os.path.join(BASE_DIR, store_filename2)
        self.store_filename3 = os.path.join(BASE_DIR, store_filename3)
        self.store_filename4 = os.path.join(BASE_DIR, store_filename4)

        # Pour savoir nous sommes actuellement dans quel partie
        self.partie_actuel = 0

        # Label compteur
        self.m = 2
        self.s = 0
        self.compteur = StringVar()
        self.compteur.set(str(self.m) + ":" + str(self.s))
        self.lbl_compteur1 = Label(self.cadre_fonctions_partie,
                                   textvariable=self.compteur,
                                   bd=4,
                                   relief="groove",
                                   height=2).grid(row=0,
                                                  column=0,
                                                  sticky=NSEW,
                                                  padx=10,
                                                  pady=10)

        # Label joueur actif
        self.joueur_actif = StringVar()
        self.joueur_actif.set("C'est le tour du joueur  {}.".format(
            self.canvas_echiquier.partie.joueur_actif))
        self.lbl_joueur_actif = Label(self.cadre_fonctions_partie,
                                      textvariable=self.joueur_actif,
                                      relief="groove",
                                      bg="green",
                                      height=2).grid(row=1,
                                                     column=0,
                                                     sticky=NSEW,
                                                     padx=10,
                                                     pady=10)

        # Label Menu de partie
        self.lbl_options_de_partie = Label(self.cadre_fonctions_partie, text="Menu", relief="sunken",
                                           font="Arial 13 bold").grid \
            (row=2, column=0, sticky=NSEW, padx=10, pady=10)

        # Bouton Nouvelle Partie
        self.btn_nouvelle_partie = Button(
            self.cadre_fonctions_partie,
            text="Nouvelle partie",
            command=self.alerte_nouvelle_partie).grid(row=3,
                                                      column=0,
                                                      sticky=NSEW)

        # Bouton Fin du tour
        self.btn_fin_du_tour = Button(self.cadre_fonctions_partie,
                                      bg="yellow",
                                      text="Fin du tour",
                                      relief="groove",
                                      height=2,
                                      command=self.fin_du_tour).grid(
                                          row=2,
                                          column=0,
                                          sticky=NSEW,
                                          padx=10,
                                          pady=10)

        # Bouton Sauvegarder
        self.btn_Sauvegarder = Button(
            self.cadre_fonctions_partie,
            text="Sauvegarder la partie",
            command=self.alerte_sauvegarder_partie).grid(row=4,
                                                         column=0,
                                                         sticky=NSEW)

        # Bouton Charger
        self.btn_Charger = Button(self.cadre_fonctions_partie,
                                  text="Charger une partie",
                                  command=self.alerte_charger_partie).grid(
                                      row=5, column=0, sticky=NSEW)

        # Boutton Quitter
        self.btn_quitter = Button(self.cadre_fonctions_partie,
                                  text="Quitter",
                                  command=self.quit).grid(row=6,
                                                          column=0,
                                                          sticky=NSEW)

        # Label options de partie
        self.lbl_options_de_partie = Label(self.cadre_fonctions, text="Options", relief="sunken",
                                           font="Arial 13 bold").grid \
            (row=1, column=0, sticky=NSEW, padx=10, pady=10)

        # Boutton revoir la partie

        self.btn_revoir_partie = Button(
            self.cadre_fonctions,
            text="Revoir une partie",
            command=self.alert_revoir_une_partie).grid(row=7,
                                                       column=0,
                                                       sticky=NSEW)

        # Bouton annuler deplacement
        self.btn_console = Button(self.cadre_fonctions,
                                  text="Annuler le dernier mouvement",
                                  command=self.annuler_deplacement).grid(
                                      row=8, column=0, sticky=NSEW)

        # Bouton pour afficher les déplacements effectués
        self.btn_console = Button(
            self.cadre_fonctions,
            text="Afficher les déplacements effectués",
            command=self.afficher_liste_deplacements).grid(row=9,
                                                           column=0,
                                                           sticky=NSEW)

        # Bouton pour lire les règlements du jeux
        self.btn_reglement = Button(
            self.cadre_fonctions,
            text="Voir les règlements du jeux en ligne",
            command=self.openweb).grid(row=10, column=0, sticky=NSEW)
        # Bouton changer thème:
        self.btn_changer_theme = Button(self.cadre_fonctions,
                                        text="Changer le thème",
                                        command=self.changer_theme).grid(
                                            row=11, column=0, sticky=NSEW)
Ejemplo n.º 11
0
class Fenetre(Tk):
    def __init__(self):
        super().__init__()
        self.estTermine = False
        self.estSauvegarde = False
        self.listemovements = []
        self.listepiecesnoirs = []
        self.listepiecesblanches = []
        self.chrono_actif = False

        # On redéfinie ce qui se passe lors de la fermeture du  fichier.
        self.protocol("WM_DELETE_WINDOW", self.demandesauvegarde)

        # Nom de la fenêtre.
        self.title("Échiquier")

        self.partie = Partie()

        # La position sélectionnée.
        self.position_selectionnee = None

        # Truc pour le redimensionnement automatique des éléments de la fenêtre.
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        # Création du canvas échiquier.
        self.canvas_echiquier = CanvasEchiquier(self, 60, self.partie)
        self.canvas_echiquier.grid(row=0, column=0, sticky=NSEW)

        # Création du menu
        self.menubar = BarreMenu(self, self.canvas_echiquier)
        self.config(menu=self.menubar)

        # Ajout d'une étiquette d'information.
        self.lblMessages = Label(self)
        self.lblMessages.config(font=("Courier", 18))
        self.lblMessages.grid()

        self.lblMessagejoueuractif = Label(self)
        self.lblMessagejoueuractif['text'] = 'Tour du joueur blanc'
        self.lblMessagejoueuractif.config(font=("Courier", 18))
        self.lblMessagejoueuractif.grid()

        # Listes des pièces perdues par chaque joueurs
        self.lblpiecesblanches = Label(self, anchor='w')
        self.lblpiecesblanches.grid(row=4, column=0)
        self.lblpiecesblanches.config(font=("Courier", 14))
        self.lblpiecesblanches['text'] = 'Pièces noires perdues: '

        self.lblpiecesnoires = Label(self, anchor='w')
        self.lblpiecesnoires.config(font=("Courier", 14))
        self.lblpiecesnoires.grid(row=4, column=1)
        self.lblpiecesnoires['text'] = 'Pièces blanches perdues: '

        # Création d'une zone de texte pour l'affichage des déplacements.
        self.afficher_deplacement = False

        self.txtListe = Text(self)
        self.txtListe.grid(row=0, column=1, sticky=NSEW)

        self.lblListe = Label(self)
        self.lblListe['text'] = 'La liste des mouvements'
        self.lblListe.grid(row=1, column=1, sticky=NSEW)

        # On lie un clic sur le CanvasEchiquier à une méthode.
        self.canvas_echiquier.bind('<Button-1>', self.selectionner)

        # chrono
        self.chrono = Label(text="")
        self.chrono.grid(row=5, column=0, sticky=NSEW)
        self.minute = 0
        self.second = 0
        self.color_chrono = "blue"

    def update_clock(self):
        if self.chrono_actif:
            self.second += 1
            if self.second == 60:
                self.second = 0
                self.minute += 1
            elif self.minute == 1 and self.second == 30:
                self.color_chrono = "red"
            elif self.minute == 2:
                self.second = 0
                self.minute = 0
                self.partie.joueur_suivant()

        now = f'Chrono: {self.minute} m : {self.second} s'
        self.chrono.configure(text=now, fg=self.color_chrono)
        self.canvas_echiquier.after(1000, self.update_clock)

    def stop_clock(self):
        self.canvas_echiquier.after_cancel(self.update_clock)
        self.second = 0
        self.chrono_actif = False

    def selectionner(self, event):
        # On trouve le numéro de ligne/colonne en divisant les positions en y/x par le nombre de pixels par case.
        ligne = event.y // self.canvas_echiquier.n_pixels_par_case
        colonne = event.x // self.canvas_echiquier.n_pixels_par_case
        position = "{}{}".format(
            self.canvas_echiquier.lettres_colonnes[colonne],
            int(self.canvas_echiquier.chiffres_rangees[
                self.canvas_echiquier.n_lignes - ligne - 1]))

        # print(event.x)               # Pour des fins de débug'
        # print(event.y)               # Pour des fins de débug

        if not self.partie.partie_terminee():
            try:
                if self.canvas_echiquier.position_selectionnee is None:
                    if self.partie.echiquier.recuperer_piece_a_position(
                            position):
                        if self.partie.joueur_actif == self.partie.echiquier.couleur_piece_a_position(
                                position):
                            # print('1er clic')  # Pour tester les positions sélectionnées

                            self.canvas_echiquier.position_selectionnee = position
                            self.lblMessages['text'] = ""
                        else:
                            messagebox.showwarning(
                                'Mauvaise couleur',
                                'Mauvaise couleur de pièce sélectionnée')

                else:
                    # print('second clic') # Pour tester les positions sélectionnées
                    # print(self.canvas_echiquier.position_selectionnee, position)
                    piecesource = self.partie.echiquier.recuperer_piece_a_position(
                        self.canvas_echiquier.position_selectionnee)

                    piececible = self.partie.echiquier.recuperer_piece_a_position(
                        position)

                    # Si une prise est faite, affiche la pièce. Sinon affiche seulement le déplacement.
                    if piececible is not None:
                        mouvement = "Le joueur {} a joué la pièce {} de {} à {} et a prit la pièce {}".format(
                            self.partie.joueur_actif, piecesource,
                            self.canvas_echiquier.position_selectionnee,
                            position, piececible)

                    else:
                        mouvement = "Le joueur {} a joué la pièce {} de {} à {} ". \
                            format(self.partie.joueur_actif, piecesource, self.canvas_echiquier.position_selectionnee,
                                   position)
                    self.partie.deplacer(
                        self.canvas_echiquier.position_selectionnee, position)
                    self.minute = 0
                    self.second = 0

                    if piececible is not None:
                        self.piecesprises(piececible)
                    self.listemovements.append(mouvement)
                    self.canvas_echiquier.position_selectionnee = None
                    self.estSauvegarde = False

                    self.rafraichirtexte()

            except (ErreurDeplacement, AucunePieceAPosition,
                    MauvaiseCouleurPiece) as e:
                self.canvas_echiquier.position_selectionnee = None
                messagebox.showwarning("Erreur", e)
                self.canvas_echiquier.position_selectionne = None
            finally:
                self.canvas_echiquier.raffraichir()

            if self.partie.joueur_actif == 'blanc':
                self.lblMessagejoueuractif['foreground'] = 'black'
                self.lblMessagejoueuractif['text'] = 'Tour du joueur blanc'

            else:
                self.lblMessagejoueuractif['foreground'] = "black"
                self.lblMessagejoueuractif['text'] = 'Tour du joueur noir'

        if self.partie.partie_terminee():
            if messagebox.askyesno(
                    "Partie terminée", "La partie est terminée, le joueur " +
                    self.partie.determiner_gagnant() + ' a gagné! =)' + '\n' +
                    'Voulez-vous rejouer de nouveau?'):
                self.menubar.nouvelle_partie()

    def piecesprises(self, piece):
        if self.partie.joueur_actif == "blanc":
            self.listepiecesnoirs.append(piece)

        elif self.partie.joueur_actif == "noir":
            self.listepiecesblanches.append(piece)

    def demandesauvegarde(self):
        if not self.estSauvegarde:
            if not messagebox.askyesno(
                    "Quitter", "Voulez vous sauvegarder avant de quitter?"):
                self.destroy()
            else:
                self.menubar.sauvegarder()
                self.destroy()
        else:
            self.destroy()

    def rafraichirtexte(self):

        self.txtListe['foreground'] = "purple"
        self.txtListe.delete("1.0", END)
        for x in self.listemovements:
            self.txtListe.insert(END, x + "\n")

        if self.partie.partie_terminee():
            self.txtListe.insert(
                END, "La partie est terminée. Le joueur  " +
                self.partie.determiner_gagnant() + ' a gagné! =)')

        self.lblpiecesblanches.config(
            text='Pièces noires perdues: ' +
            (" ".join(map(str, self.listepiecesblanches))))
        self.lblpiecesnoires.config(
            text='Pièces blanches perdues: ' +
            (" ".join(map(str, self.listepiecesnoirs))))
Ejemplo n.º 12
0
# -*- coding: utf-8 -*-
"""Module principal du package pychecs2. C'est ce module que nous allons exécuter pour démarrer votre jeu.
Importez les modules nécessaires et démarrez votre programme à partir d'ici. Le code fourni n'est qu'à titre d'exemple.

"""
from pychecs2.echecs.partie import Partie
from pychecs2.interface.exemple import Fenetre

if __name__ == '__main__':
    # Création d'une instance de Partie.
    p = Partie()

    # Affichage de l'échiquier dans cette partie.
    # print(p.echiquier)

    # Création et affichage d'une fenêtre (aucun lien avec la partie ci-haut).
    Fenetre().mainloop()

    #test push
Ejemplo n.º 13
0
class Fenetre(Tk):
    def __init__(self):
        super().__init__()

        self.protocol("WM_DELETE_WINDOW", self.fermeture)

        # Nom de la fenêtre.
        self.title("Échiquier")

        #Initialisation d'une partie
        self.partie = Partie()

        # Truc pour le redimensionnement automatique des éléments de la fenêtre.
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        # Création du canvas échiquier.
        self.canvas_echiquier = CanvasEchiquier(self, 60, self.partie)
        self.canvas_echiquier.grid(sticky=NSEW)

        # Ajout d'une étiquette d'information.
        self.messages = Label(self)
        self.messages.grid()

        # Ajout d'une étiquette qui indique le joueur actif.
        self.messages_joueur_actif = Label(self)
        self.messages_joueur_actif['text'] = (
            "C'est au joueur blanc de commencer! ")
        self.messages_joueur_actif['foreground'] = 'blue'
        self.messages_joueur_actif.grid()

        # On lie un clic sur le CanvasEchiquier à une méthode.
        self.canvas_echiquier.bind('<Button-1>', self.selectionner)

        # Ajout d'un cadre pour regrouper les boutons
        frame_boutons = Frame(self)
        frame_boutons.grid(row=0, column=1)

        #Bouton pour annuler le dernier mouvement.
        bouton_dernier_mouvement = bouton_sauvegarder = Button(
            frame_boutons,
            text="Annuler le dernier mouvement",
            command=self.charger_dernier_mouvement)
        bouton_dernier_mouvement.grid()

        #Ajout des boutons pour sauvegarder et charger une partie.
        bouton_sauvegarder = Button(frame_boutons,
                                    text="Sauvegarder la partie",
                                    command=self.sauvegarder_partie)
        bouton_charger = Button(frame_boutons,
                                text="Charger la partie",
                                command=self.charger_partie)
        bouton_sauvegarder.grid()
        bouton_charger.grid()

        #Ajout d'un bouton pour commencer une nouvelle partie.
        bouton_nouvelle_partie = Button(frame_boutons,
                                        text="Nouvelle partie",
                                        command=self.nouvelle_partie)
        bouton_nouvelle_partie.grid()

    def fermeture(self):

        if messagebox.askyesno(
                "Quitter",
                "Voulez vous sauvegarder la partie avant de quitter?"):
            self.sauvegarder_partie()

        self.destroy()

    def mise_a_jour_message_joueur_actif(self):
        self.messages_joueur_actif['foreground'] = 'blue'
        self.messages_joueur_actif['text'] = ("C'est le tour du joueur " +
                                              self.partie.joueur_actif + '.')

    def sauvegarder_partie(self):
        with open('./sauvegarde_partie.bin', 'wb') as f:
            pickle.dump(self.partie, f)

    def charger_partie(self):
        with open('./sauvegarde_partie.bin', 'rb') as f:
            try:
                self.canvas_echiquier.partie = pickle.load(f)

                self.partie = self.canvas_echiquier.partie

                self.canvas_echiquier.rafraichir()

                self.mise_a_jour_message_joueur_actif()

            except EOFError:
                self.messages['text'] = "Il n'y a pas de partie sauvegarder !"

    def sauvegarder_dernier_mouvement(self):
        with open('./dernier_mouvement.bin', 'wb') as f:
            pickle.dump(self.partie, f)

    def charger_dernier_mouvement(self):
        with open('./dernier_mouvement.bin', 'rb') as f:
            try:
                self.canvas_echiquier.partie = pickle.load(f)

                #C'est la chose la plus redneck que j'ai fait de toute ma vie
                self.partie = self.canvas_echiquier.partie

                self.canvas_echiquier.rafraichir()

                self.mise_a_jour_message_joueur_actif()

            except EOFError:
                self.messages['text'] = "Il n'y a pas de dernier mouvement !"

    def nouvelle_partie(self):
        self.canvas_echiquier.partie = Partie()
        self.partie = self.canvas_echiquier.partie

        self.canvas_echiquier.rafraichir()

        self.mise_a_jour_message_joueur_actif()
        self.messages['text'] = ""

    def premier_clic_valide(self, position):
        #Ceci permet au joueur actif de changer de pièce source sans compléter le déplacement.
        piece = self.partie.echiquier.recuperer_piece_a_position(position)

        if piece is None:
            raise AucunePieceAPosition('Aucune pièce à cet endroit!')
        elif piece.couleur != self.partie.joueur_actif:
            raise MauvaiseCouleurPiece("La pièce n'appartient pas au joueur " +
                                       self.partie.joueur_actif + '!')

    def selectionner(self, event):
        # On trouve le numéro de ligne/colonne en divisant les positions en y/x par le nombre de pixels par case.
        ligne = event.y // self.canvas_echiquier.n_pixels_par_case
        colonne = event.x // self.canvas_echiquier.n_pixels_par_case
        position = "{}{}".format(
            self.canvas_echiquier.lettres_colonnes[colonne],
            int(self.canvas_echiquier.chiffres_rangees[
                self.canvas_echiquier.n_lignes - ligne - 1]))

        # Ce qui met en jaune c'est cette ligne-ci
        case = self.canvas_echiquier.correspondance_case_rectangle[position]
        self.canvas_echiquier.itemconfig(case, fill='yellow')

        self.sauvegarder_dernier_mouvement()

        try:
            if self.canvas_echiquier.position_selectionnee == None:

                # Puisque la pièce source est valide, on retire le message d'erreur actif
                self.messages['text'] = ""

                self.premier_clic_valide(position)

                #Premier clic: position_source
                self.canvas_echiquier.position_selectionnee = position

            else:
                # Condition qui permet de changer d'idée en cliquant sur une autre des pièces du joueur actif
                if self.partie.echiquier.couleur_piece_a_position(
                        position) == self.partie.joueur_actif:

                    self.canvas_echiquier.rafraichir()
                    self.canvas_echiquier.position_selectionnee = position

                    case = self.canvas_echiquier.correspondance_case_rectangle[
                        position]
                    self.canvas_echiquier.itemconfig(case, fill='yellow')

                else:
                    # Deuxième clic: position_cible
                    self.partie.deplacer(
                        self.canvas_echiquier.position_selectionnee, position)
                    self.canvas_echiquier.position_selectionnee = None

                    # Detection echec
                    # Note: le joueur actif a changé
                    if self.partie.echiquier.echec_sur_le_roi_de_couleur(
                            self.partie.joueur_actif):
                        self.messages[
                            'text'] = "Le roi " + self.partie.joueur_actif + " est en échec!"

                        #TODO: Échec et mat ici.
                        #if self.partie.echiquier.echec_et_mat_sur_le_roi_de_couleur(self.partie.joueur_actif):
                        #    self.messages['text'] = "Le roi " + self.partie.joueur_actif + " est en échec et mat!"

            if self.partie.partie_terminee():
                self.messages['foreground'] = 'green'
                self.messages[
                    'text'] = 'Partie terminée! Le joueur ' + self.partie.determiner_gagnant(
                    ) + (' a gagné!')
            else:
                self.mise_a_jour_message_joueur_actif()

        except (ErreurDeplacement, AucunePieceAPosition,
                MauvaiseCouleurPiece) as e:
            self.messages['foreground'] = 'red'
            self.messages['text'] = e
            self.canvas_echiquier.position_selectionnee = None

        except ProvoqueEchecJoueursActif as e:
            self.messages['text'] = e
            self.charger_dernier_mouvement()
            self.canvas_echiquier.position_selectionnee = None

        finally:
            if self.canvas_echiquier.position_selectionnee == None:
                self.canvas_echiquier.rafraichir()
Ejemplo n.º 14
0
    def __init__(self):
        super().__init__()
        self.estTermine = False
        self.estSauvegarde = False
        self.listemovements = []
        self.listepiecesnoirs = []
        self.listepiecesblanches = []
        self.chrono_actif = False

        # On redéfinie ce qui se passe lors de la fermeture du  fichier.
        self.protocol("WM_DELETE_WINDOW", self.demandesauvegarde)

        # Nom de la fenêtre.
        self.title("Échiquier")

        self.partie = Partie()

        # La position sélectionnée.
        self.position_selectionnee = None

        # Truc pour le redimensionnement automatique des éléments de la fenêtre.
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        # Création du canvas échiquier.
        self.canvas_echiquier = CanvasEchiquier(self, 60, self.partie)
        self.canvas_echiquier.grid(row=0, column=0, sticky=NSEW)

        # Création du menu
        self.menubar = BarreMenu(self, self.canvas_echiquier)
        self.config(menu=self.menubar)

        # Ajout d'une étiquette d'information.
        self.lblMessages = Label(self)
        self.lblMessages.config(font=("Courier", 18))
        self.lblMessages.grid()

        self.lblMessagejoueuractif = Label(self)
        self.lblMessagejoueuractif['text'] = 'Tour du joueur blanc'
        self.lblMessagejoueuractif.config(font=("Courier", 18))
        self.lblMessagejoueuractif.grid()

        # Listes des pièces perdues par chaque joueurs
        self.lblpiecesblanches = Label(self, anchor='w')
        self.lblpiecesblanches.grid(row=4, column=0)
        self.lblpiecesblanches.config(font=("Courier", 14))
        self.lblpiecesblanches['text'] = 'Pièces noires perdues: '

        self.lblpiecesnoires = Label(self, anchor='w')
        self.lblpiecesnoires.config(font=("Courier", 14))
        self.lblpiecesnoires.grid(row=4, column=1)
        self.lblpiecesnoires['text'] = 'Pièces blanches perdues: '

        # Création d'une zone de texte pour l'affichage des déplacements.
        self.afficher_deplacement = False

        self.txtListe = Text(self)
        self.txtListe.grid(row=0, column=1, sticky=NSEW)

        self.lblListe = Label(self)
        self.lblListe['text'] = 'La liste des mouvements'
        self.lblListe.grid(row=1, column=1, sticky=NSEW)

        # On lie un clic sur le CanvasEchiquier à une méthode.
        self.canvas_echiquier.bind('<Button-1>', self.selectionner)

        # chrono
        self.chrono = Label(text="")
        self.chrono.grid(row=5, column=0, sticky=NSEW)
        self.minute = 0
        self.second = 0
        self.color_chrono = "blue"
Ejemplo n.º 15
0
class Fenetre(Tk):
    def __init__(self):
        super().__init__()

        # Nom de la fenêtre.
        self.title("Échiquier")

        self.partie = Partie()

        #Bouton X (pour quitter)
        self.protocol('WM_DELETE_WINDOW', self.message_quitter)

        # Truc pour le redimensionnement automatique des éléments de la fenêtre.
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        # Création du canvas échiquier.
        self.canvas_echiquier = CanvasEchiquier(self, 60, self.partie)
        self.canvas_echiquier.grid(sticky=NSEW)

        ##########################################################
        #                                                        #
        #                    VISUEL                              #
        #                                                        #
        ##########################################################
        # Étiquette d'information et de sélection des pièces
        self.messages = Label(self)
        self.messages['foreground'] = 'black'
        self.messages['text'] = "Bienvenue au super jeux d'échec!"
        self.messages.grid(row=1, sticky='w')

        # # Étiquette d'information sur le joueur courant
        self.messages1 = Label(self)
        self.messages1[
            'text'] = "Au tour du joueur: " + self.partie.joueur_actif.upper()
        self.messages1.grid(row=2, sticky='w')
        self.messages1['foreground'] = 'blue'

        # Création du frame a droite du canevas
        self.monFramePrincipal = Frame(self)
        self.monFramePrincipal.grid(row=0, column=1, sticky='n')

        # FRAME a DROITE: Fenetre pour afficher la liste des déplacements effectués
        self.mon_frame1 = LabelFrame(self.monFramePrincipal,
                                     text="Les déplacements ",
                                     borderwidth=2,
                                     relief=RIDGE,
                                     padx=5,
                                     pady=5)
        self.mon_frame1.grid(row=0, column=0, sticky='n')
        self.yScroll = Scrollbar(self.mon_frame1, orient=VERTICAL)
        self.yScroll.grid(row=0, column=1, sticky=N + S)
        #small_font = font(size=5)
        self.liste1 = Listbox(self.mon_frame1, yscrollcommand=self.yScroll.set)
        self.liste1 = Listbox(self.mon_frame1)
        self.liste1.grid(row=0, column=0)
        self.yScroll['command'] = self.liste1.yview

        # Creation d'un espace pour mettre les 2 fenetres de pièces mangées (un sous-Frame)
        self.monSousFrame = Frame(self.monFramePrincipal)
        self.monSousFrame.grid(row=1, column=0, sticky='n')

        # FRAME a DROITE: Fenetre pour afficher les pieces blanches mangées
        self.mon_frame2 = LabelFrame(self.monSousFrame,
                                     text="Les blancs\nmangés ",
                                     borderwidth=2,
                                     relief=RIDGE,
                                     padx=5,
                                     pady=5,
                                     width=7)
        self.mon_frame2.grid(row=0, column=0, sticky='n')
        self.yScroll = Scrollbar(self.mon_frame2, orient=VERTICAL)
        self.yScroll.grid(row=0, column=1, sticky=N + S)
        self.liste2 = Listbox(self.mon_frame2, yscrollcommand=self.yScroll.set)
        self.liste2 = Listbox(self.mon_frame2, width=7)
        self.liste2.grid(row=0, column=0)
        self.yScroll['command'] = self.liste2.yview

        # FRAME a DROITE: Fenetre pour afficher les pieces noires mangées
        self.mon_frame2 = LabelFrame(self.monSousFrame,
                                     text="Les noirs\nmangés ",
                                     borderwidth=2,
                                     relief=RIDGE,
                                     padx=5,
                                     pady=5,
                                     width=7)
        self.mon_frame2.grid(row=0, column=1, sticky='n')
        self.yScroll = Scrollbar(self.mon_frame2, orient=VERTICAL)
        self.yScroll.grid(row=0, column=1, sticky=N + S)
        self.liste3 = Listbox(self.mon_frame2, yscrollcommand=self.yScroll.set)
        self.liste3 = Listbox(self.mon_frame2, width=7)
        self.liste3.grid(row=0, column=0)
        self.yScroll['command'] = self.liste3.yview

        # FRAME a DROITE: Bouton pour se connecter au site web des intrusctions d'echec
        self.mon_frame3 = Frame(self.monFramePrincipal,
                                borderwidth=2,
                                relief=RIDGE,
                                padx=5,
                                pady=5)
        self.mon_frame3.grid(row=2, column=0, sticky='n')
        but1 = Button(self.mon_frame3,
                      text="Lien web pour accéder\naux règles du jeux!",
                      command=self.ouvrirURL).grid(row=0, column=0)

        # Frame pour les options de jeux en bas de l'échiquier
        self.mon_frame = LabelFrame(self,
                                    text="Options de partie",
                                    borderwidth=2,
                                    relief=RIDGE,
                                    padx=5,
                                    pady=5)
        self.mon_frame.grid(row=4, column=0, sticky='w')
        bouton_sauver = Button(self.mon_frame,
                               text="Sauvegarder",
                               command=self.sauvergarder).grid(row=0, column=0)
        bouton_charge = Button(self.mon_frame,
                               text="Charger",
                               command=self.message_charger).grid(row=0,
                                                                  column=1)
        bouton_demarrer = Button(self.mon_frame,
                                 text="Redémarrage",
                                 command=self.message_reinitialiser).grid(
                                     row=0, column=2)
        bouton_annuler = Button(self.mon_frame,
                                text="Annuler dernier mouvement",
                                command=self.annulerDernierMouvement).grid(
                                    row=0, column=3)

        # On lie un clic sur le CanvasEchiquier à une méthode.
        self.canvas_echiquier.bind('<Button-1>', self.selectionner)

        self.piece_a_deplacer = None
        self.position_piece_a_deplacer = None

        #Pour que x et y soient accessibles dans selectionner ET dans creer_carre_selection
        self.x = 1
        self.y = 1

    def message_charger(self):
        """"
            Ouvre une fenêtre s'assurant que l'utilisateur veut bien charger.
            Lui propose de sauvegarder la partie.
        """
        message = messagebox.askyesno(
            'Avertissement',
            'Voulez-vous vraiment charger une autre partie? \nCette partie sera perdue.',
            icon='warning')
        if message is True:
            self.charger()

    def message_reinitialiser(self):
        """"
            Ouvre une fenêtre s'assurant que l'utilisateur veut bien réinitialiser.
            Lui propose de sauvegarder la partie.
        """
        message = messagebox.askyesnocancel(
            'Avertissement',
            'Voulez-vous sauvgarder avant de redémarrer la partie? \nTout changement non sauvegardé sera perdu.',
            icon='warning')
        if message is True:
            self.sauvergarder()
            self.reinitialiser()
        elif message is False:
            self.reinitialiser()

    def message_quitter(self):
        """"
            Ouvre une fenêtre s'assurant que l'utilisateur veut bien quitter.
            Lui propose de sauvegarder la partie.
        """
        message = messagebox.askyesnocancel(
            'Avertissement',
            'Voulez-vous sauvgarder avant de quitter? \nTout changement non sauvegardé sera perdu.',
            icon='warning')
        if message is True:
            self.sauvergarder()
            self.destroy()
        elif message is False:
            self.destroy()

    def ouvrirURL(self):
        '''
        Permet d'ouvrir un ULR qui donne sur les règlements du jeux d'échec
        '''
        url = 'https://fr.wikipedia.org/wiki/Règles_du_jeu_d%27échecs'
        webbrowser.open_new(url)

    def reinitialiser(self):
        '''
        Permet de raffraichir les cases, les pieces, les pieces mangées et les informations dans les Listbox
        pour les déplacements et les pièces blanches et noires.
        '''
        self.partie.echiquier.initialiser_echiquier_depart()
        self.partie.joueur_actif = 'blanc'
        self.messages['text'] = ''
        self.canvas_echiquier.raffraichir_cases()
        self.canvas_echiquier.raffraichir_pieces()
        self.rafraichirPiecesMangees()
        self.liste1.delete(0, END)
        self.liste2.delete(0, END)
        self.liste3.delete(0, END)

    def entrer_nom_sauvegarde(self):
        """"
            On affiche une fenêtre demandant à l'utlisateur d'entrer un nom pour la partie à sauvegarder.
            Pour charger une partie sauvegardée, il faut entrer le nom de la sauvegarde choisi ici.
            Par défaut, le nom de la sauvegarde est 'sauvegarde'.
        """
        popup = Tk()
        popup.withdraw()
        nom_sauvegarde = simpledialog.askstring(
            title="Sauvegarder",
            prompt="Entrez le nom de la partie à sauvegarder:",
            initialvalue="sauvegarde")

        self.partie.nom_fichier_sauvegarde = nom_sauvegarde

    def recuperer_nom_sauvegarde(self):
        """"
            On affiche une fenêtre demandant à l'utlisateur d'entrer le nom d'une sauvegarde existante.
            Ce nom sera stocké dans self.partie.nom_fichier_sauvegarde.
        """
        popup = Tk()
        popup.withdraw()
        nom_sauvegarde = simpledialog.askstring(
            title="Charger",
            prompt="Entrez le nom d'une partie sauvegardée existante:")

        self.partie.nom_fichier_sauvegarde = nom_sauvegarde

    def sauvergarder(self):
        """"
            Sauvegarde la position des pièces dans l'échiquier au moment de la sauvegarde.
            La sauvegarde est faite au nom entré par l'utilisateur dans self.partie.nom_fichier_sauvegarde.
        """
        self.entrer_nom_sauvegarde()
        if self.partie.nom_fichier_sauvegarde != '' and self.partie.nom_fichier_sauvegarde is not None:
            self.partie.sauvegarder_partie()

        self.canvas_echiquier.raffraichir_cases()
        self.canvas_echiquier.raffraichir_pieces()

    def charger(self):
        """"
        Permet de charger une partie existante.
        Si le nom entré n'existe pas, retourne une erreur.
        Si le fichier existe, il charge l'échiqier.
        """
        self.recuperer_nom_sauvegarde()
        try:
            self.partie.charger_partie()
        except:
            popup = Tk()
            popup.title('Erreur')

            label = Label(
                popup,
                text=
                "Le nom de sauvegarde entré n'existe pas. Impossible de charger la partie."
            )
            label.grid()
            popup.mainloop()

        self.canvas_echiquier.raffraichir_cases()
        self.canvas_echiquier.raffraichir_pieces()

    def annulerDernierMouvement(self):
        '''
        Permet d'annuler le dernier mouvement et de mettre à jour l'affichage
        '''
        try:
            self.partie.annulerDernierMouvement()
            self.canvas_echiquier.raffraichir_cases()
            self.canvas_echiquier.raffraichir_pieces()

            self.liste1.delete(END)
            self.messages1[
                'text'] = "Au tour du joueur: " + self.partie.joueur_actif.upper(
                )
            self.rafraichirPiecesMangees()
        except:
            self.messages[
                'text'] = "Vous ne pouvez pas retourner davantage en arrière."
            self.messages['foreground'] = 'red'

    def rafraichirPiecesMangees(self):
        '''
        Permet de rafraichir l'affichage des pièces blanches et noires mangées
        '''
        self.liste2.delete(0, END)
        for i in self.partie.gapBlanc:
            self.liste2.insert(END, i)
        self.liste3.delete(0, END)
        for i in self.partie.gapNoir:
            self.liste3.insert(END, i)

    def roi_en_rouge(self):
        """"
            Si le Roi du joueur actif est en échec, un carré rouge est créé sous le Roi menacé.
        """
        if self.partie.mon_roi_en_echec():
            #On supprime les pieces et les cases
            # self.canvas_echiquier.delete('case')
            # self.canvas_echiquier.delete('piece')

            #On determine la position du Roi en échec:
            position_roi = self.partie.position_mon_roi(
                self.partie.joueur_actif)

            #Écriture de la case du roi en pixels
            index_colonne = self.partie.echiquier.lettres_colonnes.index(
                position_roi[0])
            coordonnees_x1 = index_colonne * self.canvas_echiquier.n_pixels_par_case
            coordonnees_x2 = coordonnees_x1 + self.canvas_echiquier.n_pixels_par_case

            coordonnees_y1 = (7 - self.partie.echiquier.chiffres_rangees.index(
                position_roi[1])) * self.canvas_echiquier.n_pixels_par_case
            coordonnees_y2 = coordonnees_y1 + self.canvas_echiquier.n_pixels_par_case

            #On redessine les cases
            # self.canvas_echiquier.dessiner_cases()

            #Dessin du carré rouge
            self.canvas_echiquier.create_rectangle(coordonnees_x1,
                                                   coordonnees_y1,
                                                   coordonnees_x2,
                                                   coordonnees_y2,
                                                   fill='red')
            #On redessine les pieces
            # self.canvas_echiquier.dessiner_pieces()

    def creer_carre_selection(self):
        """"
            Dessine un carré rose à la position (x,y).
            Méthode appelée pour identifier la case sélectionnée par le joueur.
        """

        #Dessiner le carre
        self.canvas_echiquier.create_rectangle(
            (self.x // self.canvas_echiquier.n_pixels_par_case) *
            self.canvas_echiquier.n_pixels_par_case,
            (self.y // self.canvas_echiquier.n_pixels_par_case) *
            self.canvas_echiquier.n_pixels_par_case,
            ((self.x // self.canvas_echiquier.n_pixels_par_case) + 1) *
            self.canvas_echiquier.n_pixels_par_case,
            ((self.y // self.canvas_echiquier.n_pixels_par_case) + 1) *
            self.canvas_echiquier.n_pixels_par_case,
            fill='pink',
            tags='select')

    def selectionner(self, event):
        """"
            Identifie ou le joueur a cliqué sur le canvas.
            Permet de sélectionner les pièces et de les déplacer.
            S'assure que les sélections et les déplacements sont valides selon les règles du jeu d'échec.
        """
        self.x = event.x
        self.y = event.y

        # On trouve le numéro de ligne/colonne en divisant les positions en y/x par le nombre de pixels par case.
        ligne = event.y // self.canvas_echiquier.n_pixels_par_case
        colonne = event.x // self.canvas_echiquier.n_pixels_par_case
        position = "{}{}".format(
            self.canvas_echiquier.lettres_colonnes[colonne],
            self.canvas_echiquier.chiffres_rangees[
                self.canvas_echiquier.n_lignes - ligne - 1])
        self.position = position

        piece_selectionnee = self.partie.echiquier.recuperer_piece_a_position(
            position)

        # Si la case sélectionnée est vide
        if piece_selectionnee is None:
            if self.piece_a_deplacer is None:  #Si aucune pièce n'est stockée dans self.piece_a_deplacer
                # Dessin de l'echiquier
                self.canvas_echiquier.delete('case')
                self.canvas_echiquier.delete('piece')
                self.canvas_echiquier.dessiner_cases()
                self.roi_en_rouge()
                self.canvas_echiquier.dessiner_pieces()

                self.messages[
                    'text'] = f"Il n'y a aucune pièce à la position {position}."
                self.messages['foreground'] = 'red'

            else:  #Si un pièce est stockée dans self.piece_a_deplacer
                try:  #On essaye d'effectuer le déplacement
                    self.partie.deplacer(self.position_piece_a_deplacer,
                                         position)

                    #Derniers déplacements et pièces mangées
                    self.liste1.insert(END, self.partie.dernierDeplacement)
                    self.liste2.delete(0, END)
                    for i in self.partie.gapBlanc:
                        self.liste2.insert(END, i)
                    self.liste3.delete(0, END)
                    for i in self.partie.gapNoir:
                        self.liste3.insert(END, i)

                    self.piece_a_deplacer = None
                    self.position_piece_a_deplacer = None

                    # Dessin de l'echiquier
                    self.canvas_echiquier.delete('case')
                    self.canvas_echiquier.delete('piece')
                    self.canvas_echiquier.delete('select')
                    self.canvas_echiquier.dessiner_cases()
                    self.roi_en_rouge()
                    self.canvas_echiquier.dessiner_pieces()

                    self.messages['text'] = ''
                except:  #Si le déplacement est non valide
                    self.piece_a_deplacer = None
                    self.position_piece_a_deplacer = None

                    # Dessin de l'echiquier
                    self.canvas_echiquier.delete('case')
                    self.canvas_echiquier.delete('piece')
                    self.canvas_echiquier.delete('select')
                    self.canvas_echiquier.dessiner_cases()
                    self.roi_en_rouge()
                    self.canvas_echiquier.dessiner_pieces()

                    self.messages['text'] = f"Le déplacement est invalide."
                    self.messages['foreground'] = 'red'
        #Si la case sélectionnée contient une pièce appartenant au joueur actif
        elif piece_selectionnee.couleur == self.partie.joueur_actif:
            if self.piece_a_deplacer is None:  #Si aucune pièce n'est stockée dans self.piece_a_deplacer, on emagasine celle slectionnée
                self.piece_a_deplacer = piece_selectionnee
                self.position_piece_a_deplacer = position

                #Dessin de l'echiquier
                self.canvas_echiquier.delete('case')
                self.canvas_echiquier.delete('piece')
                self.canvas_echiquier.dessiner_cases()
                self.creer_carre_selection()
                self.roi_en_rouge()
                self.canvas_echiquier.dessiner_pieces()

                self.messages[
                    'text'] = f'Pièce sélectionnée : {self.piece_a_deplacer} à la position {position}.'
                self.messages['foreground'] = 'black'
            elif self.piece_a_deplacer == piece_selectionnee:  #1c

                self.piece_a_deplacer = None
                self.position_piece_a_deplacer = None

                # Dessin de l'echiquier
                self.canvas_echiquier.delete('case')
                self.canvas_echiquier.delete('piece')
                self.canvas_echiquier.delete('select')
                self.canvas_echiquier.dessiner_cases()
                self.roi_en_rouge()
                self.canvas_echiquier.dessiner_pieces()

                self.messages['text'] = f'Aucune pièce sélectionnée.'
                self.messages['foreground'] = 'black'
            else:  # 1b
                #Roque
                if isinstance(piece_selectionnee, Tour) and isinstance(
                        self.piece_a_deplacer, Roi):
                    if self.partie.roque_est_valide(
                            self.position_piece_a_deplacer, position):
                        self.partie.roquer(self.position_piece_a_deplacer,
                                           position)

                        #Derniers déplacements et pièces mangées
                        self.liste1.insert(END, self.partie.dernierDeplacement)
                        self.liste2.delete(0, END)
                        for i in self.partie.gapBlanc:
                            self.liste2.insert(END, i)
                        self.liste3.delete(0, END)
                        for i in self.partie.gapNoir:
                            self.liste3.insert(END, i)
                        self.piece_a_deplacer = None
                        self.position_piece_a_deplacer = None

                        # Dessin de l'echiquier
                        self.canvas_echiquier.delete('case')
                        self.canvas_echiquier.delete('piece')
                        self.canvas_echiquier.delete('select')
                        self.canvas_echiquier.dessiner_cases()
                        self.roi_en_rouge()
                        self.canvas_echiquier.dessiner_pieces()
                        self.messages['text'] = ''
                    else:
                        self.piece_a_deplacer = None
                        self.position_piece_a_deplacer = None

                        # Dessin de l'echiquier
                        self.canvas_echiquier.delete('case')
                        self.canvas_echiquier.delete('piece')
                        self.canvas_echiquier.delete('select')
                        self.canvas_echiquier.dessiner_cases()
                        self.roi_en_rouge()
                        self.canvas_echiquier.dessiner_pieces()

                        self.messages['text'] = f"Le déplacement est invalide."
                        self.messages['foreground'] = 'red'

                #Si on tente de sélectionner une 2e fois la même case, on la désélectionne
                else:
                    self.piece_a_deplacer = piece_selectionnee
                    self.position_piece_a_deplacer = position

                    # Dessin de l'echiquier
                    self.canvas_echiquier.delete('case')
                    self.canvas_echiquier.delete('piece')
                    self.canvas_echiquier.delete('select')
                    self.canvas_echiquier.dessiner_cases()
                    self.creer_carre_selection()
                    self.roi_en_rouge()
                    self.canvas_echiquier.dessiner_pieces()

                    self.messages[
                        'text'] = f'Pièce sélectionnée : {self.piece_a_deplacer} à la position {position}.'
                    self.messages['foreground'] = 'black'
        #Si la case sélectionnée contient une pièce appartenant à l'adversaire
        elif piece_selectionnee.couleur != self.partie.joueur_actif:
            #Si aucune pièce n'est stockée dans self.piece_a_deplacer
            if self.piece_a_deplacer is None:
                # Dessin de l'echiquier
                self.canvas_echiquier.delete('case')
                self.canvas_echiquier.delete('piece')
                self.canvas_echiquier.dessiner_cases()
                self.roi_en_rouge()
                self.canvas_echiquier.dessiner_pieces()

                self.messages[
                    'text'] = f"La pièce à la position {position} n'est pas à vous!"
                self.messages['foreground'] = 'red'
            #Si une pièce est stockée dans self.piece_a_deplacer
            else:
                try:  #On tente de la déplacer jusqu'à la case sélectionnée
                    self.partie.deplacer(self.position_piece_a_deplacer,
                                         position)

                    # Derniers déplacements et pièces mangées
                    self.liste1.insert(END, self.partie.dernierDeplacement)
                    self.liste2.delete(0, END)
                    for i in self.partie.gapBlanc:
                        self.liste2.insert(END, i)
                    self.liste3.delete(0, END)
                    for i in self.partie.gapNoir:
                        self.liste3.insert(END, i)

                    self.piece_a_deplacer = None
                    self.position_piece_a_deplacer = None

                    # Dessin de l'echiquier
                    self.canvas_echiquier.delete('case')
                    self.canvas_echiquier.delete('piece')
                    self.canvas_echiquier.delete('select')
                    self.canvas_echiquier.dessiner_cases()
                    self.roi_en_rouge()
                    self.canvas_echiquier.dessiner_pieces()

                    self.messages['text'] = ''

                    #Partie terminée?
                    if self.partie.partie_terminee():
                        self.messages['foreground'] = 'green'
                        self.messages[
                            'text'] = 'Partie terminée, les ' + self.partie.determiner_gagnant().upper() \
                                      + ' ont gagné.\nOn recommence?!'
                except:  # Si le déplacement est invalide
                    self.piece_a_deplacer = None
                    self.position_piece_a_deplacer = None

                    # Dessin de l'echiquier
                    self.canvas_echiquier.delete('case')
                    self.canvas_echiquier.delete('piece')
                    self.canvas_echiquier.delete('select')
                    self.canvas_echiquier.dessiner_cases()
                    self.roi_en_rouge()
                    self.canvas_echiquier.dessiner_pieces()

                    self.messages['text'] = f"Le déplacement est invalide."
                    self.messages['foreground'] = 'red'

        self.messages1[
            'text'] = "Au tour du joueur: " + self.partie.joueur_actif.upper()
Ejemplo n.º 16
0
class Fenetre(Tk):
    def __init__(self):
        super().__init__()

        # Nom de la fenêtre.
        self.title("Chess")

        # quelques attributs à utiliser plustard
        self.position_source = None
        self.option_indice = 0
        self.protocol(
            'WM_DELETE_WINDOW', self.demander
        )  # cette instruction fait appel a une fonction si le joueur
        # click sur le bouton fermé de la fenetre tk

        # Création du canvas échiquier.
        self.canvas_echiquier = CanvasEchiquier(self, 50)
        self.canvas_echiquier.grid(padx=0,
                                   pady=0,
                                   sticky=NSEW,
                                   row=0,
                                   column=0,
                                   rowspan=2)

        # Redimensionnement automatique du canvas.
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        # Label pour les infos sur la partie, voir les paramètres 'text=...' pour avoir plus de détails sur chaque sous-fram
        self.frame_infos = LabelFrame(self,
                                      borderwidth=3,
                                      relief=RIDGE,
                                      text="Information sur la partie")
        self.frame_infos.grid(row=0, column=1, sticky=N)

        self.mon_label_info = Label(self.frame_infos,
                                    font=("DejaVu Sans", 16),
                                    text="C'est au tour du joueur blanc")
        self.mon_label_info.grid(columnspan=4)

        self.prises_blanc = Label(self.frame_infos,
                                  borderwidth=2,
                                  relief=RIDGE,
                                  font=("DejaVu Sans", 8),
                                  text="Prises du\njoueur blanc")
        self.prises_blanc.grid(row=1, column=0, sticky=N + W)

        self.prises_noir = Label(self.frame_infos,
                                 borderwidth=2,
                                 relief=RIDGE,
                                 font=("DejaVu Sans", 8),
                                 text="Prises du\njoueur noir")
        self.prises_noir.grid(row=1, column=1, sticky=N + E)

        self.depla_blanc = Label(self.frame_infos,
                                 borderwidth=2,
                                 relief=RIDGE,
                                 font=("DejaVu Sans", 8),
                                 text="Liste des déplacements\njoueur blanc")
        self.depla_blanc.grid(row=1, column=2, sticky=N + W)

        self.depla_noir = Label(self.frame_infos,
                                borderwidth=2,
                                relief=RIDGE,
                                font=("DejaVu Sans", 8),
                                text="Liste des déplacements\njoueur noir")
        self.depla_noir.grid(row=1, column=3, sticky=N + E)

        # Label pour le menu (contenant des bouton) de la partie, voir les paramètres 'text=...' pour avoir plus de
        # détails sur cache bouton: chaque bouton envoi vers une fonction voir les paramètres 'command=...'
        self.frame_menu = LabelFrame(self,
                                     borderwidth=3,
                                     relief=RIDGE,
                                     text="Menu de la partie")
        self.frame_menu.grid(row=1, column=1, sticky=NSEW, padx=10, pady=0)

        self.nouvelle = Button(self.frame_menu,
                               text="Nouvelle partie",
                               command=self.nouvelle_partie)
        self.nouvelle.grid(sticky=NSEW, row=0, column=0)

        self.sauv = Button(self.frame_menu,
                           text="Sauvegarder la partie",
                           command=self.save)
        self.sauv.grid(sticky=NSEW, row=1, column=0)

        self.load = Button(self.frame_menu,
                           text="Charger une partie",
                           command=self.load)
        self.load.grid(sticky=NSEW, row=2, column=0)

        self.infos = Button(self.frame_menu,
                            text="Informations sur le jeu",
                            command=self.infos_et_règles)
        self.infos.grid(sticky=NSEW, row=3, column=0)

        self.annul = Button(self.frame_menu,
                            text="Annuler le dernier déplacement",
                            command=self.annuler)
        self.annul.grid(sticky=NSEW, row=4, column=0)

        self.o = Button(self.frame_menu,
                        text="Passez la main à l'ordi",
                        command=self.ordi)
        self.o.grid(sticky=N + E + W, row=0, column=1)

        self.o_h_a = Checkbutton(
            self.frame_menu,
            text="Activer cette case puis faites un\nclick droit sur la piece "
            "voulu\npour voir les possibilitées\nqui s'offrent à "
            "vous",
            command=self.activer_indice)
        self.o_h_a.grid(sticky=NSEW, row=1, column=1, rowspan=3)

        self.partie = Partie(self.canvas_echiquier.echiquier)

        # Ajout d'une étiquette d'information.
        self.messages = Label(self, font=("DejaVu Sans", 16))
        self.messages.grid(row=2, columnspan=2)

        # On lie un clic sur le CanvasEchiquier à une méthode.
        self.canvas_echiquier.bind('<Button-3>', self.option_hint)
        self.canvas_echiquier.bind('<Button-1>', self.selectionner_source)
        self.canvas_echiquier.bind('<ButtonRelease-1>',
                                   self.selectionner_cible)
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# fonctions liées
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    def selectionner_source(self, event):
        # On trouve le numéro de ligne/colonne en divisant les positions en y/x par le nombre de pixels par case.
        ligne = event.y // self.canvas_echiquier.n_pixels_par_case
        colonne = event.x // self.canvas_echiquier.n_pixels_par_case

        # On récupère l'information sur la pièce à l'endroit choisi, lors le de la pression du bouton gauche
        try:
            position = "{}{}".format(
                self.canvas_echiquier.lettres_colonnes[colonne],
                int(self.canvas_echiquier.chiffres_rangees[
                    self.canvas_echiquier.n_lignes - ligne - 1]))

            # on essaie de récupérer la piece et on la place dans un attribut
            self.position_source = position
            self.piece_source = self.canvas_echiquier.echiquier.dictionnaire_pieces[
                self.position_source]

            self.messages['foreground'] = 'black'
            self.messages[
                'text'] = 'Pièce sélectionnée : {} à la position {}.'.format(
                    self.piece_source, self.position_source)

        except KeyError:  # sauf si la positions est vide
            self.messages['foreground'] = 'red'
            self.messages[
                'text'] = "La position source que vous avez choisi est invalide veuillez choisir de nouveau"
        except IndexError:
            self.messages['foreground'] = 'red'
            self.messages['text'] = ""
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    def selectionner_cible(self, event):
        # On trouve le numéro de ligne/colonne en divisant les positions en y/x par le nombre de pixels par case.
        ligne = event.y // self.canvas_echiquier.n_pixels_par_case
        colonne = event.x // self.canvas_echiquier.n_pixels_par_case

        # On récupère l'information sur la pièce à l'endroit choisi lors du relachement du bouton gauche
        try:
            position = "{}{}".format(
                self.canvas_echiquier.lettres_colonnes[colonne],
                int(self.canvas_echiquier.chiffres_rangees[
                    self.canvas_echiquier.n_lignes - ligne - 1]))
            self.position_cible = position
            self.partie.jouer(
                self.position_source, self.position_cible
            )  # on envoie à la fonction qui fait le déplacement dans le dict de l'échiquier
            self.affichage_info()
            if self.partie.partie_terminee(
            ):  # on fait un envois à la fonction qui verifie si la partie est terminé
                self.partie.joueur_suivant(
                )  # on retourne vers le joueur gagnant et on affiche une messagebox
                reponse = messagebox.askquestion(
                    'La partie_terminée',
                    'La partie est terminée, félicitation au joueur {}.\nVoulez-vous '
                    'jouer une nouvelle partie ou quitter?\nCliquez sur "Oui" pour '
                    'rejouer ou sur non pour quitter.'.format(
                        self.partie.joueur_actif))
                if reponse == "yes":  # le message box nous demande si on veut vraiment quitter ou
                    self.nouvelle_partie()  # jouer une nouvelle partie
                else:
                    self.destroy()
        except ChoisirDaborsPositionSource as e:  # il ya 5 cas ou le deplacement ne peut pas étre effectué
            self.messages[
                'foreground'] = 'red'  # ces exceptions se situent dans d'autre modules
            self.messages[
                'text'] = e  # le nom des class des exceptions est assez expressif...
        except PositionSourceInvalide as e:
            self.messages['foreground'] = 'red'
            self.messages['text'] = e
        except DeuxPositionsDeMemeCouleur as e:
            self.messages['foreground'] = 'red'
            self.messages['text'] = e
        except DeplacementNonValide as e:
            self.messages['foreground'] = 'red'
            self.messages['text'] = e
        except CestPasLeBonJoueur as e:
            self.messages['foreground'] = 'red'
            self.messages['text'] = e
        except IndexError:
            self.messages['foreground'] = 'red'
            self.messages['text'] = ""
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    # si le joueur click sur le bouton nouvelle partie

    def nouvelle_partie(self):
        reponse = messagebox.askquestion(
            "C'est une bonne partie...courage",
            "Si vous quittez, vous risquez de perdre la "
            "partie courante?\nCliquez sur 'Oui' pour sau"
            "vegarder la partie ou sur 'Non' pour "
            "quitter.".format(self.partie.joueur_actif))
        if reponse == "yes":  # on affiche une messagebox qui pose une question au joueur
            self.save(
            )  # s'il reponds qu'il veut sauver la partie on fait un appel de fonction (voir en bas)
        else:  # sinon on réinitialise l'echiquier, réaffiche le canvas
            self.canvas_echiquier.echiquier.initialiser_echiquier_depart()
            self.canvas_echiquier.delete('piece')
            self.canvas_echiquier.dessiner_pieces()
            self.partie.joueur_actif = 'blanc'
            self.messages['foreground'] = 'black'
            self.messages['text'] = "c'est parti"
            self.mon_label_info['text'] = "C'est au tour du joueur blanc"
            self.prises_blanc['text'] = "Prises du\njoueur blanc"
            self.prises_noir['text'] = "Prises du\njoueur noir"
            self.depla_blanc['text'] = "Liste des déplacements\njoueur blanc"
            self.depla_noir['text'] = "Liste des déplacements\njoueur noir"
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# si le joueur click sur le bouton sauvegarder

    def save(
        self
    ):  # on ouvre une fenetre de dialogue pour le (path) de sauvegarde, (seulement .txt et prédefini),
        # et aussi un demande un nom de fichier
        destination = filedialog.asksaveasfilename(
            title='Choisissez un répertoire où sauvegarder votre '
            'partie',
            defaultextension='.txt',
            filetypes=[('text seulement', '.txt')])
        if destination:
            sauvegarde = open(destination, "w")
            for e in self.canvas_echiquier.echiquier.dictionnaire_pieces:
                sauvegarde.write(e)  # on y écrit chaque position pleine.
                piece = self.canvas_echiquier.echiquier.dictionnaire_pieces[e]
                caracteres_pieces_w = {
                    Pion('blanc'): 'PB',
                    Pion('noir'): 'PN',
                    Tour('blanc'): 'TB',
                    Tour('noir'): 'TN',
                    Cavalier('blanc'): 'CB',
                    Cavalier('noir'): 'CN',
                    Fou('blanc'): 'FB',
                    Fou('noir'): 'FN',
                    Roi('blanc'): 'RB',
                    Roi('noir'): 'RN',
                    Dame('blanc'): 'DB',
                    Dame('noir'): 'DN'
                }
                for p in caracteres_pieces_w:  # pour chque position on compare le type
                    if type(p) == type(
                            piece
                    ) and p.couleur == piece.couleur:  # de piece qu'elle contient avec le dict
                        sauvegarde.write(
                            caracteres_pieces_w[p]
                        )  # defini au dessus puis on ecrit le caract
                sauvegarde.write('\n')  # correspondant, puis on saute la ligne
            sauvegarde.write(self.partie.joueur_actif
                             )  # apres avoir parcouru toutes les piece
            sauvegarde.close()  # on ecrit le nom du joueur actif
            self.messages['foreground'] = 'black'
            self.messages[
                'text'] = 'La partie à été enregistré avec success'  # enfin on affiche un message que tout c'est bien passé

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# si le joueur click sur le bouton charger une nouvelle partie

    def load(self):
        reponse = messagebox.askquestion(
            "C'est une bonne partie...courage",
            "Si vous chargez une nouvelle partie, vous "
            "risquez de perdre la partie courante?\nCliquez sur "
            "'Oui' pour sauvegarder la partie courante ou sur 'Non' pour "
            "continuer.".format(self.partie.joueur_actif))
        if reponse == "yes":  # on affiche une fenetre pour demander si vraiment on veut quitter la partie en cours
            self.save()
        fichier_source = filedialog.askopenfilename(
            title='Choisissez le fichier où est sauvegardé vôtre '
            'partie',
            defaultextension='.txt',
            filetypes=[('text seulement', '.txt')])
        if fichier_source:
            load = open(fichier_source,
                        'r')  # le même fonctionnement que pour sel.save()
            dicos_chaine = load.readlines()
            caracteres_pieces_r = {
                'PB': Pion('blanc'),
                'PN': Pion('noir'),
                'TB': Tour('blanc'),
                'TN': Tour('noir'),
                'CB': Cavalier('blanc'),
                'CN': Cavalier('noir'),
                'FB': Fou('blanc'),
                'FN': Fou('noir'),
                'RB': Roi('blanc'),
                'RN': Roi('noir'),
                'DB': Dame('blanc'),
                'DN': Dame('noir')
            }
            pos = ''
            piece = None
            piece_class = ''
            self.canvas_echiquier.echiquier.dictionnaire_pieces = {}
            for l in range(len(dicos_chaine) - 1):
                pos = dicos_chaine[l][0:2]
                piece = dicos_chaine[l][2:4]
                for p in caracteres_pieces_r:
                    if piece == p:
                        piece_class = caracteres_pieces_r[p]
                self.canvas_echiquier.echiquier.dictionnaire_pieces[
                    pos] = piece_class
            self.partie.joueur_actif = dicos_chaine[-1]
            load.close()
            self.canvas_echiquier.delete('piece')
            self.canvas_echiquier.dessiner_pieces()
            self.messages['foreground'] = 'black'
            self.messages['text'] = 'La partie à été chargé avec succès'
            self.messages['text'] = "c'est parti"
            self.mon_label_info['text'] = "C'est au tour du joueur {}".format(
                self.partie.joueur_actif)
            self.mon_label_info['text'] = "C'est au tour du joueur blanc"
            self.prises_blanc['text'] = "Prises du\njoueur blanc"
            self.prises_noir['text'] = "Prises du\njoueur noir"
            self.depla_blanc['text'] = "Liste des déplacements\njoueur blanc"
            self.depla_noir['text'] = "Liste des déplacements\njoueur noir"
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# annuler le dernier déplacement et seulement le dérnier

    def annuler(self):
        # ce premier bloque s'assure qu'il n'y a pas eu d'appel de cette fonction juste avant, on ne peut annuler qu'un seul déplaclement à la fois
        # et ceci en regardant si la derniere position source est bien vide.
        if self.canvas_echiquier.echiquier.poss_annuler not in self.canvas_echiquier.echiquier.dictionnaire_pieces:
            self.canvas_echiquier.echiquier.dictionnaire_pieces[
                self.canvas_echiquier.echiquier.
                poss_annuler] = self.canvas_echiquier.echiquier.piece_s_dep
            # après cela nous avons deux cas soit on recupère la dernier pièce mangée (si c'est le cas) que nous avons
            # stocké dans un attribut de echiquier.py
            if self.canvas_echiquier.echiquier.piece_cible_mangé:
                self.canvas_echiquier.echiquier.dictionnaire_pieces[
                    self.canvas_echiquier.echiquier.
                    posc_annuler] = self.canvas_echiquier.echiquier.piece_cible_mangé
            else:  # sinon on remet la piece à sa place
                del self.canvas_echiquier.echiquier.dictionnaire_pieces[
                    self.canvas_echiquier.echiquier.posc_annuler]
        else:
            self.messages['text'] = 'Plus aucun déplacement à annuler'
        # puis on réaffiche le tout avec un message que tout s'est bien passé
        self.partie.joueur_actif = self.canvas_echiquier.echiquier.piece_s_dep.couleur
        self.canvas_echiquier.delete('piece')
        self.canvas_echiquier.dessiner_pieces()
        self.messages['foreground'] = 'black'
        self.messages[
            'text'] = 'Le dernier déplacement a été annulé avec succès'
        if self.partie.joueur_actif == 'blanc':  # on affiche le déplacement dans la liste des infos
            self.depla_blanc['text'] = self.depla_blanc['text'] + '(annulé)'
        else:
            self.depla_noir['text'] = self.depla_noir['text'] + '(annulé)'

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# si le joueur active la case pour les indices l'attribut self.option_indice se change en true.
# et puis s'il clique sur la piece de son choix avec le bouton droit il fait un appel vers cette fonction

    def option_hint(self, event):
        try:
            if self.option_indice == True:
                self.canvas_echiquier.delete(
                    'piece'
                )  # ce bloque sert lors du changement de piece sélectionné
                self.canvas_echiquier.dessiner_pieces(
                )  # comme ça les indices de l'ancienne pièce sont effacé
                self.canvas_echiquier.dessiner_cases()
                l = ''
                ligne = event.y // self.canvas_echiquier.n_pixels_par_case  # on recupère la position de l'évènement
                colonne = event.x // self.canvas_echiquier.n_pixels_par_case
                position = "{}{}".format(
                    self.canvas_echiquier.lettres_colonnes[colonne],
                    int(self.canvas_echiquier.chiffres_rangees[
                        self.canvas_echiquier.n_lignes - ligne - 1]))
                liste = self.canvas_echiquier.echiquier.hint(
                    position
                )  # on recupère la liste des positions possible depuis une fonction dans un autre module
                if self.canvas_echiquier.echiquier.dictionnaire_pieces[
                        position].couleur == self.partie.joueur_actif:
                    for e in range(len(liste)):
                        lettr = ord(
                            liste[e][0]
                        ) - 97  # on recupère les positions équivalentes dans l'echiquier
                        chiff = abs(
                            int(liste[e][1]) - 1 -
                            7)  # pour chaque position de la liste precedente.
                        debut_ligne = chiff * self.canvas_echiquier.n_pixels_par_case
                        fin_ligne = debut_ligne + self.canvas_echiquier.n_pixels_par_case
                        debut_colonne = lettr * self.canvas_echiquier.n_pixels_par_case
                        fin_colonne = debut_colonne + self.canvas_echiquier.n_pixels_par_case
                        couleur = 'yellow'  # puis seulement pour chaque position de la liste on réaffiche la case
                        self.canvas_echiquier.create_rectangle(debut_colonne,
                                                               debut_ligne,
                                                               fin_colonne,
                                                               fin_ligne,
                                                               fill=couleur,
                                                               tags='case')

        except PositionSourceInvalide as e:  # exception le joueur choisi une position invalide
            self.messages['foreground'] = 'red'
            self.messages['text'] = e
        except IndexError:
            self.messages['foreground'] = 'red'
            self.messages['text'] = ""
        finally:
            self.canvas_echiquier.delete(
                'piece'
            )  #puis on raffiche les pieces sur le nouvelle echiquier
            self.canvas_echiquier.dessiner_pieces()
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# comme expliqué plus haut lorsque le joueur active la case pour les indices l'attribut self.option_indice se change
# en true.

    def activer_indice(self):
        if self.option_indice == 0:
            self.option_indice = 1
        else:
            self.option_indice = 0
            self.canvas_echiquier.dessiner_cases()
            self.canvas_echiquier.delete('piece')
            self.canvas_echiquier.dessiner_pieces()
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# lorsque le joueur blanc clique sur le bouton 'passer la main à l'ordi' ce code est appeller pour faire jouer une
# pièce par l'ordi (l'odri joue les pièces noirs)

    def ordi(self):
        try:

            if self.partie.joueur_actif == 'blanc':
                raise CestPasLeBonJoueur("C'est à vous de jouer maintenant")
            list_possit_noir = []
            for pos_piece_noir in self.canvas_echiquier.echiquier.dictionnaire_pieces:
                if self.canvas_echiquier.echiquier.dictionnaire_pieces[
                        pos_piece_noir].couleur == 'noir':
                    list_possit_noir.append(
                        pos_piece_noir
                    )  # on récupère les positions de toutes les pièces noirs
            self.position_source = ''
            self.position_cible = ''
            list_pos_s_posib = []
            list_indice = []
            for i in list_possit_noir:  # pour chaque pièces
                list_indice = self.canvas_echiquier.echiquier.hint(
                    i)  # donne moi la liste des possibilités de déplacement
                if list_indice:  # si cette pièce peut se déplacer
                    list_pos_s_posib.append(
                        i
                    )  # crée une liste des pièce noires qui peuvent se déplacer
            for j in list_pos_s_posib:  # maintenant pour chaque pièce noir qui peut se déplacer
                list_indice = []
                list_indice = self.canvas_echiquier.echiquier.hint(
                    j)  # récupère la liste des possibilités de déplacemen
                for k in list_indice:  # si dans la liste des possibilités de déplacemen
                    if k in self.canvas_echiquier.echiquier.dictionnaire_pieces and self.canvas_echiquier.echiquier.dictionnaire_pieces[
                            k].couleur != 'noir':
                        self.position_cible = k  # tu trouve une piece dans l'échiquier et qui est blanche
                        self.position_source = j  # réfléchi pas! mange la!
                        self.piece_source = self.canvas_echiquier.echiquier.dictionnaire_pieces[
                            self.position_source]
                        break

            if not self.position_source and not self.position_cible:  # si après tout ça tu trouves rien
                self.position_source = random.choice(
                    list_pos_s_posib)  # pioche une position de pièce noir
                self.piece_source = self.canvas_echiquier.echiquier.dictionnaire_pieces[
                    self.position_source]
                list_indice = []
                list_indice = self.canvas_echiquier.echiquier.hint(
                    self.position_source
                )  # récupère la liste des possibilités de déplacemen
                self.position_cible = random.choice(
                    list_indice)  # et pioche une position cible
            self.partie.jouer(self.position_source,
                              self.position_cible)  # enfin le déplacement
            self.affichage_info()

            if self.partie.partie_terminee(
            ):  # on fait un envois à la fonction qui verifie si la partie est terminé
                self.partie.joueur_suivant(
                )  # on retourne vers le joueur gagnant et on affiche une messagebox
                reponse = messagebox.askquestion(
                    'La partie_terminée',
                    'La partie est terminée, félicitation au joueur {}.\nVoulez-vous '
                    'jouer une nouvelle partie ou quitter?\nCliquez sur "Oui" pour '
                    'rejouer ou sur non pour quitter.'.format(
                        self.partie.joueur_actif))
                if reponse == "yes":  # le message box nous demande si on veut vraiment quitter ou
                    self.nouvelle_partie()  # jouer une nouvelle partie
                    return
                else:
                    self.destroy()
                    return

        except CestPasLeBonJoueur as e:  # exception le joueur na pas encore jouer
            self.messages['foreground'] = 'red'
            self.messages['text'] = e
        self.messages[
            'text'] = "Humain! c'est à ton tour"  # on rassur le jouer (et surtout moi!) que tout s'est bien passé
        self.mon_label_info['text'] = "C'est au tour du joueur blanc"

        # question philosophique qu'es ce que l'intelligence???
#######################################################################################################################
# si le joueur click sur le bouton fermé tk il affiche un message pour demander s'il veut vraiment quitter ou sauvé

    def demander(self):
        reponse = messagebox.askquestion(
            "C'est une bonne partie...courage",
            "Si vous quittez, vous risquez de perdre la "
            "partie courante?\nCliquez sur 'Oui' pour "
            "sauvegarder la partie ou sur 'Non' pour "
            "quitter.".format(self.partie.joueur_actif))
        if reponse == "yes":
            self.save()
        else:
            self.destroy()
#######################################################################################################################

    def affichage_info(self):
        if self.canvas_echiquier.echiquier.piece_cible_mangé:  # si une piece à été manger
            c = self.canvas_echiquier.echiquier.piece_cible_mangé.couleur  # on fait l'affichage dans la liste
            if c == 'blanc':  # des prises
                self.prises_noir[
                    'text'] = self.prises_noir['text'] + '\n{}'.format(
                        self.canvas_echiquier.echiquier.piece_cible_mangé)
            elif c == 'noir':
                self.prises_blanc[
                    'text'] = self.prises_blanc['text'] + '\n{}'.format(
                        self.canvas_echiquier.echiquier.piece_cible_mangé)

        if self.partie.joueur_actif == 'blanc':  # on affiche le déplacement dans la liste des infos
            self.depla_noir[
                'text'] = self.depla_noir['text'] + '\n->{} de {} à {}'.format(
                    self.piece_source, self.position_source,
                    self.position_cible)
        else:
            self.depla_blanc['text'] = self.depla_blanc[
                'text'] + '\n->{} de {} à {}'.format(self.piece_source,
                                                     self.position_source,
                                                     self.position_cible)
        self.canvas_echiquier.dessiner_cases()
        self.canvas_echiquier.delete('piece')
        self.canvas_echiquier.dessiner_pieces()
        self.mon_label_info['text'] = "C'est au tour du joueur {}".format(
            self.partie.joueur_actif)
        self.messages['foreground'] = 'black'
        self.messages['text'] = 'Le déplacement a été effectué avec succès'
#######################################################################################################################
# cette fonction ouvre le fichier ReadME.txt qui contient les règles et consignes d'utilisation, ce fichier se
# trouve dans le dossier actuel ou se trouve ce module

    def infos_et_règles(self):
        fenetre_infos = Toplevel()
        fenetre_infos.title('Informations sur le jeu')
        label_consignes = Label(fenetre_infos, borderwidth=2, relief=RIDGE, font=("DejaVu Sans", 10), text="Vous trouverez les règles du jeu d'échecs en bas. "
                                                                                                          "Mais d'alors je vous explique les fonctionnalités du programme.\n"
                                                                                                          "- La partie commence avec le joueur blanc (toujours)\n"
                                                                                                          "####################################################################################################################\n"
                                                                                                          "Label Info. (cette section contient certaines informations sur la partie)\n"
                                                                                                          "####################################################################################################################\n"
                                                                                                          "- Un texte dans le labelframe indique c'est le tour de quel joueur, selon l'alternance des tours.\n"
                                                                                                          "- Pour déplacer une pièce maintenez là avec le bouton gauche de la souris et déposez là dans la position de votre"
                                                                                                          " choix, le déplacement sera effectué ou non, selon la validité de celui-ci.\n"
                                                                                                          "- Tous les déplacements sont affichés dans les listes à gauche de l'échiquier 'Liste des déplacements joueur blanc' et "
                                                                                                          "'Liste des déplacements joueur noir' selon le joueur.\n"
                                                                                                          "- Si le déplacement génère une prise, la pièce mangée est affichée dans les listes, encore une fois, à gauche de l'échiquier "
                                                                                                          "'Prises du joueur blanc' et 'Prises du joueur noir' selon le joueur.\n"
                                                                                                          "####################################################################################################################\n"
                                                                                                          "Label menu. (cette section contient les principales fonctionnalités du jeu)\n"
                                                                                                          "####################################################################################################################\n"
                                                                                                          "- Un bouton 'Nouvelle partie', pour démarrer une nouvelle partie, le programme va vous proposer de sauvegarder la partie " \
                                                                                                        "courante.\n" \
                                                                                                        "- Un bouton 'Sauvegarder la partie' qui sauvegarde la partie dans un fichier .txt (vous devrez choisir l'emplacement " \
                                                                                                        "et le nom du fichier).\n" \
                                                                                                        "- Un bouton 'Charger une partie' qui charge la partie depuis un fichier .txt (vous devrez choisir l'emplacement  " \
                                                                                                        "du fichier).\n" \
                                                                                                        "- Un bouton 'Informations sur le jeu' qui ouvre le présent document.\n" \
                                                                                                        "- Un bouton 'Annuler le dernier déplacement' qui annule le dernier déplacement, et seulement le dernier déplacement.\n" \
                                                                                                        "- Une case à cocher si vous voulez que le programme vous montre les déplacements possibles pour une certaine pièce\ " \
                                                                                                        "(il vafalloir choisir la pièce que vous voulez avec le bouton droit de la souris).")
        label_consignes.grid(row=0, column=0, sticky=N + E + W)
        label_règles = Label(
            fenetre_infos,
            borderwidth=2,
            relief=RIDGE,
            font=("DejaVu Sans", 10),
            text="Quelques règles de jeu d'échecs..."
            "\n####################################################################################################################"
            "\nJe vois dans les mots-clés que certains aimeraient savoir comment on va à dame, ou comment on"
            "récupère une pièce, ou si on peut manger le roi... Alors hop! \nPetit cours d'échecs, rapide, sur ce qui"
            "semble vous préoccuper."
            "\nUn échiquier comporte 64 cases sur lesquelles il y a, au début de la partie, 32 pièces : 8 pions + 8"
            "pièces légères/lourdes et roi \n(2 tours, 2 cavaliers, 2 fous, la dame, le roi) aussi bien chez les"
            "noirs que chez les blancs."
            "\nLa dame se place 'sur sa couleur' : une dame blanche se place sur la case blanche centrale de sa rangée."
            "\nUne dame noire sur la case noire, en face de la dame blanche de toute façon. Le roi se place sur la case voisine."
            "\nDe gauche à droite, chez les blancs (qui se placent sur les colonnes 1 et 2, voir chiffres et lettres sur les côtés"
            "\nde la plupart des échiquiers), on a : tour cavalier fou dame roi fou cavalier tour. Et un pion devant chaque pièce."
            "\nLa case la plus proche d'un joueur, tout à droite, doit être une case blanche, sinon c'est que l'échiquier est mal fichu."
            "\nOn ne mange pas le roi. Sauf en blitz chez les disons euh... bourrins, et en parties amicales uniquement. Mais dans"
            "\nun tournoi de blitz, prendre le roi sera considéré comme un coup illégal et occasionnera la perte de la partie pour"
            "\ncelui qui a mangé le roi. Alors qu'il suffit de dire à l'adversaire qu'il a perdu car son roi était en échec et"
            "\nqu'il n'a pas paré l'échec."
            "\nPour récupérer une pièce, il faut amener un pion à promotion, c'est-à-dire le faire avancer jusqu'à ce qu'il soit"
            "\narrivé sur la rangée tout au bout de l'échiquier et donc qu'il ne puisse plus avancer. Au moment où on pose le pion"
            "\nsur la dernière case, on peut le remplacer par n'importe quelle pièce de sa couleur, sauf le roi. Si on choisit"
            "\nune dame mais qu'on a toujours la sienne sur l'échiquier, on peut prendre une tour retournée ou une pièce, ou ce"
            "\nqu'on veut pour représenter la deuxième dame. Mais attention!!! En tournoi, une tour renversée reste une tour,"
            "\nil faut donc arrêter la pendule (cet appareil qui mesure le temps de réflexion des joueurs et est, selon les"
            "\nparties, amie ou ennemie...), appeler l'arbitre et lui demander une dame. On peut aussi choisir une autre pièce,"
            "\nmais la dame étant la pièce la plus polyvalente, c'est généralement elle qui est choisie. [mais bien évidemment,"
            "\nsi en choisissant une dame on met l'autre pat il vaut mieux choisir une autre pièce]."
            "\n####################################################################################################################"
            "\nSource:"
            "meosine, Quelques règles de jeu d'échecs...<http://meosine.canalblog.com/archives/2008/02/18/8003563.html>, 18 février 2008"
            "\n######################################################################################################################"
        )
        label_règles.grid(row=1, column=0, sticky=N + E + W)
Ejemplo n.º 17
0
# -*- coding: utf-8 -*-
"""Module principal du package pychecs. C'est ce module que nous allons exécuter pour démarrer votre jeu.

"""
from pychecs2.echecs.partie import Partie

if __name__ == '__main__':
    # Création d'une instance de Partie.
    p = Partie()

    # Exemple de modification du dictionnaire de pièces, afin de débuter une partie simplifiée pour faire
    # vos tests. Vous devez importer les pièces appropriés pour que ce code fonctionne.
    # p.echiquier.dictionnaire_pieces = {
    #     'b1': Roi('noir'),
    #     'c4': Fou('noir'),
    #     'b8': Tour('blanc'),
    #     'g7': Roi('blanc')
    # }

    # Démarrage de cette partie.
    p.jouer()
Ejemplo n.º 18
0
    def __init__(self):
        super().__init__()

        # Nom de la fenêtre.
        self.title("Échiquier")

        # Creation d'une nouvelle partie
        self.partie = Partie()
        self.sauvegarder("Revenir")

        # La position sélectionnée.
        self.position_selectionnee = None

        # Truc pour le redimensionnement automatique des éléments de la fenêtre.
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        # Création du canvas échiquier.
        self.canvas_echiquier = CanvasEchiquier(self, 60, self.partie)
        self.canvas_echiquier.grid(sticky=NSEW)

        # Frame bouton Sauvegare/NG/coup précédent
        self.frame_sauvegarde = Frame(self)
        self.frame_sauvegarde.grid(row=1)

        # label invisible
        self.label_invisible1 = Label(self.frame_sauvegarde)
        self.label_invisible1.grid(row=0)

        # Creation d'un bouton nouvelle partie
        self.boutton_nouvelle_partie = Button(self.frame_sauvegarde,
                                              text='Nouvelle Partie',
                                              command=self.nouvelle_partie)
        self.boutton_nouvelle_partie.grid()

        # label invisible
        self.label_invisible2 = Label(self.frame_sauvegarde)
        self.label_invisible2.grid(row=1, column=2)

        # Creation d'un bouton précédant
        self.boutton_revenir = Button(self.frame_sauvegarde,
                                      text='Coup précédant',
                                      command=self.revenir)
        self.boutton_revenir.grid(row=1, column=3)

        # label invisible
        self.label_invisible2 = Label(self.frame_sauvegarde)
        self.label_invisible2.grid(row=1, column=4)

        # Sauvegarder
        self.boutton_sauvegarde = Button(self.frame_sauvegarde,
                                         text='Sauvegarder',
                                         command=self.faire_sauvegarder)
        self.boutton_sauvegarde.grid(row=1, column=5)

        # label invisible
        self.label_invisible2 = Label(self.frame_sauvegarde)
        self.label_invisible2.grid(row=1, column=6)

        # Charger
        self.bouton_charger = Button(self.frame_sauvegarde,
                                     text='     Charger     ',
                                     command=self.faire_charger)
        self.bouton_charger.grid(row=1, column=7)

        # Frame joueur actif
        self.frame_info = LabelFrame(self, text="Joueur actif")
        self.frame_info.grid(row=0, column=1, sticky=NW)

        self.label_temporaire = Label(self.frame_info,
                                      text="C'est le tour au joueur " +
                                      self.partie.joueur_actif,
                                      background='snow')
        self.label_temporaire.grid(row=0, sticky=N, column=0)

        # label invisible
        self.label_invisible = Label(self.frame_info)
        self.label_invisible.grid(row=1, column=0, padx=100)

        # label theme
        self.label_theme = Label(self.frame_info, text="Thème:")
        self.label_theme.grid(row=2, sticky=W)

        # Changer de thème
        self.valeur = StringVar()
        self.boite_theme = ttk.Combobox(self.frame_info,
                                        textvariable=self.valeur,
                                        state="readonly")
        self.boite_theme["values"] = [
            "Classique", "Noel", "Saint-Valentin", "Doritos-MountainDew"
        ]
        self.boite_theme.current(0)
        self.boite_theme.grid(row=3)
        self.boite_theme.bind("<<ComboboxSelected>>", self.changer_theme)

        # label invisible
        self.label_invisible = Label(self.frame_info)
        self.label_invisible.grid(row=4, column=0)

        # label invisible
        self.label_invisible = Label(self.frame_info)
        self.label_invisible.grid(row=5, column=0)

        # label invisible
        self.label_invisible = Label(self.frame_info)
        self.label_invisible.grid(row=6, column=0)

        # label invisible
        self.label_invisible = Label(self.frame_info)
        self.label_invisible.grid(row=7, column=0)

        # label invisible
        self.label_invisible = Label(self.frame_info)
        self.label_invisible.grid(row=8, column=0)

        # bouton Reglement
        self.bouton_reglement = Button(self.frame_info,
                                       text='Règlements',
                                       command=self.montre_reglement)
        self.bouton_reglement.grid(row=9, column=0)

        # label invisible
        self.label_invisible = Label(self.frame_info)
        self.label_invisible.grid(row=10, column=0)

        # bouton Troll
        self.bouton_troll = Button(self.frame_info,
                                   text='Ne pas cliquer :)',
                                   background='red',
                                   command=self.troll)
        self.bouton_troll.grid(row=11, column=0)

        # label invisible
        self.label_invisible = Label(self.frame_info)
        self.label_invisible.grid(row=12, column=0, pady=58)

        # label note
        self.label_note = Label(self.frame_info,
                                text='*Note:',
                                background='yellow')
        self.label_note.grid(row=13, column=0, sticky=NW)
        self.label_clic1 = Label(self.frame_info,
                                 text='Clique gauche = Sélectionner pièce')
        self.label_clic1.grid(row=14, column=0, sticky=NW)
        self.label_clic2 = Label(self.frame_info,
                                 text='Clique droit = Déposer pièce')
        self.label_clic2.grid(row=15, column=0, sticky=NW)

        # Ajout d'une étiquette d'information.
        self.messages = Label(self)
        self.messages.grid()

        # On lie un clic sur le CanvasEchiquier à une méthode.
        self.canvas_echiquier.bind('<Button-1>', self.selectionner)
        self.canvas_echiquier.bind('<Button-3>', self.deposer)
Ejemplo n.º 19
0
class Fenetre(Tk):
    def __init__(self):
        super().__init__()

        # Nom de la fenêtre.
        self.title("Échiquier")

        # Creation d'une nouvelle partie
        self.partie = Partie()
        self.sauvegarder("Revenir")

        # La position sélectionnée.
        self.position_selectionnee = None

        # Truc pour le redimensionnement automatique des éléments de la fenêtre.
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        # Création du canvas échiquier.
        self.canvas_echiquier = CanvasEchiquier(self, 60, self.partie)
        self.canvas_echiquier.grid(sticky=NSEW)

        # Frame bouton Sauvegare/NG/coup précédent
        self.frame_sauvegarde = Frame(self)
        self.frame_sauvegarde.grid(row=1)

        # label invisible
        self.label_invisible1 = Label(self.frame_sauvegarde)
        self.label_invisible1.grid(row=0)

        # Creation d'un bouton nouvelle partie
        self.boutton_nouvelle_partie = Button(self.frame_sauvegarde,
                                              text='Nouvelle Partie',
                                              command=self.nouvelle_partie)
        self.boutton_nouvelle_partie.grid()

        # label invisible
        self.label_invisible2 = Label(self.frame_sauvegarde)
        self.label_invisible2.grid(row=1, column=2)

        # Creation d'un bouton précédant
        self.boutton_revenir = Button(self.frame_sauvegarde,
                                      text='Coup précédant',
                                      command=self.revenir)
        self.boutton_revenir.grid(row=1, column=3)

        # label invisible
        self.label_invisible2 = Label(self.frame_sauvegarde)
        self.label_invisible2.grid(row=1, column=4)

        # Sauvegarder
        self.boutton_sauvegarde = Button(self.frame_sauvegarde,
                                         text='Sauvegarder',
                                         command=self.faire_sauvegarder)
        self.boutton_sauvegarde.grid(row=1, column=5)

        # label invisible
        self.label_invisible2 = Label(self.frame_sauvegarde)
        self.label_invisible2.grid(row=1, column=6)

        # Charger
        self.bouton_charger = Button(self.frame_sauvegarde,
                                     text='     Charger     ',
                                     command=self.faire_charger)
        self.bouton_charger.grid(row=1, column=7)

        # Frame joueur actif
        self.frame_info = LabelFrame(self, text="Joueur actif")
        self.frame_info.grid(row=0, column=1, sticky=NW)

        self.label_temporaire = Label(self.frame_info,
                                      text="C'est le tour au joueur " +
                                      self.partie.joueur_actif,
                                      background='snow')
        self.label_temporaire.grid(row=0, sticky=N, column=0)

        # label invisible
        self.label_invisible = Label(self.frame_info)
        self.label_invisible.grid(row=1, column=0, padx=100)

        # label theme
        self.label_theme = Label(self.frame_info, text="Thème:")
        self.label_theme.grid(row=2, sticky=W)

        # Changer de thème
        self.valeur = StringVar()
        self.boite_theme = ttk.Combobox(self.frame_info,
                                        textvariable=self.valeur,
                                        state="readonly")
        self.boite_theme["values"] = [
            "Classique", "Noel", "Saint-Valentin", "Doritos-MountainDew"
        ]
        self.boite_theme.current(0)
        self.boite_theme.grid(row=3)
        self.boite_theme.bind("<<ComboboxSelected>>", self.changer_theme)

        # label invisible
        self.label_invisible = Label(self.frame_info)
        self.label_invisible.grid(row=4, column=0)

        # label invisible
        self.label_invisible = Label(self.frame_info)
        self.label_invisible.grid(row=5, column=0)

        # label invisible
        self.label_invisible = Label(self.frame_info)
        self.label_invisible.grid(row=6, column=0)

        # label invisible
        self.label_invisible = Label(self.frame_info)
        self.label_invisible.grid(row=7, column=0)

        # label invisible
        self.label_invisible = Label(self.frame_info)
        self.label_invisible.grid(row=8, column=0)

        # bouton Reglement
        self.bouton_reglement = Button(self.frame_info,
                                       text='Règlements',
                                       command=self.montre_reglement)
        self.bouton_reglement.grid(row=9, column=0)

        # label invisible
        self.label_invisible = Label(self.frame_info)
        self.label_invisible.grid(row=10, column=0)

        # bouton Troll
        self.bouton_troll = Button(self.frame_info,
                                   text='Ne pas cliquer :)',
                                   background='red',
                                   command=self.troll)
        self.bouton_troll.grid(row=11, column=0)

        # label invisible
        self.label_invisible = Label(self.frame_info)
        self.label_invisible.grid(row=12, column=0, pady=58)

        # label note
        self.label_note = Label(self.frame_info,
                                text='*Note:',
                                background='yellow')
        self.label_note.grid(row=13, column=0, sticky=NW)
        self.label_clic1 = Label(self.frame_info,
                                 text='Clique gauche = Sélectionner pièce')
        self.label_clic1.grid(row=14, column=0, sticky=NW)
        self.label_clic2 = Label(self.frame_info,
                                 text='Clique droit = Déposer pièce')
        self.label_clic2.grid(row=15, column=0, sticky=NW)

        # Ajout d'une étiquette d'information.
        self.messages = Label(self)
        self.messages.grid()

        # On lie un clic sur le CanvasEchiquier à une méthode.
        self.canvas_echiquier.bind('<Button-1>', self.selectionner)
        self.canvas_echiquier.bind('<Button-3>', self.deposer)

    def faire_sauvegarder(self):
        try:
            self.sauvegarder(
                filedialog.asksaveasfilename(initialdir=os.path.join(
                    os.path.realpath(os.path.curdir), 'Sauvegarde')))

        except FileNotFoundError:
            self.messages['foreground'] = 'red'
            self.messages['text'] = "La partie n'a pas été sauvegardée"
            self.canvas_echiquier.dessiner_cases()
            self.canvas_echiquier.dessiner_pieces()

    def faire_charger(self):
        try:
            self.charger(
                filedialog.askopenfilename(initialdir=os.path.join(
                    os.path.realpath(os.path.curdir), 'Sauvegarde')))
        except FileNotFoundError:
            self.messages['foreground'] = 'red'
            self.messages['text'] = "Aucune partie n'a été chargée"
            self.canvas_echiquier.dessiner_cases()
            self.canvas_echiquier.dessiner_pieces()

    def sauvegarder(self, nom_fichier):

        with open(nom_fichier, 'wb') as partie:
            a = self.partie.echiquier.dictionnaire_pieces
            b = self.partie.joueur_actif

            pickle.dump(a, partie)
            pickle.dump(b, partie)

        partie.close()

    def charger(self, nom_fichier):

        with open(nom_fichier, 'rb') as partie:
            a = pickle.load(partie)
            b = pickle.load(partie)
            self.partie.echiquier.dictionnaire_pieces = a
            self.partie.joueur_actif = b

        partie.close()

        self.messages['text'] = ''
        self.canvas_echiquier.dessiner_cases()
        self.canvas_echiquier.dessiner_pieces()
        self.label_temporaire[
            'text'] = "C'est le tour au joueur " + self.partie.joueur_actif

    class MauvaiseCouleur(Exception):
        pass

    class DeplacementInvalide(Exception):
        pass

    def selectionner(self, event):

        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'
        ]

        if self.partie.partie_terminee() == False:

            # On trouve le numéro de ligne/colonne en divisant les positions en y/x par le nombre de pixels par case.
            ligne = event.y // self.canvas_echiquier.n_pixels_par_case
            colonne = event.x // self.canvas_echiquier.n_pixels_par_case
            position_source = "{}{}".format(
                self.canvas_echiquier.partie.echiquier.
                lettres_colonnes[colonne],
                int(self.canvas_echiquier.partie.echiquier.chiffres_rangees[
                    self.canvas_echiquier.n_lignes - ligne - 1]))
            liste_lettre_a_chiffre = {
                'a': 0,
                'b': 1,
                'c': 2,
                'd': 3,
                'e': 4,
                'f': 5,
                'g': 6,
                'h': 7
            }
            couleur_joueur_actif = self.partie.joueur_actif
            couleur_piece_selectionnée = self.partie.echiquier.couleur_piece_a_position(
                position_source)

            try:

                self.canvas_echiquier.dessiner_cases()
                self.canvas_echiquier.dessiner_pieces()
                piece = self.canvas_echiquier.partie.echiquier.dictionnaire_pieces[
                    position_source]

                # On change la valeur de l'attribut position_selectionnee.
                self.position_selectionnee = position_source
                self.messages['foreground'] = 'black'
                self.messages[
                    'text'] = 'Pièce sélectionnée : {} à la position {}.'.format(
                        piece, self.position_selectionnee)
                self.canvas_echiquier.grid()

                if self.position_selectionnee is not None:
                    self.canvas_echiquier.create_rectangle(
                        liste_lettre_a_chiffre[position_source[0]] *
                        self.canvas_echiquier.n_pixels_par_case,
                        8 * self.canvas_echiquier.n_pixels_par_case -
                        int(position_source[1]) *
                        self.canvas_echiquier.n_pixels_par_case,
                        self.canvas_echiquier.n_pixels_par_case +
                        liste_lettre_a_chiffre[position_source[0]] *
                        self.canvas_echiquier.n_pixels_par_case,
                        8 * self.canvas_echiquier.n_pixels_par_case -
                        int(position_source[1]) *
                        self.canvas_echiquier.n_pixels_par_case +
                        self.canvas_echiquier.n_pixels_par_case,
                        fill='yellow',
                        tags='case')

                    for i in toutes_les_position:
                        if self.partie.echiquier.deplacement_est_valide(
                                position_source, i):
                            self.canvas_echiquier.create_rectangle(
                                liste_lettre_a_chiffre[i[0]] *
                                self.canvas_echiquier.n_pixels_par_case,
                                8 * self.canvas_echiquier.n_pixels_par_case -
                                int(i[1]) *
                                self.canvas_echiquier.n_pixels_par_case,
                                self.canvas_echiquier.n_pixels_par_case +
                                liste_lettre_a_chiffre[i[0]] *
                                self.canvas_echiquier.n_pixels_par_case,
                                8 * self.canvas_echiquier.n_pixels_par_case -
                                int(i[1]) *
                                self.canvas_echiquier.n_pixels_par_case +
                                self.canvas_echiquier.n_pixels_par_case,
                                fill='cyan',
                                tags='case')
                            if self.partie.echiquier.recuperer_piece_a_position(
                                    i) is not None:
                                self.canvas_echiquier.create_rectangle(
                                    liste_lettre_a_chiffre[i[0]] *
                                    self.canvas_echiquier.n_pixels_par_case,
                                    8 * self.canvas_echiquier.n_pixels_par_case
                                    - int(i[1]) *
                                    self.canvas_echiquier.n_pixels_par_case,
                                    self.canvas_echiquier.n_pixels_par_case +
                                    liste_lettre_a_chiffre[i[0]] *
                                    self.canvas_echiquier.n_pixels_par_case,
                                    8 * self.canvas_echiquier.n_pixels_par_case
                                    - int(i[1]) *
                                    self.canvas_echiquier.n_pixels_par_case +
                                    self.canvas_echiquier.n_pixels_par_case,
                                    fill='red',
                                    tags='case')
                    self.canvas_echiquier.dessiner_pieces()
                if couleur_joueur_actif != couleur_piece_selectionnée:
                    raise self.MauvaiseCouleur

            except self.MauvaiseCouleur:
                self.messages['foreground'] = 'red'
                self.messages[
                    'text'] = "Erreur: Cette pièce n'est pas la votre"
                self.canvas_echiquier.dessiner_cases()
                self.canvas_echiquier.dessiner_pieces()

            except KeyError:
                self.messages['foreground'] = 'red'
                self.messages['text'] = 'Erreur: Aucune pièce à cet endroit.'
                self.canvas_echiquier.dessiner_cases()
                self.canvas_echiquier.dessiner_pieces()

    def deposer(self, event):

        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'
        ]

        # On trouve le numéro de ligne/colonne en divisant les positions en y/x par le nombre de pixels par case.
        ligne = event.y // self.canvas_echiquier.n_pixels_par_case
        colonne = event.x // self.canvas_echiquier.n_pixels_par_case
        global position_cible
        position_cible = "{}{}".format(
            self.canvas_echiquier.partie.echiquier.lettres_colonnes[colonne],
            int(self.canvas_echiquier.partie.echiquier.chiffres_rangees[
                self.canvas_echiquier.n_lignes - ligne - 1]))

        if self.partie.echiquier.deplacement_est_valide(
                self.position_selectionnee, position_cible) == True:
            self.sauvegarder("Revenir")

        try:
            var = 1
            if self.partie.echiquier.couleur_piece_a_position(
                    self.position_selectionnee) == self.partie.joueur_actif:
                if self.partie.echiquier.deplacer(self.position_selectionnee,
                                                  position_cible) == True:
                    self.partie.echiquier.deplacer(self.position_selectionnee,
                                                   position_cible)
                    var = 0
                    if isinstance(
                            self.partie.echiquier.recuperer_piece_a_position(
                                position_cible), Pion) == True:
                        if self.partie.echiquier.couleur_piece_a_position(
                                position_cible) == 'blanc':
                            if position_cible[1] == '8':
                                self.partie.echiquier.dictionnaire_pieces[
                                    position_cible] = Dame('blanc')
                                self.canvas_echiquier.dessiner_cases()
                                self.canvas_echiquier.dessiner_pieces()
                        elif self.partie.echiquier.couleur_piece_a_position(
                                position_cible) == 'noir':
                            if position_cible[1] == '1':
                                self.partie.echiquier.dictionnaire_pieces[
                                    position_cible] = Dame('noir')
                                self.canvas_echiquier.dessiner_cases()
                                self.canvas_echiquier.dessiner_pieces()

                    self.canvas_echiquier.dessiner_cases()
                    self.canvas_echiquier.dessiner_pieces()
                    self.partie.partie_terminee()
                    for i in toutes_les_position:
                        if self.partie.echiquier.deplacement_est_valide(
                                position_cible, i) and isinstance(
                                    self.partie.echiquier.
                                    recuperer_piece_a_position(i),
                                    Roi) == True:
                            self.partie.joueur_suivant()
                            self.messages['foreground'] = 'red'
                            self.messages[
                                'text'] = 'Le Roi ' + self.partie.joueur_actif + ' est en échec'
                            self.partie.joueur_suivant()
                            self.canvas_echiquier.dessiner_cases()
                            self.canvas_echiquier.dessiner_pieces()

                        if isinstance(
                                self.partie.echiquier.
                                recuperer_piece_a_position(i),
                                Pion) == True or isinstance(
                                    self.partie.echiquier.
                                    recuperer_piece_a_position(i),
                                    Tour) == True or isinstance(
                                        self.partie.echiquier.
                                        recuperer_piece_a_position(i),
                                        Fou) == True or isinstance(
                                            self.partie.echiquier.
                                            recuperer_piece_a_position(i),
                                            Cavalier) == True or isinstance(
                                                self.partie.echiquier.
                                                recuperer_piece_a_position(i),
                                                Dame) == True:
                            var = 1

                    self.partie.joueur_suivant()
                    self.label_temporaire[
                        'text'] = "C'est le tour au joueur " + self.partie.joueur_actif

                else:
                    raise self.DeplacementInvalide

        except self.DeplacementInvalide:
            self.messages['foreground'] = 'red'
            self.messages['text'] = 'Erreur: Deplacement invalide'
            self.canvas_echiquier.dessiner_cases()
            self.canvas_echiquier.dessiner_pieces()

        if self.partie.partie_terminee() == True:
            for i in toutes_les_position:
                if isinstance(
                        self.partie.echiquier.recuperer_piece_a_position(i),
                        Roi) == True:
                    couleur = self.partie.echiquier.couleur_piece_a_position(i)
            self.messages['foreground'] = 'red'
            self.messages['text'] = 'La partie est terminer.'
            self.label_temporaire['text'] = 'Félicitation joueur ' + couleur
            if var == 0:
                self.label_temporaire['text'] = 'Partie nulle de type pat'
                var2 = 1
                self.canvas_echiquier.dessiner_cases()
                self.canvas_echiquier.dessiner_pieces()

            self.canvas_echiquier.dessiner_cases()
            self.canvas_echiquier.dessiner_pieces()

    def nouvelle_partie(self):

        self.charger("Nouvelle_partie")
        self.label_temporaire[
            'text'] = "C'est le tour au joueur " + self.partie.joueur_actif

    def revenir(self):
        self.charger("Revenir")
        self.label_temporaire[
            'text'] = "C'est le tour au joueur " + self.partie.joueur_actif

    def changer_theme(self, event):
        if self.valeur.get() == 'Noel':
            self.canvas_echiquier.couleur_1 = 'red3'
            self.canvas_echiquier.couleur_2 = 'chartreuse4'
            self.canvas_echiquier.dessiner_cases()
            self.canvas_echiquier.dessiner_pieces()

        elif self.valeur.get() == 'Saint-Valentin':
            self.canvas_echiquier.couleur_1 = 'magenta'
            self.canvas_echiquier.couleur_2 = 'pink'
            self.canvas_echiquier.dessiner_cases()
            self.canvas_echiquier.dessiner_pieces()

        elif self.valeur.get() == 'Doritos-MountainDew':
            self.canvas_echiquier.couleur_1 = 'dark orange'
            self.canvas_echiquier.couleur_2 = 'chartreuse'
            self.canvas_echiquier.dessiner_cases()
            self.canvas_echiquier.dessiner_pieces()

        else:
            self.canvas_echiquier.couleur_1 = 'white'
            self.canvas_echiquier.couleur_2 = 'grey'
            self.canvas_echiquier.dessiner_cases()
            self.canvas_echiquier.dessiner_pieces()

    def montre_reglement(self):

        webbrowser.open_new(
            "https://fr.wikipedia.org/wiki/R%C3%A8gles_du_jeu_d'%C3%A9checs")

    def troll(self):

        webbrowser.open_new("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
        self.bouton_troll['text'] = 'On vous avait prévenu'