Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 11/06/2015, à 18:56

Lhomme

arreter le chronomètre au lancement de l'autre (Python)

Bonjour,
je suis entrain de faire un jeux python entre deux joueurs et je veux que chaque joueur ait 20 secondes pour exécuter son tour. J'ai défini une méthode qui donne un bon chrono. Le problème est que les temps se superposent au fur et à mesure qu'on joue. Voici la méthode qui produit le chrono:

      # ajout d'une étiquette pour le temps à ne pas dépasser par le joueur courant
      self.lab = Label(self,foreground='black' )
      self.lab.grid(row = 9, column =2)

    def decompte(self,count =20):
        """
        Fonction gérant le temps à ne pas dépasser par chaque jouer
        """

        self.lab['text'] = 'Il vous reste  '+ str(count) + ' secondes'
        if count > 0 :
            self.temps = self.after(1000, self.decompte, count-1)
J'ai essayé plusieurs méthode pour reprendre le temps à 20 et ne plus afficher celui du joueur précédent sans succès.
Si quelqu'un a une idée, ça m'aiderait beaucoup.
Merci

Hors ligne

#2 Le 11/06/2015, à 21:08

pingouinux

Re : arreter le chronomètre au lancement de l'autre (Python)

Bonsoir,
L'idéal serait que tu fournisses le script actuel (ou au moins une partie), en expliquant ce qui ne va pas, pour pouvoir faire des tests.

Hors ligne

#3 Le 12/06/2015, à 04:47

MicP

Re : arreter le chronomètre au lancement de l'autre (Python)

Ça ressemble à un chrono pour partie d'échec, et si c'est ça, une rapide recherche sur le forum me donne ce lien

Mais c'est tellement plus édifiant de le faire sois-même, mais comme toujours, il faut bien définir ce que l'on veux faire de façon logique.

Dernière modification par MicP (Le 12/06/2015, à 04:59)

Hors ligne

#4 Le 13/06/2015, à 07:19

Lhomme

Re : arreter le chronomètre au lancement de l'autre (Python)

Bonjour à pingouinux et MicP,

Merci de votre réponse, j'ai regardé le lien fourni par MicP, le code parait long juste pour un chrono, de plus j'ai testé sans obtenir quelque.
je mets  le script au niveau ou je suis.( J'apprends à programmer un jeu de dame) Le chrono décrémente bien. Je voudrais que dès qu'un joueur joue son tour dans les 20 secondes qu'il a, son chrono s'arrête pour afficher celui de l'adversaire.

from tkinter import Tk, Canvas, Label, NSEW, messagebox


class CanvasDamier(Canvas):
    def __init__(self, parent, n_pixels_par_case):
        # Nombre de lignes et de colonnes.
        self.n_lignes = 8
        self.n_colonnes = 8

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

        # Appel du constructeur de la classe de base (Canvas).
        super().__init__(parent, width=self.n_lignes * n_pixels_par_case,
                         height=self.n_colonnes * self.n_pixels_par_case)

        # Dictionnaire contenant les pièces.
        self.piecesb = {
            (7, 0): 'PB', (7, 2): 'PB', (7, 4): 'PB', (7, 6): 'PB', (6, 1): 'PB', (6, 3): 'PB', (6, 5): 'PB',
            (6, 7): 'PB', (5, 0): 'PB', (5, 2): 'PB', (5, 4): 'PB', (5, 6): 'PB'}
        self.piecesn = {
            (2, 1): 'PN', (2, 3): 'PN', (2, 5): 'PN', (2, 7): 'PN', (1, 0): 'PN', (1, 2): 'PN', (1, 4): 'PN',
            (1, 6): 'PN', (0, 1): 'PN',  (0, 3): 'PN', (0, 5): 'PN', (0, 7): 'PN'}

       
        self.bind('<Configure>', self.redimensionner)

    def dessiner_cases(self):
        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

                # On détermine la couleur.
                if (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):
        caracteres_pieces = {'PB': 'o',
                             'DB': 'O',
                             'PN': 'x',
                             'DN': 'X'}

        # Caractères unicode représentant les pièces. Vous avez besoin de la police d'écriture Deja-Vu, qui est
        # installée automatiquement si vous installez le logiciel LibreOffice.
        #caracteres_pieces = {'PB': '\u26C0',
        #                     'DB': '\u26C1',
        #                     'PN': '\u26C2',
        #                     'DN': '\u26C3'}

        # Pour tout paire position, pièce:
        for position, piece in self.piecesb.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 = position[0] * self.n_pixels_par_case + self.n_pixels_par_case // 2
            coordonnee_x = position[1] * self.n_pixels_par_case + self.n_pixels_par_case // 2
            self.create_text(coordonnee_x, coordonnee_y, text=caracteres_pieces[piece],
                             font=('Deja Vu', self.n_pixels_par_case//2), tags='pieceb')
        for position, piece in self.piecesn.items():
           
            coordonnee_y = position[0] * self.n_pixels_par_case + self.n_pixels_par_case // 2
            coordonnee_x = position[1] * self.n_pixels_par_case + self.n_pixels_par_case // 2
            self.create_text(coordonnee_x, coordonnee_y, text=caracteres_pieces[piece],
                             font=('Deja Vu', self.n_pixels_par_case//2), tags='piecen')
    def redimensionner(self, event):
   
        nouvelle_taille = min(event.width, event.height)

       
        self.n_pixels_par_case = nouvelle_taille // self.n_lignes

       
        self.delete('case')
        self.dessiner_cases()

        self.delete('pieceb')
        self.delete('piecen')
        self.dessiner_pieces()


class Fenetre(Tk):
    def __init__(self):
        super().__init__()

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

        # La position sélectionnée.
        self.position_selectionnee = None
        self.pion = None
        # ajout d'une étuette pour le chrono
        self.lab = Label(self,foreground='red', text = '' )
        self.lab.grid()

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

        # Création du canvas damier.
        self.canvas_damier = CanvasDamier(self, 60)
        self.canvas_damier.grid(sticky=NSEW)

        # Ajout d'une étiquette d'information.
        self.messages = Label(self)
        self.messages.grid()
        self.val = 1
        self.val_ligne = None
        self.val_colonne = None

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

    def selectionner(self, event):
       
        self.ligne = event.y // self.canvas_damier.n_pixels_par_case
        self.colonne = event.x // self.canvas_damier.n_pixels_par_case

       
        try:
            pieceb = self.canvas_damier.piecesb[(self.ligne, self.colonne)]
            #piecen = self.canvas_damier.piecesn[(self.ligne,self.colonne)]

            self.position_selectionnee = (self.ligne, self.colonne)

            self.messages['foreground'] = 'black'
            self.messages['text'] = 'Pièce sélectionnée : {} à la position {}.'.format(pieceb,
                                                                                      self.position_selectionnee)
            self.canvas_damier.delete('pieceb')
            self.pion = 'PB'
            if self.val ==1:
                del self.canvas_damier.piecesb[self.ligne, self.colonne]
                self.val =0
                self.val_ligne = self.ligne
                self.val_colonne = self.colonne

            self.canvas_damier.dessiner_pieces()
        except KeyError:
            try:

                piecen = self.canvas_damier.piecesn[(self.ligne, self.colonne)]
                # On change la valeur de l'attribut position_selectionnee.
                self.position_selectionnee = (self.ligne, self.colonne)

                self.messages['foreground'] = 'black'
                self.messages['text'] = 'Pièce sélectionnée : {} à la position {}.'.format(piecen,
                                                                                      self.position_selectionnee)
                self.canvas_damier.delete('piecen')
                self.pion = 'PN'
                if self.val ==1:
                    del self.canvas_damier.piecesn[self.ligne, self.colonne]
                    self.val =0
                    self.val_ligne = self.ligne
                    self.val_colonne = self.colonne

                self.canvas_damier.dessiner_pieces()
            except KeyError:

                self.messages['foreground'] = 'red'
                self.messages['text'] = 'Erreur: Aucune pièce à cet endroit.'

    def inscrire(self,event):

        if (self.pion == 'PB'):
            if self.ligne1 != self.val_ligne -1 or (self.colonne1 != self.val_colonne -1 and self.colonne1 != self.val_colonne +1):
                messagebox.showerror('Erreur', 'Case invalide')

            else:
                self.canvas_damier.delete('pieceb')
                self.canvas_damier.piecesb[self.ligne1, self.colonne1] = self.pion
                self.val =1
                self.canvas_damier.dessiner_pieces()
        elif self.pion == 'PN':
            if self.ligne1 != self.val_ligne +1 or (self.colonne1 != self.val_colonne -1 and self.colonne1 != self.val_colonne +1):
                messagebox.showerror('Erreur', 'Case invalide')
            else:
                self.canvas_damier.delete('piecen')
                self.canvas_damier.piecesn[self.ligne1, self.colonne1] = self.pion
                self.val =1
                self.canvas_damier.dessiner_pieces()
        self.decompte()
    def clic(self,event):
        if self.val ==1:
            self.selectionner(event)

        elif self.val ==0:

            self.ligne1 = event.y // self.canvas_damier.n_pixels_par_case
            self.colonne1 = event.x // self.canvas_damier.n_pixels_par_case
            try:
                self.canvas_damier.piecesb[self.ligne1, self.colonne1]== 'PB'
                messagebox.showerror('Erreur', 'Case occupée')
            except KeyError:
                try:
                    self.canvas_damier.piecesn[self.ligne1, self.colonne1]=='PN'
                    messagebox.showerror('Erreur', 'Case occupée')
                except KeyError:
                    self.inscrire(event)

    def decompte(self,count =20):
        """
        Fonction gérant le temps à ne pas dépasser par chaque jouer
        """

        self.lab['text'] = 'Il vous reste  '+ str(count) + ' secondes'
        if count > 0 :
            self.after(1000, self.decompte, count-1)


if __name__ == '__main__':
    f = Fenetre()
    f.mainloop()

Hors ligne

#5 Le 13/06/2015, à 10:55

pingouinux

Re : arreter le chronomètre au lancement de l'autre (Python)

Effectivement, la fonction decompte va jusqu'à 0, et il y en a plusieurs en cours simultanément si les joueurs jouent rapidement.
Je te propose ceci (mais il y a peut-être plus simple) :

  1. Supprimer la fonction decompte actuelle (lignes 204 à 211)

  2. Remplacer la ligne 185
       

            self.decompte()

        par
       

            if self.chrono : self.chrono.arret=True
            self.chrono=Chrono(self)
  3. Ajouter après la ligne 90
         

           self.chrono=None
  4. Ajouter après la ligne 86
       

    class Chrono() :
        def __init__(self,fenetre):
            self.arret=False
            self.decompte(fenetre)
    
        def decompte(self,fenetre,count =20):
            """
            Fonction gérant le temps à ne pas dépasser par chaque jouer
            """
    
            if self.arret : return
            fenetre.lab['text'] = 'Il vous reste  '+ str(count) + ' secondes'
            if count > 0 :
                fenetre.after(1000, self.decompte, fenetre, count-1)

Hors ligne

#6 Le 14/06/2015, à 12:17

Lhomme

Re : arreter le chronomètre au lancement de l'autre (Python)

Un gros merci, c'est effectivement ce que je voulais. Ça fonctionne très bien.

Hors ligne