Partage
  • Partager sur Facebook
  • Partager sur Twitter

menu de jeu tkinter

récupération d'une valeur du menu pour faire ma fenêtre de jeu

    6 novembre 2022 à 23:06:30

    Bonjour, je code un morpion en tkinter et je rencontre un problème qui m'empêche de donner.. une finition à mon jeu.

    Je souhaiterais créer une fenêtre à l'exécution du fichier de mon jeu qui me permet de choisir la taille de la grille et de lancer le jeu.

    J'ai tout essayé : créer une deuxième fenêtre, créer une frame dans la fenêtre puis la supprimer et créer mon canvas, créer une frame dans le canvas puis la détruire et redimensionner le canvas grâce à ma valeur.. Bref ça fait plusieurs jours que je bosse là-dessus et que je me retrouve comme un c** avec une variable qui doit être modifiée manuellement dans le fichier pour choisir la taille de la grille. Si quelqu'un pouvait me trouver une solution ça serait juste magique. 

    Mon jeu (la variable que le menu doit me permettre de modifier est la variable n):

    from tkinter import *
    from tkinter import messagebox
                    
    def xy_vers_ij(x, y):
        i = 0
        if y >= 100:
            i = 1
            if y >= 200:
                i = 2
                if y >= 300:
                    i = 3
                    if y >= 400:
                        i = 4
                        if y >= 500:
                            i = 5
        j = 0
        if x >= 100:
            j = 1
            if x >= 200:
                j = 2
                if x >= 300:
                    j = 3
                    if x >= 400:
                        j = 4
                        if x >= 500:
                            j = 5
        return(i, j)
    
    def placer(grille, i, j, symbole):
        grille[i][j] = symbole
        
    def libre(grille, i, j):
        return grille[i][j] == '.'
        
    def test_l(grille, i, n):
        for j in range(0, n-2):
            if grille[i][j] == grille[i][j+1] == grille[i][j+2] != '.': return True
        return False
        
    def test_c(grille, j, n):
        for i in range(0, n-2):
            if grille[i][j] == grille[i+1][j] == grille[i+2][j] != '.': return True
        return False
        
    def obtenir_lignes(grille):
        return [[x for x in ligne] for ligne in grille]
    
    def obtenir_colonnes(grille):
        return zip(*grille)
    
    def obtenir_diag_arr(grille, n):
        b = [None] * (n-1)
        grille = [b[i:] + r + b[:i] for i, r in enumerate(obtenir_lignes(grille))]
        return [[x for x in r if x is not None] for r in obtenir_colonnes(grille)]
    
    def obtenir_diag_av(grille, n):
        b = [None] * (n-1)
        grille = [b[:i] + r + b[i:] for i, r in enumerate(obtenir_lignes(grille))]
        return [[x for x in r if x is not None] for r in obtenir_colonnes(grille)]
    
    def test_d(grille, n):
        diagonales = obtenir_diag_arr(grille, n) + obtenir_diag_av(grille, n)
        for i in range(len(diagonales)):
            if len(diagonales[i]) > 2:
                for j in range(0, len(diagonales[i])-2):
                    if diagonales[i][j] == diagonales[i][j+1] == diagonales[i][j+2] != '.': return True
        return False 
              
    def nulle(grille, n):
        for ligne in range(n):
            for colonne in range(n):
                 if libre(grille, ligne, colonne) : return False
        return True
            
    def test(grille, i, j, n):
        return test_d(grille, n) or test_l(grille, i, n) or test_c(grille, j, n)
    
    def croix(i, j):
        can.create_line(j*100+10, i*100+10, j*100+90, i*100+90, width="3", fill="white")
        can.create_line(j*100+90, i*100+10, j*100+10, i*100+90, width="3", fill="white")
    
    def cercle(i, j):
        can.create_oval(j*100+6, i*100+6, j*100+94, i*100+94, width="3", outline="white", fill="black")
        
    def nv_partie(n):
        if messagebox.askyesno('Morpion', 'Refaire une partie ?') == True:
            can.delete('all')
            can.create_line(100, 0, 100, n*100, width="3", fill="white")
            can.create_line(200, 0, 200, n*100, width="3", fill="white")
            can.create_line(0, 100, n*100, 100, width="3", fill="white")
            can.create_line(0, 200, n*100, 200, width="3", fill="white")
            ajout_ligne(n)
            grille = [['.' for colonne in range(n)] for ligne in range(n)]
        else: fen.destroy()
        
    def click(evt):
        x, y = evt.x, evt.y
        i, j = xy_vers_ij(x, y)
        global joueur, grille
        
        #case vide ?
        if not libre(grille, i, j):
            messagebox.showerror('Morpion', 'Cette case est prise')
        else : 
            #Tour joueur 1
            if joueur == 1:
                croix(i, j)
                placer(grille, i, j, 'X')
                if test(grille, i, j, n):
                    messagebox.showinfo('Morpion', 'Le Joueur 1 (X) a gagné la partie !')
                    nv_partie(n)
                elif nulle(grille, n):
                    messagebox.showinfo('Morpion', 'Egalité ! Pas de vainqueur')
                    nv_partie(n)
                joueur += 1
                
            #Tour joueur 2
            else:
                cercle(i, j)
                placer(grille, i, j, 'O')
                if test(grille, i, j, n):
                    messagebox.showinfo('Morpion', 'Le Joueur 2 (O) a gagné la partie !')
                    nv_partie(n)
                elif nulle(grille, n):
                    messagebox.showinfo('Morpion', 'Egalité ! Pas de vainqueur')
                    nv_partie(n)
                joueur -= 1
    
    def ajout_ligne(n):
        if n >= 4:
            can.create_line(300, 0, 300, n*100, width="3", fill="white")
            can.create_line(0, 300, n*100, 300, width="3", fill="white")
            if n >= 5:
                can.create_line(400, 0, 400, n*100, width="3", fill="white")
                can.create_line(0, 400, n*100, 400, width="3", fill="white")
                if n >= 6:
                    can.create_line(500, 0, 500, 600, width="3", fill="white")
                    can.create_line(0, 500, 600, 500, width="3", fill="white")
    
    def règles():
        rules = Toplevel()
        rules.title('Règles')
        Label(rules, text="Le jeu du Morpion est une grille de largeur et de hauteur égale, dans laquelle vous devez aligner 3 symboles (une croix pour le joueur 1 et un cercle pour le joueur 2).\nLes symboles peuvent être alignés en ligne, en colonnes ou en diagonale.\nQui sera le plus malin d'entre vous et alignera 3 symboles ? Une seule façon de le savoir: Jouez !").pack()
    
    fen = Tk()
    fen.title('Morpion')
    
    menu = Menu(fen)
    menu.add_command(label='Règles', command=règles)
    
    fen.config(menu=menu)
    
    n=6
    
    can = Canvas(width=n*100, height=n*100, bg="black")
    grille = [['.' for colonne in range(n)] for ligne in range(n)]
    joueur = 1
    
    can.create_line(100, 0, 100, n*100, width="3", fill="white")
    can.create_line(200, 0, 200, n*100, width="3", fill="white")
    can.create_line(0, 100, n*100, 100, width="3", fill="white")
    can.create_line(0, 200, n*100, 200, width="3", fill="white")
    ajout_ligne(n)
    
    can.bind('<Button-1>', click)
    can.pack()
    
    fen.mainloop()



    -
    Edité par RetroTeens 7 novembre 2022 à 7:53:02

    • Partager sur Facebook
    • Partager sur Twitter
      7 novembre 2022 à 10:56:47

      Bonjour,

      Tu pourrais créer une fenêtre principale pour initialiser n, avec un bouton qui crée une fenêtre secondaire (avec Toplevel() ), et ce n'est pas obligatoire de détruire la 1ere

      -
      Edité par Phil_1857 7 novembre 2022 à 10:59:58

      • Partager sur Facebook
      • Partager sur Twitter
        7 novembre 2022 à 11:57:23

        peut-être aussi problème de portée de ta variables n
        • Partager sur Facebook
        • Partager sur Twitter
          7 novembre 2022 à 19:45:32

          umfred a écrit:

          peut-être aussi problème de portée de ta variables n

          Oui c'est justement ça le problème.

          Phil_1857 a écrit:

          Bonjour,

          Tu pourrais créer une fenêtre principale pour initialiser n, avec un bouton qui crée une fenêtre secondaire (avec Toplevel() ), et ce n'est pas obligatoire de détruire la 1ere.

          Alors je viens d'essayer et j'arrive à un certain problème : - soit quand je crée une fonction pour créer la Toplevel et y dessiner le canvas puis l'executer avec mon bouton "Jouer", ma fonction de click ne reconnaît plus les variables grille et can.

          - soit quand je crée la Toplevel avec mon bouton puis que dans la suite de mon code je dessine dedans, je ne peux pas assigner mon canvas à la Toplevel. Alors il ne se crée pas.

          -
          Edité par RetroTeens 7 novembre 2022 à 19:54:39

          • Partager sur Facebook
          • Partager sur Twitter
            7 novembre 2022 à 20:12:46

            Bonjour.

            Sur une petite appli destinée à résoudre des systèmes d´équations, j´avais fait pour ma grille de saisie des indices des inconnues une liste de mes Entry dont le nombre était fonction du carré des inconnues que je faisais varier avec un Slider.

            Je les disposais ensuite avec grid dans une Frame avec une double boucle (axe vertical et axe horizontal).

            Edit : Après adaptation.

             

            -
            Edité par PB68 8 novembre 2022 à 14:20:53

            • Partager sur Facebook
            • Partager sur Twitter

            PB68

              8 novembre 2022 à 9:44:25

              Bonjour,

              "soit quand je crée la Toplevel avec mon bouton puis que dans la suite de mon code je dessine dedans, je ne peux pas assigner mon canvas à la Toplevel. Alors il ne se crée pas."

              def new_win():
              
                  _grid = Toplevel(fen)
                  _grid.title('Morpion')
                  _grid.geometry('600x670+450+2')
                  zone_graphique = Canvas(_grid,bg='lightgrey',height=150,width=150)


              Et dans zone_graphique, on dessine la grille en faisant une boucle de 0 à n+1 pour créer n+1 lignes horizontales et n+1 lignes verticales :

              -
              Edité par Phil_1857 8 novembre 2022 à 13:14:30

              • Partager sur Facebook
              • Partager sur Twitter
                8 novembre 2022 à 14:19:24

                J'ai réussi à dessiner ma grille à la bonne taille certes en créant la Toplevel  mais je ne peux pas dessiner mes croix et mes cercles dedans après ça me met que can n'est pas défini ce qui est normal puisque le canvas est créé dans la fonction qui crée la Toplevel.
                • Partager sur Facebook
                • Partager sur Twitter
                  8 novembre 2022 à 16:49:59

                  Normal : c'est la portée des variables

                  can (si c'est le nom de ton Canvas) est inconnu hors de la fonction qui créé Toplevel

                  Tu devrais le renvoyer en écrivant ça à la fin de cette fonction:

                  return(can)

                  et donc appeler la fonction comme ceci:

                  can = fonction_qui_crée_Toplevel()

                  can est donc maintenant connu dans le programme principal et tu peux l'injecter dans la fonction qui dessine croix et cercles

                  -
                  Edité par Phil_1857 8 novembre 2022 à 16:51:11

                  • Partager sur Facebook
                  • Partager sur Twitter
                    8 novembre 2022 à 18:23:56

                    Phil_1857 a écrit:

                    Normal : c'est la portée des variables

                    can (si c'est le nom de ton Canvas) est inconnu hors de la fonction qui créé Toplevel

                    Tu devrais le renvoyer en écrivant ça à la fin de cette fonction:

                    return(can)

                    et donc appeler la fonction comme ceci:

                    can = fonction_qui_crée_Toplevel()

                    can est donc maintenant connu dans le programme principal et tu peux l'injecter dans la fonction qui dessine croix et cercles

                    -
                    Edité par Phil_1857 il y a environ 1 heure


                    Je vais essayer ça, ça devrait marcher normalement. Merci beaucoup !!
                    • Partager sur Facebook
                    • Partager sur Twitter

                    menu de jeu 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