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 __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 __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)
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()
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)
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."
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
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)
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))))
# -*- 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
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()
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"
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()
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)
# -*- 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()
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)
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'