Partage
  • Partager sur Facebook
  • Partager sur Twitter

Demande aide pour morpion tkinter

Aide pour elément croix et ronds plus souris

    8 mars 2015 à 14:39:21

    bonjour as tous

    je debute vraiment en programation et je voudrais avoir votre aide concernant mon morpion en Tkinter.

    Alors voila j'aimerais que quand je clique avec le bouton droit de la souris le programe met des croix pour le joeur1 et met des ronds ensuite pour le joueur 2.

    Merci de votre aide,voici le programme:

    #!/usr/bin/python
    #coding: utf-8
    
    from Tkinter import *
    fenetre = Tk()
    fenetre.wm_title( "Morpion" )
    
    def delete(): #permet de recommencer au debut
        can.delete(ALL)
    	
        grille()
    
    def dessinercroix( evenement ): 
        croix()
    
    def grille():
        for i in range( nb+1 ):
            can.create_line( x0+c*i, y0, x0+c*i, y0 + nb*c, fill = "black" )
            can.create_line( x0, y0+c*i, x0+nb*c , y0+c*i, fill = "black" )
    
    def croix(x, y) : # fonction qui permet de tracer une croix dans le canvas
            can.create_line(x+20, y+20, x+80, y+80, fill="black", width=5)  # cree deux lignes en diagonales formant une croix de couleur noir
            can.create_line(x+80, y+20, x+20, y+80, fill="black", width=5)
    
    def ronds(x, y) : # fonction pour créer le ronds 
        can.create_oval(x+80,y+20, x+20 , y+80, fill="black", width=5) #cree le ronds
    
    # variables :
    nb = 3 # nb de cases
    c = 140 # taille d'une case
    x0, y0 = 10, 10 # coordonnées du point en haut à gauche de la grille
    
    eff = Button(fenetre, text = 'recommencer', command = delete)
    fenetre.bind( "<Button-1>", dessinercroix )
    fenetre.focus_set()
    can = Canvas( fenetre, height = 500, width = 500, bg = "white" ) #creation de la grille 
    can.pack( side = LEFT )
    grille()
    eff.pack()
    fenetre.mainloop()
    



    • Partager sur Facebook
    • Partager sur Twitter
      10 mars 2015 à 8:17:54

      Toujours besoin d'aide?
      • Partager sur Facebook
      • Partager sur Twitter
        10 mars 2015 à 11:30:10

        Tu as besoin d'une variable qui détermine quel est le joueur en train de jouer. Comme tu débutes, et que tu n'as probablement pas encore vu les classes, le plus simple est probablement d'avoir une variable globale contenant cette information.

        Voici un exemple qui devrait t'inspirer

        !/usr/bin/env python

        -- coding: utf8 --

        from Tkinter import *

        def restart():

        "Permet de recommencer au debut"
        grille.delete(ALL)
        draw_board(grille)
        grid[:] = [[ None for col in range(NB_CASES)] for row in range(NB_CASES)]
        
        
        

        def from_screen_to_grid(x, y):

        """Retourne la position dans la grille du point donné à l'écran.
        Si le point est en dehors de la grille, retourne None.
        """
        pos_x = (x - MARGIN_X) // TAILLE_CASE
        if pos_x < 0 or pos_x >= NB_CASES:
            pos_x = None
        pos_y = (y - MARGIN_Y) // TAILLE_CASE
        if pos_y < 0 or pos_y >= NB_CASES:
            pos_y = None
        return pos_x, pos_y
        
        
        

        def on_click(evenement):

        "Traite le click de souris sur la grille."
        grid_x, grid_y = from_screen_to_grid(evenement.x, evenement.y)
        
        if grid_x is None or grid_y is None:
            return
        
        if grid[grid_y][grid_x] is not None:
            return
            
        global player_turn
        if player_turn == 0:
            grid[grid_y][grid_x] = "CROIX"
            dessine_croix(grid_x, grid_y)
            player_turn = 1
        else: # player_turn == 1
            grid[grid_y][grid_x] = "ROND"
            dessine_rond(grid_x, grid_y)
            player_turn = 0
        

        def draw_board(grille):

        "Dessine le plateau de jeu"
        for i in range(NB_CASES + 1):
            grille.create_line(MARGIN_X + TAILLE_CASE * i,
                               MARGIN_Y,
                               MARGIN_X + TAILLE_CASE * i,
                               MARGIN_Y + NB_CASES * TAILLE_CASE,
                               fill="black")
            grille.create_line(MARGIN_X,
                               MARGIN_Y + TAILLE_CASE * i,
                               MARGIN_X + NB_CASES * TAILLE_CASE,
                               MARGIN_Y + TAILLE_CASE * i,
                               fill="black")
        

        def dessine_croix(grid_x, grid_y):

        "Permet de tracer une croix dans le canvas aux coordonnées de la grille grid_x, grid_y"
        x = grid_x * TAILLE_CASE + MARGIN_X
        y = grid_y * TAILLE_CASE + MARGIN_Y
        TOP_LEFT = TAILLE_CASE * 0.8
        BOTTOM_RIGHT = TAILLE_CASE * 0.2
        grille.create_line(x + TOP_LEFT, y + TOP_LEFT,
                           x + BOTTOM_RIGHT, y + BOTTOM_RIGHT,
                           fill="black", width=5)
        grille.create_line(x + BOTTOM_RIGHT, y + TOP_LEFT,
                           x + TOP_LEFT, y + BOTTOM_RIGHT,
                           fill="black", width=5)
        

        def dessine_rond(grid_x, grid_y):

        "Permet de créer le rond dans le canvas aux coordonnées de la grille grid_x, grid_y"
        x = grid_x * TAILLE_CASE + MARGIN_X
        y = grid_y * TAILLE_CASE + MARGIN_Y
        TOP_LEFT = TAILLE_CASE * 0.8
        BOTTOM_RIGHT = TAILLE_CASE * 0.2
        grille.create_oval(x + BOTTOM_RIGHT, y + TOP_LEFT,
                           x + TOP_LEFT , y + BOTTOM_RIGHT,
                           fill="black", width=5)
        

        Constantes :

        NB_CASES = 3 TAILLE_CASE = 140 MARGIN_X, MARGIN_Y = 10, 10

        player_turn = 0 # 0 for player 1, 1 for player 2 grid = [[ None for col in range(NB_CASES)] for row in range(NB_CASES)]

        fenetre = Tk() fenetre.wm_title("Morpion") fenetre.focus_set()

        grille = Canvas(fenetre, height=500, width=500, bg="white" ) grille.bind("<Button-1>", on_click) grille.pack(side=LEFT) draw_board(grille)

        button_restart = Button(fenetre, text='recommencer', command=restart) button_restart.pack()

        fenetre.mainloop()

        </pre>

        -
        Edité par Dan737 10 mars 2015 à 11:30:54

        • Partager sur Facebook
        • Partager sur Twitter
          10 mars 2015 à 12:03:15

          bonjour a vous

          oui j'ai toujours besoin d'aide

          Merci de votre reponce a tous

          • Partager sur Facebook
          • Partager sur Twitter
            10 mars 2015 à 12:16:42

            DAn737 as tout dis, regarde son code et dis nous ce que tu ne comprends pas :)

            • Partager sur Facebook
            • Partager sur Twitter
              10 mars 2015 à 16:17:34

              Re le mot margin je ne comprends pas du tout ☺
              • Partager sur Facebook
              • Partager sur Twitter
                10 mars 2015 à 16:30:31

                MARGIN_X, MARGIN_Y = 10, 10
                • Partager sur Facebook
                • Partager sur Twitter
                  10 mars 2015 à 16:50:42

                  Tu l'aides pas vraiment.

                  Margin en anglais c'est la marge, en l'occurrence ça doit vouloir dire une marge intérieure ou extérieure aux cases. :)

                  Et elles sont écrites en majuscules pour faire passer le message qu'on ne doit pas modifier ces variables, ce sont des constantes.

                  -
                  Edité par InhumanRampage 10 mars 2015 à 16:52:07

                  • Partager sur Facebook
                  • Partager sur Twitter
                    10 mars 2015 à 17:10:17

                    d'accord merci a vous tous
                    • Partager sur Facebook
                    • Partager sur Twitter
                      10 mars 2015 à 19:28:34

                      Dans ton code, tu avais appelé ça x0, y0. Perso je trouve plus explicite de nommer les variables MARGE_X et MARGE_Y (en français si c'est plus clair pour toi) puisque c'est à ça que sert ces valeurs; à décaler un peu la grille.

                      Regarde aussi en ligne 29 dans ton code, tu as nb = 3 # nb de cases, alors que moi j'ai écrit NB_CASES = 3. J'ai pas besoin de mettre de commentaires car le nom de la variable (constante ici) est explicite. Tout le monde sait ce que représente ce 3. C'est une bonne habitude à prendre, de nommer les variables, fonctions, classes, ... par un nom qui représente vraiment ce qu'il est ou à quoi il sert. Dernier exemple, ton fonction delete. Moi je l'ai appeler restart, car elle est appelée pour relancer la partie, pas pour effacer quelque chose. L'effacement est l'une des choses qu'il faut faire pour relancer la partie. Tu vois? :)

                      • Partager sur Facebook
                      • Partager sur Twitter
                        11 mars 2015 à 16:23:49

                        ah oui d'accord je comprend mieux merci a toi

                        Je débute vraiment en programmation  donc merci de votre aide tous.

                        Ps:le meilleur ide c'est lequel ?je suis sur windows

                        • Partager sur Facebook
                        • Partager sur Twitter
                          21 mai 2015 à 15:11:14

                          Bonjour, par curiosité, j'aimerais quelques explications sur cette partie ! Merci bien :)
                           deffrom_screen_to_grid(x, y):
                          """Retourne la position dans la grille du point donné à l'écran.
                          Si le point est en dehors de la grille, retourne None.
                          """
                          pos_x = (x - MARGIN_X) // TAILLE_CASE
                          if pos_x < 0 or pos_x >= NB_CASES:
                          pos_x = None
                          pos_y = (y - MARGIN_Y) // TAILLE_CASE
                          if pos_y < 0 or pos_y >= NB_CASES:
                          pos_y = None
                          return pos_x, pos_y
                          • Partager sur Facebook
                          • Partager sur Twitter
                            22 mai 2015 à 6:45:36

                            j'avoue ne pas avoir compris non plus :o

                            • Partager sur Facebook
                            • Partager sur Twitter
                              22 mai 2015 à 8:37:17

                              bonjour

                              Dans le code de Dan ligne 11, pourquoi écrire grid[:] = ?

                              (la question porte sur le [:])

                              merci

                              • Partager sur Facebook
                              • Partager sur Twitter
                                22 mai 2015 à 10:30:39

                                @ClmPOmar: l'idée est de trouver pour des coordonnées écran (x, y) quel est la case (i, j) correspondante du tableau dessiné. Prenons un exemple. Soit un tableau de 3 cases sur 3 situé tout en haut à gauche (coordonnée 0, 0 à l'écran). Imaginons que chaque case fait 10 pixels de côté. Dans le système de coordonnées i, j de mon tableau, je nomme donc mes cases comme ceci

                                (0, 0) | (1, 0) | (2, 0)

                                (0, 1) | (1, 1) | (2, 1)

                                (0, 2) | (1, 2) | (2, 2)

                                </pre> Donc quelles sont les coordonnées sur l'écran de chacun de ces cases? Pour la case (0, 0), ça va de (0, 0) à (9, 9) puisqu'elle fait 10 pixels sur 10. Pour la case (1, 0), c'est (10, 0) à (19, 9), et pour la case (2, 0) c'est (20, 0) à (20, 9). Pour la case (0, 1) ça va de (0, 10) à (9, 19), puis pour la (1, 1) de (10, 10) à (19, 19) et ainsi de suite. Donc pour aller du x à l'écran vers le i du tableau, il suffit de faire la division euclidienne de x par la taille de la case (10 pixels). Si on a pour x 12, alors 12 // 10 = 1 avec un reste de 2 dont on se fout. Ainsi pour x et y on a: i = x // TAILLE_CASE et j = y // TAILLE_CASE.

                                Maintenant si on ne place pas le tableau tout en haut à gauche mais qu'on met une marge à droite et une marge en haut, il est évident que pour le précédent calcul, il faut d'abord retirer la valeur de la marge de droite à x avant de faire la division. Si la marge de droite valait 50 pixels, la case (0, 0) va de (100, 0) à (109, 9). Donc si on enlève 100 de x, on revient dans notre premier cas.

                                Finalement on vérifie si on a bien cliqué sur le tableau en s'assurant que l'indice i ou j trouvé est bien compris dans les bornes de notre tableau. Pour un tableau de 3 sur 3, on ne peut pas avoir un i plus petit que 0 ou plus grand que 2. Même chose pour j. Si c'est le cas, je retourne None.

                                @ast2: cette notation est un slice. Ca veut dire assigner ce qui est à droite du signe égal à l'entièreté de la liste. C'est pas hyper nécessaire dans ce cas-ci. C'est un poil plus performant (mais dans ce cas, on s'en fout clairement) car Python ne doit pas désallouer de la mémoire pour l'ancienne liste et ré-allouer de la mémoire pour la nouvelle liste.

                                >>> li = list(range(20))
                                >>> li
                                [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
                                >>> li[10:] = list(range(10)) # On assigne cette liste au slice qui va de 10 à la fin de la liste
                                >>> li
                                [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
                                >>> li[:] = ['a'] * 20 # On assigne cette liste au slice qui fait l'entièreté du contenu de la liste
                                >>> li
                                ['a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a']
                                

                                -
                                Edité par Dan737 22 mai 2015 à 10:31:14

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  22 mai 2015 à 11:46:17

                                  Slt je viens de voir  vos messages  que tout  suite. Mais @Dan737  a répondu  pour moi. Merci a toi @Dan737
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    22 mai 2015 à 15:47:35

                                    Merci pour la réponse Dan

                                    • Partager sur Facebook
                                    • Partager sur Twitter

                                    Demande aide pour morpion tkinter

                                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                    • Editeur
                                    • Markdown