Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Puissance 4] Algo de verification de diagonales ...

Verifier si 4 pions sont alignés en diagonales !

Sujet résolu
    3 mai 2011 à 11:52:28

    Bonjour,
    J'ai en tête de créer un petit jeu de puissance 4 jouable a 2 joueurs a tour de rôle et je bute sur la verification de 4 pions alignés !
    Pour les lignes verticales et horisontales, j'ai trouver un moyen de les verifier, surement pas le meilleur mais fonctionnel !
    Par contre, je n'arrive pas a trouver un moyen de vérification pour les diagonales !
    Voici mon ébauche:
    #!/usr/bin/python
    #-*- coding: Utf-8 -*-
    
    class Puiss4(object):
        """Créer le tableau de jeu, ajoute et vérifie les pions"""
        def __init__(self):
            "Initialisation de la grille de jeu"
            self.jeu = [ ["0"]*6 for _ in range(7)] # Création de la grille de jeu
    
        def ajoutPion(self, couleur, colone):
            for ligne in xrange(7):
                if self.jeu[colone][ligne] == "0":
                    self.jeu[colone][ligne] = couleur
                    break
    
        def verif(self):
            # Verification des colones
            colones = [""]*7
            for n in xrange(7):
                colones[n] = colones[n].join(self.jeu[n])
                print colones[n] # Pour tester !
            for e in colones:
                if "RRRR" in e:
                    print "Rouge a gagné !"
                if "JJJJ" in e:
                    print "Jaune a gagné !"
            # Verification des lignes
            lignes = [""]*6
            for element in colones:
                for n in xrange(6):
                    lignes[n] = lignes[n] + element[n]
            for e in lignes:
                if "RRRR" in e:
                    print "Rouge a gagné !"
                if "JJJJ" in e:
                    print "Jaune a gagné !"
                print e # Pour tester !
            # Verification des diagonales
    


    sinon, qu'est ce que vous penser d'utiliser un dictionnaire et de le comparer dirrectement aux 69 possibilités de gagner la partie ?
    Merci de votre aide !
    • Partager sur Facebook
    • Partager sur Twitter
      3 mai 2011 à 12:32:48

      perso j'en ai fait un en créant 4 grilles: verticale, horizontale et une pour chaque diagonale ...
      quand on pose un pion, on remplit chacune des grilles; c'est facile à checker ensuite ...
      class Puissance4:
          """
          Puissance4 possede:
          
          1 methode: put_pawn()
          les appels succesifs a put_pawn() font jouer tour a tour tant que Run est True.
          
          5 attributs qui permettent d'implementer une GUI: Player, Winner, Pawn, Grid et Winlist.
          Player, Winner et Pawn ne sont pas essentiels mais apportent une indiquation sur le deroulement du jeu.
          Player est le numero du joueur en cours, vaut 1 ou 2.
          Winner vaut None tant qu'il n'y a pas de gagnant, sinon vaut Player et suspend le deroulement normal de put_pawn().
          Pawn est le pion du joueur en cours.
          Grid est une liste de bytearray qui represente la grille de jeu lue horizotalement (voir la doc bytearray).
          Grid servira donc pour une interface graphique.
          exemple pour une grille 5x3:
          Grid=
          [
          b'00000',
          b'00000',
          b'00000'
          ]
          Winlist ; c'est la liste des coordonnees des pions places gagnant dans Grid.
          """    
          def __init__(self,Width,Height,Align,Empty,PawnJ1,PawnJ2):
              """
              le jeu s'initialise ainsi:
              Width et Height indiquent la taille de la grille de jeu, soit la largeur et la hauteur.
              Align indique le nombre de pions a aligner pour gagner.
              Empty,PawnJ1 et PawnJ2 sont 3 caracteres correspondant a:
              case vide, pion du 1er joueur et pion du 2nd joueur...
              vous pouvez indiquer une valeur numerique, par exemple, si vous voulez
              que 0 represente case vide:
              Empty = '\0'
              """
              self.Align = Align
              self.Pawns = [PawnJ1,PawnJ2]
              self.Empty = Empty
              self.Winner = None
              self.Run = True
              self.Shots = Width*Height
              self.Player = 1
              self.Pawn = self.Pawns[0]
              self.Winlist = ([],[],[],[])
              self.Grid = [bytearray(self.Empty*Width) for _ in range(Height)]
              self.Grid_verti = [bytearray(self.Empty*Height) for _ in range(Width)]
              self.Grid_diag1 = [bytearray(self.Empty*(Height)) for _ in range(Width+Height-1)]
              self.Grid_diag2 = [bytearray(self.Empty*(Height)) for _ in range(Width+Height-1)]
      
          def put_pawn(self,Column):
              """
              l'argument Column indique la colonne dans laquelle le joueur veut poser son pion.
              put_pawn() maintient Player, Pawn et Winner qui indiquent quel joueur joue ou va jouer ...
              et s'il y a un gagnant.
              """
              if self.Run:
                  try:
                      y = self.Grid_verti[Column].rindex(self.Empty)
                  except: return
                  
                  self.Shots -= 1
                  
                  self.Grid[y][Column] = self.Pawn
                  pos = self.Grid[y].find(self.Align*self.Pawn)
                  if pos > -1:
                      self.Winner = self.Player
                      self.Run = False
                      while self.Grid[y][pos:pos+1] == self.Pawn:
                          self.Winlist[0].append((pos,y))
                          pos+=1      
                  
                  self.Grid_verti[Column][y] = self.Pawn
                  pos = self.Grid_verti[Column].find(self.Align*self.Pawn)
                  if pos > -1:
                      self.Winner = self.Player
                      self.Run = False
                      while self.Grid_verti[Column][pos:pos+1] == self.Pawn:
                          self.Winlist[1].append((Column,pos))
                          pos+=1
                  
                  diag = y+Column
                  self.Grid_diag1[diag][y] = self.Pawn
                  pos = self.Grid_diag1[diag].find(self.Align*self.Pawn)
                  if pos > -1:
                      self.Winner = self.Player
                      self.Run = False
                      while self.Grid_diag1[diag][pos:pos+1] == self.Pawn:
                          self.Winlist[2].append((diag-pos,pos))
                          pos += 1
      
                  diag = Column-y+len(self.Grid)-1
                  self.Grid_diag2[diag][y] = self.Pawn
                  pos = self.Grid_diag2[diag].find(self.Align*self.Pawn)
                  if pos > -1:
                      self.Winner = self.Player
                      self.Run = False
                      while self.Grid_diag2[diag][pos:pos+1] == self.Pawn:
                          self.Winlist[3].append((Column-y+pos,pos))
                          pos += 1
                          
                  if not self.Shots: self.Run = False
                  if self.Run:
                      self.Pawns.reverse()
                      self.Pawn = self.Pawns[0]
                      self.Player = (not self.Player-1)+1
      
      #***************************************************************************************************************
      #***************************************************************************************************************
      # exemple en mode console
      if __name__ == '__main__':
          # routine qui affiche la grille
          def showgrid():
              print ' A B C D E F G'
              for _ in game.Grid:
                  print _.replace('','|')
                  print '---------------'
          # routine qui lit dans quelle colonne poser le pion
          askwhere = lambda: 'ABCDEFG'.index(raw_input("joueur "+str(game.Player)+" joue: ").upper())
          # arguments pour l'initialisation du jeu
          init = largeur,hauteur,alignement,case_vide,pion_joueur_1,pion_joueur_2 = 7,6,4,' ','x','o'
          
          game = Puissance4(*init) # init du jeu
          showgrid() # affichage de la grille
          while game.Run: # tant que c'est jouable ...
              game.put_pawn(askwhere()) # poser un pion
              showgrid() # affichage de la grille
          print "joueur "+str(game.Winner)+" gagne!" if game.Winner else "personne ne gagne"
          print game.Winlist
      

      il manquerait une variable qui indique la position du pion qui vient d'être posé pour faciliter la mise en place d'une GUI ... mais c'est jouable.
      • Partager sur Facebook
      • Partager sur Twitter

      Python c'est bon, mangez-en. 

        3 mai 2011 à 14:44:11

        Merci pour l'info, je vais surement essayé de faire la même chose pour mes diagonales.
        @ +++
        • Partager sur Facebook
        • Partager sur Twitter
          3 mai 2011 à 15:08:32

          Citation : Darioo2


          J'ai en tête de créer un petit jeu de puissance 4 jouable a 2 joueurs



          Classique, par exemple posé sur Prologin DF 2003 :





          LIN=6
          COL=7
          
          # capture du plateau par lignes
          lignes=["".join(raw_input().split()) for lin in range(LIN)]
          
          colonnes=[[lignes[lin][col] for lin in range(LIN)] for col in range(COL)]
          colonnes=["".join(col) for col in colonnes]
          
          diagM=[[] for  i in range(LIN+COL-1)]
          for lin in range(LIN):
              for col in range(COL):
                  diagM[lin + col]+=[lignes[lin][col]]
          diagM=["".join(d) for d in diagM]
          
          diagD=[[] for  i in range(-COL,LIN)]
          for lin in range(LIN):
              for col in range(COL):
                  diagD[COL-1+lin - col]+=[lignes[lin][col]]
          diagD=["".join(d) for d in diagD]
                  
          t=lignes[::-1]+colonnes[::-1]+diagM+diagD
          
          def estPresent(t,c1,c2):
              c1=4*str(c1)
              c2=4*str(c2)
              for z in t:
                  for c in (c1,c2):
                      if c in z:
                          return c[0]
              return 0
          
          print estPresent(t,1,2)
          


          Je l'ai écrit il y a environ 2 ans quand j'ai commencé Python donc le code n'est peut-être pas parfait. Sinon, c'est l'algo naïf, sans prise de tête : pour les quatre directions

          verticale, horizontale, diagonale montante et diagonale descendante


          on construit une listes de listes (ou de chaînes plutôt il me semble) et tout simplement on demande à Python de rechercher 4 jetons consécutifs monocolores. C'est aussi à quelques détails près l'algo de josmiley avec la méthode find.


          Je suis sûr que du point de vue de l'exécution, ce type d'algo convient parfaitement bien que ce ne soit pas du tout optimisé. Un bon algo est capable de déceler immédiatement la présence d'un configuration gagnante sans tout recalculer (sans même devoir stocker à part les lignes verticales, horizontales et diagonales). Pour commencer une IA, ce serait le minimum à mon avis. Mais comme disent Kernighan et Pike : Don't optimize what doesn't matter.
          • Partager sur Facebook
          • Partager sur Twitter
            3 mai 2011 à 23:55:40

            me suis amusé à faire un oneline avec l'exemple du prologin ...
            grid = ['0010000','0022000','0121000','0221000','2212100','1211210']
            print max([max(['1' if '1111' in l else '2' if '2222' in l else '0' for l in g]) for g in grid,[''.join(l) for l in zip(*grid)],[''.join(l) for l in zip(*['0'*x+l+'0'*(len(grid)-x) for x,l in enumerate(grid)])],[''.join(l) for l in zip(*['0'*(len(grid)-x)+l+'0'*x for x,l in enumerate(grid)])]])
            

            aucun intérêt, c'est pour le fun ...
            • Partager sur Facebook
            • Partager sur Twitter

            Python c'est bon, mangez-en. 

              4 mai 2011 à 17:21:45

              Bonjour,
              Merci pour vos réponses, j'ai réussis a finir mon algo pour les diagonales, il reste 2 ou 3 trucs a améliorer dans le code mais la méthode de vérification est opérationelle !
              #!/usr/bin/python
              #-*- coding: Utf-8 -*-
              
              class Puiss4(object):
                  """Créer le tableau de jeu, ajoute et vérifie les pions"""
                  def __init__(self):
                      "Initialisation de la grille de jeu"
                      self.jeu = [ ["0"]*6 for _ in xrange(7)] # Création de la grille de jeu
                      self.gagnant = None
              
                  def affichage(self): # Pour le mode console !
                      "Affiche le puissance4 en mode console"
                      print "\n| 1 | 2 | 3 | 4 | 5 | 6 | 7 |"
                      print "-----------------------------"
                      for n in xrange(5, -1, -1):
                          ligne = "| "
                          for n2 in xrange(7):
                              ligne = ligne + self.jeu[n2][n] + " | "
                          print ligne
                                      
                  def ajoutPion(self, couleur, colone):
                      for ligne in xrange(7):
                          if "0" in self.jeu[colone]:
                              if self.jeu[colone][ligne] == "0":
                                  self.jeu[colone][ligne] = couleur
                                  break
              
                  def verif(self):
                      # Verification des colones
                      colones = [""]*7
                      for n in xrange(7):
                          colones[n] = colones[n].join(self.jeu[n])
                      for e in colones:
                          if "RRRR" in e:
                              self.gagnant = "Rouge"
                          if "JJJJ" in e:
                              self.gagnant = "Jaune"
                              
                      # Verification des lignes
                      lignes = [""]*6
                      for element in colones:
                          for n in xrange(6):
                              lignes[n] = lignes[n] + element[n]
                      for e in lignes:
                          if "RRRR" in e:
                              self.gagnant = "Rouge"
                          if "JJJJ" in e:
                              self.gagnant = "Jaune"
                          
                      # Verification des diagonales
                      for y in xrange(3):
                          for x in xrange(4):
                              diag = ""
                              for xx in xrange(4):
                                  diag = diag+self.jeu[x+xx][y+xx]
                              if diag == "RRRR":
                                  self.gagnant = "Rouge"
                              elif diag == "JJJJ":
                                  self.gagnant = "Jaune"
                      for y in xrange(3):
                          for x in xrange(3, 7):
                              diag = ""
                              for xx in xrange(4):
                                  diag = diag+self.jeu[x-xx][y+xx]
                              if diag == "RRRR":
                                  self.gagnant = "Rouge"
                              elif diag == "JJJJ":
                                  self.gagnant = "Jaune"
              
                  def victoire(self, couleur, coords): # A completer !
                      "Détermine le gagnant et localise la combinaison gagnante"
                      pass
              
              if __name__ == "__main__":
                  partie = Puiss4()
                  while 1:
                      partie.affichage()
                      rouge =raw_input("\n\nJoueur Rouge inserez un jeton dans une des colones: ")
                      partie.ajoutPion("R", int(rouge)-1)
                      partie.verif()
                      if partie.gagnant:
                          break
                      partie.affichage()
                      jaune = raw_input("\n\nJoueur Jaune inserez un jeton dans une des colones: ")
                      partie.ajoutPion("J", int(jaune)-1)
                      partie.verif()
                      if partie.gagnant:
                          break
              
                  print u"\nJoueur", partie.gagnant, "gagne !!!\n"
                  raw_input("Appuyez sur <Entrez> pour quitter la partie !")
              

              Merci pour vos exemples, je les ai lu avec beaucoup d'intéret !
              @ +++
              • Partager sur Facebook
              • Partager sur Twitter

              [Puissance 4] Algo de verification de diagonales ...

              × 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