Partage
  • Partager sur Facebook
  • Partager sur Twitter

Ne comprend pas le code

    2 mai 2011 à 8:41:45

    Bonjour à tous,
    je vous écris car j'ai besoin de vous,on a ocmmencé le python,mais j'ai des difficultés avec ce language.
    On a écris un morpion like en python mais je n'arrive pas à tout capter...
    Si quelqu'un ici pourrais m'expliquer en détail ce programme,ça m'aiderais beaucoup...

    def test_victoire(p):
        for c in ((0,1,2),(3,4,5),(6,7,8),(0,3,6),(1,4,7),(2,5,8),(0,4,8),(2,4,6)):
            if p[c[0]]==p[c[1]]==p[c[2]]:
                if p[c[0]]==1 : return 1
                if p[c[0]]==2 : return 2
        return 0
    
    
    def MatchNul(p):
        nul=1
        for c in range(9):
            if p[c]==0:
                nul=0
                break
        return nul
            
    
    def Tree(p,j,compteur):
        for c in range(9):
            if p[c]==0 :
                p[c]=j
                t=test_victoire(p)
                if t==j:
                    compteur=compteur+1
                elif MatchNul(p)==1:
                    compteur=compteur+1
                else :
                    compteur=Tree(p,3-j,compteur)
                p[c]=0
        return compteur
                
    
    print(Tree([0,0,0,0,0,0,0,0,0],1,0))
    


    Je sais que c'est surement un programme super simple mais j'avoue que j'ai du mal...

    merci d'avance,

    Cordialement,
    • Partager sur Facebook
    • Partager sur Twitter
      2 mai 2011 à 9:39:34

      Citation : lifetor

      Bonjour à tous,
      je vous écris car j'ai besoin de vous,on a ocmmencé le python,mais j'ai des difficultés avec ce language.
      On a écris un morpion like en python mais je n'arrive pas à tout capter...
      Si quelqu'un ici pourrais m'expliquer en détail ce programme,ça m'aiderais beaucoup...

      def test_victoire(p):
          for c in ((0,1,2),(3,4,5),(6,7,8),(0,3,6),(1,4,7),(2,5,8),(0,4,8),(2,4,6)):
              if p[c[0]]==p[c[1]]==p[c[2]]:
                  if p[c[0]]==1 : return 1
                  if p[c[0]]==2 : return 2
          return 0
      


      Cette fonction teste la victoire sur un plateau passé en argument. Le plateau est stocké sous forme d'une liste de 9 éléments, qui correspondent aux neufs cases :
      0 1 2
      3 4 5
      6 7 8


      La boucle for c in va faire prendre à la variable locale c chaque triplet. On teste alors si les valeurs stockées dans la liste-plateau sont égales sur l'une ou l'autre de ces positions, pour voir l'un des joueurs a gagné. On teste alors si c'est le joueur 1 ou le joueur 2 : il suffit de regarder le contenu d'une case, chaque coup joué par le joueur 1 (respectivement le joueur 2) remplit la case avec un 1 (respectivement un 2).

      Citation

      def MatchNul(p):
          nul=1
          for c in range(9):
              if p[c]==0:
                  nul=0
                  break
          return nul
      


      Cette fonction (pas très bien écrite, on aurait mieux fait d'utiliser un booléen ici) vérifie si l'une des cases du plateau est encore à 0. On initialise la variable nul à 1. Puis, pour chaque case du plateau (on retrouve une boucle for qui fait parcourir à c les valeurs de 0 à 8 inclus), si jamais une case est à 0, alors on stocke 0 dans la variable nul et on le renvoie. Si on ne trouve jamais de case de p à 0, alors nul vaudra 1 à la fin de la boucle, et on renverra donc 1.

      Il faut comprendre ici que les cases du plateau sont initialement remplies d'un 0 (avant que les joueurs ne jouent dedans). On veut voir ici si la partie est finie, ou s'il reste encore des coups : il ne peut rester de coups que s'il reste au moins une case libre, c'est à dire encore remplie d'un 0.


      Citation

      def Tree(p,j,compteur):
          for c in range(9):
              if p[c]==0 :
                  p[c]=j
                  t=test_victoire(p)
                  if t==j:
                      compteur=compteur+1
                  elif MatchNul(p)==1:
                      compteur=compteur+1
                  else :
                      compteur=Tree(p,3-j,compteur)
                  p[c]=0
          return compteur
      


      Cette fonction assez marrante va tester le nombre de combinaisons possibles pour le morpion. En fait, elle joue toutes les parties (255168 en tout) en remplissant la grille au fur et à mesure. Tu peux voir en effet que le plateau p est modifié par une boucle (mais seulement les cases vides, voir le test if p[c] == 0), qu'à chaque fois on teste la victoire du joueur qu'on est en train d'examiner, qu'on teste également un match nul, et que si ni l'une ni l'autre de ces conditions n'est remplie, on fait un appel récursif en changeant la valeur du paramètre j. C'est une petite astuce là encore : si j vaut 1, 3-j vaudra 2 (donc après avoir simulé un coup du joueur 1 on simule un coup du joueur 2), et réciproquement.

      La variable compteur est modifiée de façon à tenir le compte du nombre de parties. Un exercice intéressant pour toi serait d'utiliser non pas une mais 3 variables, qui serviraient à compter respectivement le nombre de matchs nuls, le nombre de victoires du joueur 1, et le nombre de victoires du joueur 2.

      Par curiosité, où as-tu trouvé ce code ?

      Citation

      print(Tree([0,0,0,0,0,0,0,0,0],1,0))


      Là on appelle la fonction de simulation sur un plateau initialement vide, en faisant commencer le joueur 1.

      Citation

      Je sais que c'est surement un programme super simple mais j'avoue que j'ai du mal...

      merci d'avance,

      Cordialement,



      Non, ça n'est pas un programme super simple. En particulier la dernière fonction demande d'avoir un peu d'expérience en programmation. Il ne faut pas te décourager si, malgré mes explications, tu n'as pas tout compris : essaye de faire des exemples avec un papier et un crayon, reviens nous poser des questions si nécessaire, et surtout essaye de modifier le code pour t'approprier sa logique (mieux la comprendre, savoir la réutiliser). Par contre, essaye aussi de ne pas trop te faire aider : je t'ai donné beaucoup d'explications ici, maintenant c'est à toi de faire tes propres expériences.

      C'est vraiment très bien d'essayer de comprendre ce bout de code. Même s'il n'est pas particulièrement bien écrit, il résout un problème intéressant qui, lorsque tu le maîtriseras vraiment, t'auras appris pas mal de choses sur la programmation.
      • Partager sur Facebook
      • Partager sur Twitter
        2 mai 2011 à 20:22:12

        Déja merci d'avoir pris le temps de me répondre.

        Citation

        La boucle for c in … va faire prendre à la variable locale c chaque triplet. On teste alors si les valeurs stockées dans la liste-plateau sont égales sur l'une ou l'autre de ces positions, pour voir l'un des joueurs a gagné. On teste alors si c'est le joueur 1 ou le joueur 2 : il suffit de regarder le contenu d'une case, chaque coup joué par le joueur 1 (respectivement le joueur 2) remplit la case avec un 1 (respectivement un 2).



        Ce que j'ai un peu de mal à comprendre,c'est que c va prendre le triplet ou l'element de la liste ?
        par exemple quand on fais :

        Citation

        if p[c[0]]==1 : return 1
        if p[c[0]]==2 : return 2


        on regarde par exemple si (1,1,1 ) ou ( 2,2,2 ) ?

        Citation

        Cette fonction (pas très bien écrite, on aurait mieux fait d'utiliser un booléen ici) vérifie si l'une des cases du plateau est encore à 0. On initialise la variable nul à 1. Puis, pour chaque case du plateau (on retrouve une boucle for qui fait parcourir à c les valeurs de 0 à 8 inclus), si jamais une case est à 0, alors on stocke 0 dans la variable nul et on le renvoie. Si on ne trouve jamais de case de p à 0, alors nul vaudra 1 à la fin de la boucle, et on renverra donc 1.

        Il faut comprendre ici que les cases du plateau sont initialement remplies d'un 0 (avant que les joueurs ne jouent dedans). On veut voir ici si la partie est finie, ou s'il reste encore des coups : il ne peut rester de coups que s'il reste au moins une case libre, c'est à dire encore remplie d'un


        Le match nul,je pense l'avoir assimiler.

        def Tree(p,j,compteur):
            for c in range(9):
                if p[c]==0 :
                    p[c]=j
                    t=test_victoire(p)
                    if t==j:
                        compteur=compteur+1
                    elif MatchNul(p)==1:
                        compteur=compteur+1
                    else :
                        compteur=Tree(p,3-j,compteur)
                    p[c]=0
            return compteur
        

        Celle la j'avoue que j'ai un peu de mal surtout à voir comment des milliers de possibilités sont testé dans cette simple boucle =S
        En faite j'étais absent à un cours et il y avais deux exercices : un morpion et à "5 à la suite" à faire,
        Le prof a fais sa correction.
        En plus quand je vois le code suivant pour le jeux "5 à la suite",j'ai envie de courrir vers la porte quoi --'


        (w,h)=eval(input("Dimension de la grille :"))
        
        tab=[[]]*w
        for i in range(w):
            tab[i]=[0]*h
                
        def affichage (w,h,tab):
            for i in range(w):
                print(tab[i])
            
        def jouer(w,h):
           affichage(w,h,tab)
           for c in range(w*h):
               y,x=0,0
               while True:
                   y,x=eval(input("Votre position : "))
                   if 0<=y<h and 0<=x<w and tab[y][x]==0:break
               tab[y][x]=2*(c&1)-1
               affichage(w,h,tab)
               if test_victoire(lines,tab):break
        
        
        def alignements(w,h):
            return[((i,j),(0,1))for i in range(h) for j in range(w-4)]+\
                  [((i,j),(1,0))for i in range(h-4)for j in range(w)]+\
                  [((i,j),(1,1))for i in range(h-4)for j in range(w-4)]+\
                  [((i,j),(1,-1))for i in range(h-4)for j in range(4,w)]
        
        lines=alignements(w,h)
        
        def test_victoire(lines,tab):
            for((y,x),(b,a)) in lines :
                if abs(sum([tab[y+i*b][x+i*a]for i in range(5)]))==5:
                     return True
            return False
        
        jouer(w,h)
        


        Enfin bon...Je vais essayer de regarder les cours du site du zero et de re regarder le programme mais j'avoue que c'est assez difficile pour moi.

        Merci beaucoup à vous!
        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          2 mai 2011 à 21:32:00

          Citation

          Ce que j'ai un peu de mal à comprendre,c'est que c va prendre le triplet ou l'element de la liste ?



          rectification: c[0] indique l'index 0 du tuple c et p[c[0]] indique que l'index de p est c[0]

          Ce code est affreusement moche et illisible et si tu ne comprends pas c'est normal, c'est parce-que ce code ne mérite même pas de commentaires.

          Citation

          Le prof a fais sa correction.



          C'est un prof qui a fait ce code?
          • Partager sur Facebook
          • Partager sur Twitter
            3 mai 2011 à 9:47:20

            Citation : lifetor

            Déja merci d'avoir pris le temps de me répondre.

            Citation

            La boucle for c in … va faire prendre à la variable locale c chaque triplet. On teste alors si les valeurs stockées dans la liste-plateau sont égales sur l'une ou l'autre de ces positions, pour voir l'un des joueurs a gagné. On teste alors si c'est le joueur 1 ou le joueur 2 : il suffit de regarder le contenu d'une case, chaque coup joué par le joueur 1 (respectivement le joueur 2) remplit la case avec un 1 (respectivement un 2).



            Ce que j'ai un peu de mal à comprendre,c'est que c va prendre le triplet ou l'element de la liste ?
            par exemple quand on fais :

            Citation

            if p[c[0]]==1 : return 1
            if p[c[0]]==2 : return 2


            on regarde par exemple si (1,1,1 ) ou ( 2,2,2 ) ?



            Il faut que tu fasses tes propres expériences pour avancer. Je te conseille par exemple de lancer un shell Python (via IDLE ou n'importe quoi, pour avoir une ligne de commande interactive Python) et d'essayer ceci :

            for c in ((0,1,2),(3,4,5),(6,7,8),(0,3,6),(1,4,7),(2,5,8),(0,4,8),(2,4,6)):
                print c
            



            Citation


            def Tree(p,j,compteur):
                for c in range(9):
                    if p[c]==0 :
                        p[c]=j
                        t=test_victoire(p)
                        if t==j:
                            compteur=compteur+1
                        elif MatchNul(p)==1:
                            compteur=compteur+1
                        else :
                            compteur=Tree(p,3-j,compteur)
                        p[c]=0
                return compteur
            


            Celle la j'avoue que j'ai un peu de mal surtout à voir comment des milliers de possibilités sont testé dans cette simple boucle =S



            Remarque l'appel récursif… c'est lui qui fait tout. La boucle elle-même sert à marquer les positions sur le plateau les unes après les autres (p[c]=j), à tester la victoire ou le match nul (auquel cas on n'a pas d'autre coup à simuler), à explorer récursivement les coups suivants en changeant de joueur (Tree(p,3-j,compteur)) puis à enlever le coup marqué au début : p[c]=0.

            Tu comprends ? On marque un PREMIER coup pour le joueur j, on simule les coups suivants pour l'autre joueur, puis on retire ce PREMIER coup, et la boucle fait qu'on recommence avec un autre PREMIER coup à un autre endroit.

            Citation

            En faite j'étais absent à un cours et il y avais deux exercices : un morpion et à "5 à la suite" à faire,
            Le prof a fais sa correction.
            En plus quand je vois le code suivant pour le jeux "5 à la suite",j'ai envie de courrir vers la porte quoi —'



            Bah, faut pas. Tu as de la chance d'étudier des problèmes concrets et rigolos dans un langage sympa comme Python, et comme je te l'ai dit, en comprenant véritablement comment marchent ces solutions tu auras appris beaucoup de choses sur la programmation.

            Citation

            Merci beaucoup à vous!



            Bon courage à toi !
            • Partager sur Facebook
            • Partager sur Twitter
              4 mai 2011 à 16:29:28

              Citation

              C'est un prof qui a fait ce code?



              Oui


              Okey je vous remercie,je vais me replonger dedans et essayer de comprendre!
              En tout cas merci,à vous :)

              EDIT:
              def test_victoire(p):
                  for c in ((0,1,2),(3,4,5),(6,7,8),(0,3,6),(1,4,7),(2,5,8),(0,4,8),(2,4,6)):
                      if p[c[0]]==p[c[1]]==p[c[2]]:
                          if p[c[0]]==1 : return 1
                          if p[c[0]]==2 : return 2
                  return 0
              


              En faite si (0,1,2) qui sont les positions gagnantes du morpion sont remplies de 1,alors p va prendre en compte cela et donc indiquer un return 1,et donc 1 gagnant ? ((1,1,1),(0,0,0),(1,2,0)...) par exemple ,donc lors de la boucle c[0] va prendre la premier tuple : (1,1,1) et donc p[c[0]]==1 car les 3 éléments sont egaux avec comme valeur 1 ?

              Citation

              Remarque l'appel récursif… c'est lui qui fait tout. La boucle elle-même sert à marquer les positions sur le plateau les unes après les autres (p[c]=j), à tester la victoire ou le match nul (auquel cas on n'a pas d'autre coup à simuler), à explorer récursivement les coups suivants en changeant de joueur (Tree(p,3-j,compteur)) puis à enlever le coup marqué au début : p[c]=0.

              Tu comprends ? On marque un PREMIER coup pour le joueur j, on simule les coups suivants pour l'autre joueur, puis on retire ce PREMIER coup, et la boucle fait qu'on recommence avec un autre PREMIER coup à un autre endroit.


              mais le for pourquoi il va de 0 à 9,en fait pourquoi on ne recommence que 9 fois ?

              merci
              • Partager sur Facebook
              • Partager sur Twitter
                4 mai 2011 à 17:36:36

                Parce qu'on simule les 9 coups différents du joueur 1 au tour 1. Ça n'est que dans l'appel récursif que l'on va jouer d'autres coups à partir de ces configurations là. Déroule les appels à la main pour mieux comprendre.
                • Partager sur Facebook
                • Partager sur Twitter

                Ne comprend pas le code

                × 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