Partage
  • Partager sur Facebook
  • Partager sur Twitter

Puissance 4

Sujet résolu
    1 janvier 2022 à 23:02:13

    Bonjour je me redirige vers vous encore une fois 😅, j'ai commencé à faire un puissance 4 et j'ai comme beaucoup un problème au niveau de la fonction de vérification,  je doute beaucoup de mes capacité en python et je doit rendre ce projet très rapidement, j'ai fait le début moi même grâce à différents site ,(https://s15847115.domainepardefaut.fr/python/tkinter/resume.html). Pour la vérification je sais déjà qu'il faut que je regarde à partir des "coordonnés" du pions joué si il y'a dans la liste d'autres pions de la même couleurs. Mais voilà je ne sais pas comment l'implementer au code. Merci beaucoup de votre aide.

    Voici le code :

    from tkinter import*
    #creation du terrain de jeu sous forme python.
    def terrain_de_jeu():
        grille= [["" for j in range(7)]for i in range(6)]
        #print(grille)
        return grille
    
    #change la couleur tout les cliques
    def change_couleur(couleur_en_cours):
    
        if couleur_en_cours == 'yellow':
            return 'red'
        else:
            return 'yellow'
    
    couleur = "red"  # c'est pour mettre une couleur par défauts
    
    #defintion d'un évenement à chaque fois que le clique gauche est pressé.
    def clique_gauche(event):
        global couleur
        X,Y = event.x,event.y
        i = Y//50
        j = X//50
        if i<=5 or i>= 0 and 0 <= j <= 6:
            jet = can.itemcget(jetons[i][j],'fill')
    
            if jet == "white":
                if i == 5:
                    can.itemconfig(jetons[i][j],fill = couleur)
                else:
                    j_dessous = can.itemcget(jetons[i+1][j],'fill')
                    if j_dessous != "white":
                        can.itemconfig(jetons[i][j],fill = couleur)
        couleur = change_couleur(couleur)
        couleur_en_cours()
    
    
        #print (i,j)
        #print(couleur)
    
    #change la couleur pour le joueur en cours
    def couleur_en_cours():
        if change_couleur(couleur) == 'red' :
            label1['text'] = "C'est aux jaunes de jouer:"
            label2['text'] = "🟡"
        elif change_couleur(couleur) == 'yellow':
            label1['text'] = "C'est aux rouges de jouer :"
            label2['text'] = "🔴"
    
    
    #fenetre principal
    fenetre = Tk()
    fenetre.geometry("450x400+500+200")
    fenetre.title("Puissance 4 ")
    can = Canvas(width = 350, height = 300, bg = 'blue') # creation du terrain de jeu Tkinter
    rectangle = can.create_rectangle(0,0,350,300)   # la le plateau bleu
    carree = terrain_de_jeu()
    jetons = terrain_de_jeu()
    d=7
    for i in range(6):
        for j in range(7):
            carree[i][j] = can.create_rectangle(j*50,i*50,j*50+50,i*50+50)
            jetons[i][j] = can.create_oval(j*50+d,i*50+d,j*50+50-5,i*50+50-5,fill='white')
    can.pack()
    can.bind("<Button-1>",clique_gauche)
    Quitter = Button(fenetre, text='Quitter',fg = 'black' , command=fenetre.destroy) # bouton "quitter"
    Quitter.pack (side=RIGHT)
    label1 = Label(fenetre, text="Les rouges commencent !",bg = 'grey') # change le texte pour le joueur en cours
    label1.pack(pady=20,side = LEFT)
    label2 = Label(fenetre, text="/",bg = 'grey')
    label2.pack(pady=20,side = LEFT)
    fenetre.mainloop()
    
    #verification
    
    
    
    



    • Partager sur Facebook
    • Partager sur Twitter
      1 janvier 2022 à 23:16:06

      Apparemment vous n'avez fait que la partie graphique. Il manque un tableau de 6x5 cases qui reflète ce qu'on voir à l'écran et qu'on va pouvoir parcourir dans tous les sens. En cherchant un peu vous avez des codes comme ici... et un chantier d'intégration car en général on commence par écrire ce code là avant de s'attaquer à faire des jolis rendus graphiques.
      • Partager sur Facebook
      • Partager sur Twitter
        1 janvier 2022 à 23:29:15

        merci pour votre réponse déjà, cependant il ne manque pas de tableau, je l'ai créé a partir de la première fonction.

        Pour le coup il ne reste vraiment que le fonction vérification, le sujet que vous m'avez redirigé me dérange car il est très ancien (2011), et il utilise des vieux termes de python que je ne maîtrise pas. 

        -
        Edité par juandecolberto 1 janvier 2022 à 23:32:07

        • Partager sur Facebook
        • Partager sur Twitter
          1 janvier 2022 à 23:44:30

          mps a écrit:

          Apparemment vous n'avez fait que la partie graphique. Il manque un tableau de 6x5 cases qui reflète ce qu'on voir à l'écran et qu'on va pouvoir parcourir dans tous les sens. 


          En réalité, il dispose d'un tableau jetons qui donne les couleurs indirectement via can.itemconfig ce qui rend faisable la recherche d'un alignement. 

          juandecolberto a écrit:

          Mais voilà je ne sais pas comment l'implementer au code. 

          Pour rechercher basiquement un alignement de couleur contenant le jeton (i, j), il faut juste considérer les 4 cas (vertical, horizontal, diagonal montant, diagonal descendant). Et pour chaque cas, vous partez de (i,j), vous comptez le nombre de jetons allant dans une direction (le haut par exemple), puis la même chose mais dans la direction opposée pour voir si au total ça fait au moins 4. L'examen de couleur dans une direction se fait avec une boucle while. Quand la boucle while s'arrête, vous recommencez pareil dans l'autre direction. Si vous n'avez jamais fait ce genre de code en plus simple, ce sera difficile.



          • Partager sur Facebook
          • Partager sur Twitter
            1 janvier 2022 à 23:54:08

            merci beaucoup et pour la vérification de ligne j"avait mon prof qui m'avait donné ce bout de code et qui m'avait expliquer brièvement le fonctionnement :
            def verif_ligne(i,j):
                return [(i,j-3+k) for k in range(7) if 0<=j-3+k<=6 and 0<= i <=5]

            cet fonction prend les coordonnée de i,j  et après il faudrait que je vérifie a partir de liste al nombre de jetons correct a partir de ces coordonnées c'est ça ?

            le problème encore une fois c'est que je manque de capacité...., mais je vais m'y mettre merci !

            • Partager sur Facebook
            • Partager sur Twitter
              2 janvier 2022 à 1:46:52

              Cette fonction est facile à vérifier.
              Choisis les intervalle pour i et j que tu souhaites tester:
              -
              def verif_ligne(i,j):
                  return [(i,j-3+k) for k in range(7) if 0<=j-3+k<=6 and 0<= i <=5]
              for i in range(3):
                  for j in range(5):
                      print(verif_ligne(i,j))

              edit:

              La fonction peut également s'écrire comme suit:

              def verif_ligne(i, j):
                  return [(i, k) for k in range(max(0, j-3), min(j+4, 7)) if 0 <= i <= 5]
              En exécutant mon code, tu auras des listes de coordonnées
              Tu peux faire quelque chose du genre:
              for x, y in verif_ligne(i, j):
                  if grille[x][y] == 'yellow':
                     # c'est un jaune, tu les compte ou tu fais autre chose.

              Le site suivant donne également des stratégies:

              https://fr.wikipedia.org/wiki/Puissance_4

              -
              Edité par PierrotLeFou 2 janvier 2022 à 6:47:30

              • Partager sur Facebook
              • Partager sur Twitter

              Le Tout est souvent plus grand que la somme de ses parties.

                2 janvier 2022 à 8:30:53

                PascalOrtiz a écrit:

                mps a écrit:

                Apparemment vous n'avez fait que la partie graphique. Il manque un tableau de 6x5 cases qui reflète ce qu'on voir à l'écran et qu'on va pouvoir parcourir dans tous les sens. 


                En réalité, il dispose d'un tableau jetons qui donne les couleurs indirectement via can.itemconfig ce qui rend faisable la recherche d'un alignement. 

                Faisable mais compliqué... et difficile à tester sans le graphisme.
                • Partager sur Facebook
                • Partager sur Twitter
                  2 janvier 2022 à 11:24:24

                  juandecolberto a écrit:

                   j"avait mon prof qui m'avait donné ce bout de code et qui m'avait expliquer brièvement le fonctionnement :

                  def verif_ligne(i,j):
                      return [(i,j-3+k) for k in range(7) if 0<=j-3+k<=6 and 0<= i <=5]

                  cet fonction prend les coordonnée de i,j  et après il faudrait que je vérifie a partir de liste al nombre de jetons correct a partir de ces coordonnées c'est ça ?


                  Note que ta fonction est mal nommée (elle ne vérifie rien, elle donne une liste de coordonnées ligne X colonne) et la version donnée par Pierrot est meilleure bien que non parfaite puisqu'elle teste i alors qu'il ne varie pas. En réalité, cette fonction (et les 3 analogues pour les autres cas d'alignement) fournit une optimisation qui me semble inutile mais on peut garder l'idée de parcourir une liste de coordonnées.

                  Et justement, dans un exercice de mon cours, je donne quelques indications pour résoudre le problème de l'alignement. Il te suffit de récupérer les 4 listes contenant les coordonnées de toutes les cases de la ligne, la colonne et les deux diagonales contenant une position donnée (i, j), cf. la question 4 où je donne des indications pour traiter le cas le moins simple des deux diagonales. Ensuite, tu cherches dans chacune de ces 4 listes s'il existe un alignement de 4 valeurs consécutives et égales à la couleur présente en (i, j), cf. question 1 qui te permet de traiter tous les cas de manière homogène. Bon courage car ce n'est pas totalement évident!

                  • Partager sur Facebook
                  • Partager sur Twitter
                    2 janvier 2022 à 11:29:31

                    ok, merci beaucoup pour votre aide précieuse en tout cas !
                    • Partager sur Facebook
                    • Partager sur Twitter
                      2 janvier 2022 à 14:56:32

                      Un truc pas terrible avec numpy, je trouve ça casse bonbon de ne pas pouvoir vérifier simplement si une liste est dans une array...
                      tableau = np.array([ [0, 0, 0, 0, 0, 0, 0],
                                           [0, 0, 0, 0, 0, 0, 0],
                                           [0, 0, 1, 0, 0, 0, 0],
                                           [0, 0, 2, 1, 0, 0, 0],
                                           [0, 0, 2, 2, 1, 0, 0],
                                           [0, 1, 2, 2, 2, 1, 1]])

                      Fonction de vérification :

                      def check(x,y,valeur):
                      	h = tableau[x][max(0,y-3):min(7,y+4)]
                      	v = tableau[max(0,x-3):min(7,x+4),y]
                      	d1 = tableau.diagonal(offset=y-x)
                      	d2 = np.fliplr(tableau).diagonal(offset=(6-y)-x)
                      	for array in [h,v,d1,d2]:
                      		count = 0
                      		for value in array:
                      			if value == valeur:
                      				count += 1
                      				if count == 4:
                      					return True
                      			else:
                      				count = 0
                      	return False
                      >>> check(3,3,1)
                      True


                      ...

                      Comment faire pour vérifier si np.array([1]*4) est dans np.array([0,1,1,1,1]) par exemple ?
                      np.isin(a,b) c'est pas adapté... np.all(a,b) non plus np.any(a,b) non plus...


                      -
                      Edité par ErispoeLeNarvalo 2 janvier 2022 à 15:27:56

                      • Partager sur Facebook
                      • Partager sur Twitter
                        2 janvier 2022 à 15:17:58

                        J'ai placé les 4 fonctions tel que suggéré par le prof pour montrer la similitude et l'idée qu'on teste les coordonnées choisies.
                        Je fais les tests  0 <= indice < limite pour simuler ce que donne le range.

                        Comme on l'a dit, ces fonctions ne vérifient rien, elles produisent des listes de coordonnées.
                        -
                        def verif_ligne(i, j):
                            return [(i, j-3+k) for k in range(7) if 0 <= i < 6 and 0 <= j-3+k < 7]
                        def verif_colonne(i, j):
                            return [(i-3+k, j) for k in range(7) if 0 <= i-3+k < 6 and 0 <= j < 7]
                        def verif_montante(i, j):
                            return [(i-3+k, j-3+k) for k in range(7) if 0 <= i-3+k < 6 and 0 <= j-3+k < 7]
                        def verif_descendante(i, j):
                            return [(i+3-k, j-3+k) for k in range(7) if 0 <= i+3-k < 6 and 0 <= j-3+k < 7]

                        -
                        Edité par PierrotLeFou 2 janvier 2022 à 15:20:10

                        • Partager sur Facebook
                        • Partager sur Twitter

                        Le Tout est souvent plus grand que la somme de ses parties.

                          2 janvier 2022 à 16:03:46

                          ErispoeLeNarvalo a écrit:

                          Un truc pas terrible avec numpy, je trouve ça casse bonbon de ne pas pouvoir vérifier simplement si une liste est dans une array...

                          tableau = np.array([ [0, 0, 0, 0, 0, 0, 0],
                                               [0, 0, 0, 0, 0, 0, 0],
                                               [0, 0, 1, 0, 0, 0, 0],
                                               [0, 0, 2, 1, 0, 0, 0],
                                               [0, 0, 2, 2, 1, 0, 0],
                                               [0, 1, 2, 2, 2, 1, 1]])

                          Fonction de vérification :

                          def check(x,y,valeur):
                          	h = tableau[x][max(0,y-3):min(7,y+4)]
                          	v = tableau[max(0,x-3):min(7,x+4),y]
                          	d1 = tableau.diagonal(offset=y-x)
                          	d2 = np.fliplr(tableau).diagonal(offset=(6-y)-x)
                          	for array in [h,v,d1,d2]:
                          		count = 0
                          		for value in array:
                          			if value == valeur:
                          				count += 1
                          				if count == 4:
                          					return True
                          			else:
                          				count = 0
                          	return False
                          >>> check(3,3,1)
                          True


                          ...

                          Comment faire pour vérifier si np.array([1]*4) est dans np.array([0,1,1,1,1]) par exemple ?
                          np.isin(a,b) c'est pas adapté... np.all(a,b) non plus np.any(a,b) non plus...


                          -
                          Edité par ErispoeLeNarvalo il y a 29 minutes


                          Merci mais je ne pense pas utilisé numpy je ne connais pas dutout
                          • Partager sur Facebook
                          • Partager sur Twitter
                            2 janvier 2022 à 21:21:45

                            def check(x,y,valeur):
                            		h = tableau[x][max(0,y-3):min(7,y+4)]
                            		v = [line[y] for line in tableau[max(0,x-3):min(7,x+4)]]
                            		d1 = []
                            		for i in range(6):
                            			try:
                            				d1.append(tableau[(x+i)-y][i])
                            			except:
                            				pass
                            Un peu la flegme de chercher comment avoir d2...
                            • Partager sur Facebook
                            • Partager sur Twitter
                              3 janvier 2022 à 17:11:20

                              PierrotLeFou a écrit:

                              J'ai placé les 4 fonctions tel que suggéré par le prof pour montrer la similitude et l'idée qu'on teste les coordonnées choisies.
                              Je fais les tests  0 <= indice < limite pour simuler ce que donne le range.

                              Comme on l'a dit, ces fonctions ne vérifient rien, elles produisent des listes de coordonnées.
                              -
                              def verif_ligne(i, j):
                                  return [(i, j-3+k) for k in range(7) if 0 <= i < 6 and 0 <= j-3+k < 7]
                              def verif_colonne(i, j):
                                  return [(i-3+k, j) for k in range(7) if 0 <= i-3+k < 6 and 0 <= j < 7]
                              def verif_montante(i, j):
                                  return [(i-3+k, j-3+k) for k in range(7) if 0 <= i-3+k < 6 and 0 <= j-3+k < 7]
                              def verif_descendante(i, j):
                                  return [(i+3-k, j-3+k) for k in range(7) if 0 <= i+3-k < 6 and 0 <= j-3+k < 7]

                              -
                              Edité par PierrotLeFou hier à 15:20

                              Donc la fonction renvoie les coordonnées des cases de la grille 3 cases avant jusqu'à 3 cases après. et donc après je pense qu'il faudrait créer une fonction qui parcours les cases associées dans cette liste et renvoie True si 4 cases consécutives contiennent les mêmes valeurs et False sinon. On peut pour cette deuxième fonction, effectuer un parcours de liste et augmenter un compteur chaque fois que l'on trouve la même valeur sur  la case suivante et le remettre à 0 sinon ?

                              • Partager sur Facebook
                              • Partager sur Twitter
                                3 janvier 2022 à 17:33:04

                                En tout cas, tu es bien parti ...
                                Ça va dépendre de la stratégie que tu veux implémenter.
                                • Partager sur Facebook
                                • Partager sur Twitter

                                Le Tout est souvent plus grand que la somme de ses parties.

                                  3 janvier 2022 à 17:59:14

                                  D'accord je pensais partir la dessus.
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    3 janvier 2022 à 21:05:02

                                    juandecolberto a écrit:

                                    PierrotLeFou a écrit:

                                    Donc la fonction renvoie les coordonnées des cases de la grille 3 cases avant jusqu'à 3 cases après. et donc après je pense qu'il faudrait créer une fonction qui parcours les cases associées dans cette liste et renvoie True si 4 cases consécutives contiennent les mêmes valeurs et False sinon. On peut pour cette deuxième fonction, effectuer un parcours de liste et augmenter un compteur chaque fois que l'on trouve la même valeur sur  la case suivante et le remettre à 0 sinon ?


                                    Oui, c'est exactement la fonction connect de la question 2 de mon exercice déjà cité dans un message ci-dessus. Avec les fonctions que t'a confectionnées Pierre, tu es en mesure de réaliser pleinement l'exercice.
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      3 janvier 2022 à 21:10:18

                                      Bon j'ai fait autre chose mais sa ne marche pas ...
                                      def verif_ligne(i, j):
                                          return [(i, j-3+k) for k in range(7) if 0 <= i < 6 and 0 <= j-3+k < 7]
                                      
                                      def victoire():
                                          global i, j
                                          for x,y in verif_ligne(i,j):
                                              if terrain_de_jeu()[x][y] == 'yellow':
                                                  return 'yellow'
                                              elif terrain_de_jeu()[x][y] == 'red':
                                                  return 'red'
                                      
                                      
                                      def fin():
                                          if victoire() == 'yellow':
                                              fenetre.destroy()
                                              fenetre_fin_j = Tk()
                                              fenetre_fin_j.geometry("450x400+500+200")
                                              fenetre_fin_j.title("Puissance 4 ")
                                              label1 = Label(fenetre_fin_j, text="Victoire des Jaunes!", bg='grey')
                                              label1.pack(pady=20, side=LEFT)
                                          elif victoire() == 'red':
                                              fenetre.destroy()
                                              fenetre_fin_r = Tk()
                                              fenetre_fin_r.geometry("450x400+500+200")
                                              fenetre_fin_r.title("Puissance 4 ")
                                              label1 = Label(fenetre_fin_r, text="Victoire des Rouges!", bg='grey')
                                              label1.pack(pady=20, side=LEFT)

                                      Après j'ai mis la fonction victoire() et fin () dans clique_gauche() mais quand je teste ils me disent que victoire() et fin() ne sont pas définis ????

                                      def clique_gauche(event):
                                          global couleur
                                          global i, j
                                          X,Y = event.x, event.y
                                          i = Y // 50
                                          j = X // 50
                                          if i <= 5 or i >= 0 and 0 <= j <= 6:
                                              jet = can.itemcget(jetons[i][j], 'fill')
                                      
                                              if jet == "white":
                                                  if i == 5:
                                                      can.itemconfig(jetons[i][j], fill=couleur)
                                                  else:
                                                      j_dessous = can.itemcget(jetons[i + 1][j], 'fill')
                                                      if j_dessous != "white":
                                                          can.itemconfig(jetons[i][j], fill=couleur)
                                      
                                          couleur = change_couleur(couleur)
                                          couleur_en_cours()
                                          victoire()
                                          fin()
                                      

                                      update : j'ai mis la fonction victoire( ) avant la fonction clique gauche( ) et sa ne m'afficher plus l'erreur mais sa ne fonctionnait toujours pas ????

                                      alors j'ai changer la fonction victoire( ) en mettant ça, problème des que l'on pose UN jetons jaune sa lance la victoire ??

                                      def victoire():
                                          global i, j
                                          for x,y in verif_ligne(i,j):
                                              if can.itemcget(jetons[x][y], 'fill') == 'yellow':
                                                  return 'yellow'

                                      -
                                      Edité par juandecolberto 3 janvier 2022 à 22:48:21

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        4 janvier 2022 à 1:37:28

                                        Si je comprend bien ta fonction, dès que je trouve un jaune sur la ligne, je retourne jaune ?
                                        C'est bien ce que tu veux faire ?
                                        Est-ce suffisant pour crier victoire! :)
                                        • Partager sur Facebook
                                        • Partager sur Twitter

                                        Le Tout est souvent plus grand que la somme de ses parties.

                                          4 janvier 2022 à 14:27:59

                                          quand tu fais

                                          def victoire():
                                              global i, j
                                              for x,y in verif_ligne(i,j):
                                                  if terrain_de_jeu()[x][y] == 'yellow':
                                                      return 'yellow'
                                                  elif terrain_de_jeu()[x][y] == 'red':
                                                      return 'red'

                                          en ligne 4 et 6, tu créés à chaque fois une fois une nouvelle grille vide (si ton code pour cette fonction n'a pas changer depuis le début)

                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          Puissance 4

                                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                          • Editeur
                                          • Markdown