Forum Programmation.python POKER :determiner si une main est une couleur ou non

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
0
29
août
2018

bonjour,
je souhaiterais déterminer si une main de 5 cartes est une couleur ou non grâce à un programme Python.
J'ai commencé ceci:

couleurs=['T','K','C','P']
def couleur(main):
"""
cherche si la main est est couleur ou non
"""
x=main.count("T")
print(x)
if x==5:
return True
else:
return False

PROBLEME rencontré :

estCOULEUR(['7 C', '9 T', 'R K', 'R C', '10 P'])
0
False
Python ne voit pas qu'il y a pourtant un T dans la liste et qui devrait être compté…

sauriez vous comment faire pour que Python réussise à compter le nombre de fois ou T et les autres couleurs apparaissent?

Merci!

  • # Revoir la méthode count

    Posté par  (site web personnel) . Évalué à 2.

    Salut,

    (pour la mise en page du code, voir la syntaxe de la coloration syntaxique avec les triples `)

    La méthode count() recherche exactement la valeur donnée, dans ton cas tu recherches T tout seul, or tu as des valeurs qui contiennent T mais pas tout seul. Il te faut donc compter le nombre de chaînes qui contiennent 'T'.
    Par exemple en passant par:

    maincoul = [x for x in main if 'T' in x]

    Et en testant ensuite la longueur de maincoul.

    Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN

    • [^] # Re: Revoir la méthode count

      Posté par  . Évalué à 2.

      Nommer la variable 'main' est une mauvaise idée. Ca prête à confusion avec l'anglais

      • [^] # Re: Revoir la méthode count

        Posté par  (site web personnel) . Évalué à 2. Dernière modification le 29 août 2018 à 14:44.

        Bah, si c'est son code à lui qui reste chez lui, il sait ce qu'il manipule.

        Si c'était pour diffuser, tout à fait d'accord.

        Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN

  • # Au niveau binaire

    Posté par  (site web personnel) . Évalué à 2. Dernière modification le 29 août 2018 à 12:08.

    J'aurai travaillé différemment (ce qui ne veut pas dire que ce que tu fais est mauvais) : il y a 52 cartes dans un jeu de poker, on peut donc représenter ça dans un entier de 64bits, chaque bit à 1 valant une carte.

    Tous les tests de combinaisons se font ensuite en comparant cet entier avec des masques de bits, des décalages de bits pour créer une main, et des « ou » logiques pour combiner la main d'un joueur avec les cartes communes.

    • [^] # Re: Au niveau binaire

      Posté par  (site web personnel) . Évalué à 5.

      Oui enfin là ce serait coder en python comme en C, l'intérêt est limité.

      • [^] # Re: Au niveau binaire

        Posté par  . Évalué à -1.

        en même temps coder en python, l'intérêt est limité ;)

        Blague à part en C j'aurais plutôt codé la couleur sur un char

        • les 4 premier bits : la couleur (masque)
        • les 4 suivants le chiffre de la carte

        ou à la rigueur sur 4 octets

        • les 4 premier bits : la couleur (masque)
        • les 13 derniers bits la valeur de la carte (et oui, on est à 17 bits, ce qui ne passe pas dans un short;

        Si on tiens au masque de bit pour que ça tienne dans un short, il faut considérer que l'absence de marqueur est une couleur, mais adieu les jeux de tarots.

        En python, il vaut mieux jouer avec des classes ou des paires ('T',7), voire utiliser des Enums https://docs.python.org/3/library/enum.htm , utiliser des caractères c'est moche

        Il ne faut pas décorner les boeufs avant d'avoir semé le vent

        • [^] # Re: Au niveau binaire

          Posté par  (site web personnel) . Évalué à 3. Dernière modification le 29 août 2018 à 17:30.

          Je ne vois pas trop l'utilité d'un masque de bits pour les couleurs, tu n'as besoin que de 2 bits pour coder 4 couleurs, et 4 bits pour les valeurs soit 6 bits pour une carte. Tu pourrais même coder une main de 5 cartes sur 30 bits et que ça tienne donc sur 4 octets (faut être un peu vicieux à ce stade tout de même, on perd en extensibilité).

          Pour ce qui est du python, j'utiliserais plutôt un NamedTuple pour faire des card.color et card.value.

  • # quinte

    Posté par  . Évalué à 1.

    Merci beaucoup pour vos réponses rapides, comment feriez vous aussi pour créer une liste de toutes les suites possibles d'une quinte(5 valeurs qui se suivent) pour calculer ensuite si la main proposée est une quinte?Le problème étant de dénombrer toutes les possibilités sans le faire à la main en commençant de la valeur 8 jusqu'à l'AS…

    • [^] # Re: quinte

      Posté par  . Évalué à 1.

      A froid comme ça, je te conseillerais de créer une méthode (is_quinte(list)) qui prend en paramètres une liste d'entier (la valeur de tes cartes) et qui renvoie True ou False.

      Dans un premier temps je trie la liste (il y a une méthode déjà prête en python)
      https://docs.python.org/3/tutorial/datastructures.html
      Ensuite je parcours la list et je regarde si le décalage entre l'élément n et l'élément n-1 est bien de 1. On retourne False dès que le décalage est différent de 1

      Si on arrive à la fin de la boucle sans avoir retourné false on return true.
      Par contre y a probablement plus opti et c'est en considérant que tu considère le valet comme un 11, la dame comme un 12, le roi comme un 13.

      Et il faut gérer le cas particulier de l'as (1 ou 14).

      • [^] # Re: quinte

        Posté par  . Évalué à 1.

        Est-il possible de faire une liste avec juste des valeurs et un espace vide pour mettre les couleurs de manière à dénombrer toutes les possibilités de quinte de la manière suivante :
        couleurs=['T','K','C','P']
        q=[((8,''),(9,''),(10,''),(V,''),(D,'')),((9,''),(10,''),(V,''),(D,''),(R,''),((10,''),(V,''),(D,''),(R,''))(A,''))]
        for c in couleurs:
        quintes=q+c
        print (quintes)

        • [^] # Re: quinte

          Posté par  (site web personnel) . Évalué à 1.

          C'est un peut plus compliqué que ça, mais c'est possible :

          couleurs = ['T', 'K', 'C', 'P']
          valeurs_quintes = [
               (8, 9, 10, 11, 12),
               (9, 10, 11, 12, 13),
               (10, 11, 12, 13, 14)
          ]
          for couleur in couleurs:
               for valeurs in valeurs_quintes:
                   quinte = [(v, couleur) for v in valeurs]
                   print(quinte)

          Matthieu Gautier|irc:starmad

          • [^] # Re: quinte

            Posté par  . Évalué à 2.

            Dans ce cas là on obtient que les quintes flush non?

    • [^] # Re: quinte

      Posté par  (site web personnel) . Évalué à 5. Dernière modification le 30 août 2018 à 14:35.

      Déjà pour savoir si une main est une suite (aussi appelée ­— plus rarement — quinte), je commencerais par ne pas créer la liste de toutes les quintes possible pour voir si celle-ci est dedans. Ça prend du temps de calcul inutile.

      Pour savoir si une main est une quinte, une manière simple est de donner une valeur numérique aux cartes non-numériques (valet, dame, roi, as), puis de les trier par valeur croissante. Si tu as un as dans la main, le traiter de manière spéciale (valeur 1 ou 14). Si toutes tes valeurs se suivent, alors tu as une suite. Si elles sont en plus d'une couleur unique (trèfle, pique, coeur, carreau), alors tu as une quinte flush.

      • [^] # Re: quinte

        Posté par  . Évalué à 1. Dernière modification le 30 août 2018 à 14:59.

        Effectivement cela parait logique, merci ! Mais par curiosité j'aurais bien aimé savoir comment définir toutes les quintes dans une liste à partir de 8 en prenant en compte justement les différentes couleurs possibles ;)

        • [^] # Re: quinte

          Posté par  . Évalué à 1.

          trois technique :

          bourin : génère toute les mains et filtre les suites

          moins bourin : observe la composition des suites, et comment est-ce qu'une suite de taille n peut être complétée pour en faire une suite de taille n+1 (c'est la solution canonique, récursive standard).

          Plus smart, plus générique probablement : considère une main avec une suite, quelles sont les opérations que tu peux y appliquer pour toujours avoir une suite ? Il faut ajouter à ça un ordre total sur les suites, et bim, tu peux te déplacer dans ton espace de suites. Tes opérations ce sera "décaler la suite de 1 dans le rang" et "décaler la suite de 1 dans la couleur" (en interprétant la séquence des couleur comme un nombre en base 4 par exemple).

      • [^] # Re: quinte

        Posté par  . Évalué à 1.

        J'aimerais bien utilisé la méthode du tri notamment avec la fonction sorted sauf que j'ai toujours les couleurs dans ma main et je ne vois pas trop comment trier que les valeurs …

        • [^] # Re: quinte

          Posté par  . Évalué à 1. Dernière modification le 30 août 2018 à 22:05.

          def QUINTE(main):
          """
          permet de savoir si la main est une quinte ou non
          """
          a=[(7,8,9,10,11),(8, 9, 10, 11, 12),(9, 10, 11, 12, 13),(10, 11, 12, 13, 14)]
          b=sorted(main)
          for k in range (len(a)):
          if b==a[k:k+4]:
          return 1
          else:
          return 0

          Python renvoie dans tous les cas 0…

          • [^] # Re: quinte

            Posté par  . Évalué à 1. Dernière modification le 31 août 2018 à 00:59.

            Il retourne 0 parce qu'il arrête après le premier test

            Il faut sortir le "else return 0" de la boucle, pour le mettre après.

            le programme fait "je teste toute les possibilité, si j'en trouve une qui marche, je peux retourner vrai, sinon, il faut que je continue, et c'est qu'une fois que j'ai fini que je peux retourner faux"

            • [^] # Re: quinte

              Posté par  . Évalué à 1. Dernière modification le 31 août 2018 à 09:27.

              même en sortant le return Python retourne encore et toujours 0….

              • [^] # Re: quinte

                Posté par  (site web personnel) . Évalué à 2. Dernière modification le 31 août 2018 à 10:31.

                L'indentation est significative en python, et lire un paté de code mal formatté ça ne donne pas très envie. Je te conseille déjà de lire l'Aide mémoire sur la syntaxe wiki situé sous le champ de rédaction de message. Le dernier exemple indique comment inclure du code (remplace ruby par python pour avoir la coloration syntaxique appropriée).

                def QUINTE(main):
                    """
                    permet de savoir si la main est une quinte ou non
                    """
                    a=[(7,8,9,10,11),(8, 9, 10, 11, 12),(9, 10, 11, 12, 13),(10, 11, 12, 13, 14)]
                    b=sorted(main)
                    for k in range (len(a)):
                        if b==a[k:k+4]:
                            return 1
                        else:
                            return 0

                C'est plus facile à lire, n'est-ce pas ?

                Bon, à partir de ça, on voit que tu as tout de même listé les suites possible, que tu tentes de boucler dessus… Sans savoir ce que contient main, c'est difficile de déduire le comportement. Ensuite si tu veux boucler sur les différentes suites possibles contenues dans a, tu peux faire for k in a pour itérer sur tous les n-uplets de la liste a.

                La notation la plus lisible et rapide reste néanmoins de te débrouiller pour avoir dans b un n-uplet trié correspondant à ta main, comme (9, 10, 11, 12, 13), puis de remplacer ta boucle par return b in a. L'opérateur in renvoie True si b est inclus dans a (c'est à dire que a contient b), et False sinon. Ainsi tu évites une boucle inutile, et tu utilises des types booléens qui sont faits pour ça plutôt que 0 et 1.

                • [^] # Re: quinte

                  Posté par  . Évalué à 1.

                  def estQUINTE(main):
                  """
                  renvoie un booléen indiquant si cette main est une "quinte" ou non
                  """
                  a=["7","8","9","10","11","8","9","10","11","12","9","10","11","12","13","10","11","12","13","14"]
                  b=sorted(main)
                  return b in a
                  if (b in a)==True:
                  *return 1
                  else :
                  *
                  return 0

                  sachant que je mets une main ainsi dans la console :
                  estQUINTE(['7 K', '8 T', '9 P', '10 T', '11 C'])
                  Python renvoie False…

                  • [^] # Re: quinte

                    Posté par  . Évalué à 1.

                    Ah, bien sûr :-)

                    >>> '7 K' == "7"
                    False
                    
                    • [^] # Re: quinte

                      Posté par  . Évalué à 1.

                      def estQUINTE(main):
                      """
                      renvoie un booléen indiquant si cette main est une "quinte" ou non
                      """
                      a=[(7,8,9,10,11),(8, 9, 10, 11, 12),(9, 10, 11, 12, 13),(10, 11, 12, 13, 14)]
                      b=sorted(main)
                      return b in a
                      if (b in a)==True:
                      return 1
                      else :
                      return 0

                      Je n'ai pas bien compris? Que devrais-je modifier ?

                      • [^] # Re: quinte

                        Posté par  . Évalué à 2. Dernière modification le 31 août 2018 à 16:07.

                        Les types sont importants, 1 n'est pas égal à "1" qui n'est pas non plus égal à "1 K".

                        le prédicat "in" de python va utiliser l'égalité, en fait, c'est pas exactement ce que tu veux, tu ne veux pas tenir compte de la couleur.

                        Je te propose de repartir du début, en prennant par exemple le type suivant pour les cartes :
                        une paire avec un entier qui représente la carte, et une chaine de caractère pour la couleur.
                        par exemple, pour le 7 de cœur.
                        (7,'C')

                        Maintenant, une main ça ressemble à [(7,'C'), (9,'P'), (11,'K'),…]

                        le truc, c'est que pour savoir si tu as une quinte, la couleur, on s'en fiche. Pour ce calcul particulier, on peut l'ignorer.

                        à partir d'une main, tu peux par exemple calculer une autre liste qui représente la main, mais dans laquelle tu as viré les couleurs. Et ensuite, tu pourra l'utiliser avec ta fonction estQuinte.

                      • [^] # Re: quinte

                        Posté par  (site web personnel) . Évalué à 2. Dernière modification le 31 août 2018 à 18:41.

                        Une nouvelle fois, utilise les options de formattage de code quand tu postes, l'indentation est importante !!!

                        Bon je ré-explique, l'opérateur in renvoie un booléen (donc True ou False). Du coup ceci n'est pas du tout nécessaire:

                        if (b in a)==True:
                            return 1
                        else :
                            return 0

                        Tu peux remplacer tout ce bloc par:

                        return b in a

                        Bon, ensuite, il semble que tu appelles:

                        estQUINTE(['7 K', '8 T', '9 P', '10 T', '11 C'])

                        Donc quand tu es dans estQUINTE, ton paramètre main vaut ['7 K', '8 T', '9 P', '10 T', '11 C'].
                        Les crochets définissent une liste. Si je tape dans un interpréteur python:

                        >>> main = ['7 K', '8 T', '9 P', '10 T', '11 C']
                        >>> type(main)
                        <type 'list'>
                        >>> type(main[0])
                        <type 'str'>

                        Il me dit que ton objet main est bien une liste, et que le premier élément main[0] est une chaîne de caractères (string).

                        Si je continue:

                        >>> b = sorted(main)
                        >>> b
                        ['10 T', '11 C', '7 K', '8 T', '9 P']

                        Voilà, tu lui as demandé de trier ta main, il l'a triée… Mais pas comme tu souhaites. Il a fait du tri de chaines de caractères (c'est ce que tu lui donnes). Du coup, 11 C vient avant 7 K parce il compare lettre par lettre, et que le 1 est avant 7. Il ne peut pas comprendre que c'est le nombre 11, puisque tu lui passes une chaîne et pas un nombre.

                        Maintenant si on séparait les deux information dans un tuple (valeur, couleur) comme j'avais proposé plus haut ? valeur est un entier, et couleur est un caractère parmi ['C', 'K', 'T', 'P'], comme tu fais actuellement.

                        Là je mets une main dans le désordre (sinon c'est pas drôle)

                        >>> main = [(11, 'K'), (8, 'T'), (9, 'P'), (10, 'T'), (7, 'C')]
                        >>> b = sorted(main)
                        >>> main
                        [(11, 'K'), (8, 'T'), (9, 'P'), (10, 'T'), (7, 'C')]
                        >>> b
                        [(7, 'C'), (8, 'T'), (9, 'P'), (10, 'T'), (11, 'K')]

                        Et voilà, la main a été triée d'après le premier champ du tuple: valeur. Maintenant ce qui va coincer c'est que tu ne peux pas comparer a et b directement. a ne contient que des valeurs, pas de couleurs. b contient valeurs et couleurs. Donc tu dois transformer b pour n'avoir que des valeurs aussi. Tu pourras ainsi comparer les deux objets en faisant ton b in a.

                        • [^] # Re: quinte

                          Posté par  . Évalué à 1.

                          >def estQUINTE(main):
                              """
                              renvoie un booléen indiquant si cette main est une "quinte" ou non
                              """
                              a=[(7,8,9,10,11),(8, 9, 10, 11, 12),(9, 10, 11, 12, 13),(10, 11, 12, 13, 14)]
                              b=sorted(main) #tester une main de type tuple (valeur,couleur) avec valeur un entier et couleur une lettre :[(7, 'C'), (8, 'T'), (9, 'P'), (10, 'T'), (11, 'K')] 
                              del b['C'] 
                              del b['T'] 
                              del b['K'] 
                              del b['P']
                              return b in a
                          
                           Bien sur cela ne marche pas, je ne vois pas comment supprimer des éléments sans supprimer le chiffre avant... Et désolé pour la mise en page des derniers messages!
                          • [^] # Re: quinte

                            Posté par  (site web personnel) . Évalué à 3. Dernière modification le 03 septembre 2018 à 12:15.

                            >>> main = [(11, 'K'), (8, 'T'), (9, 'P'), (10, 'T'), (7, 'C')]
                            >>> b = sorted(main)
                            >>> b
                            [(7, 'C'), (8, 'T'), (9, 'P'), (10, 'T'), (11, 'K')]
                            >>> del b['C']
                            Traceback (most recent call last):
                              File "<stdin>", line 1, in <module>
                            TypeError: list indices must be integers, not str

                            Lis les messages d'erreur, ils sont là te guider. Apprends aussi à décrire ton problème au lien de dire "ça ne marche pas". Bien souvent, mieux formuler ton problème te permettra de le comprendre et souvent de trouver la solution par toi même.

                            Bon, revenons à nos moutons. Tu as donc dû avoir ce message d'erreur:

                            TypeError: list indices must be integers, not str

                            Traduction:

                            Erreur de type: les index de listes doivent être des entiers, et pas des chaînes de caractères.

                            C'est parce que dans une liste, les éléments sont ordonnés et accessibles par indice (leur position dans la liste): indice → valeur. Tu peux donc accéder à b[0], mais pas à b['C'].

                            Exemple: effacer le 3ème élément d'une liste

                            >>> my_list = [1, 2, 3, 4]
                            >>> my_list
                            [1, 2, 3, 4]
                            >>> del my_list[2]
                            >>> my_list
                            [1, 2, 4]

                            Les indices commencent à 0, donc le 1 se trouve à l'indice 0, le 2 se trouve à l'indice 1, le 3 se trouve à l'indice 2, et le 4 se trouve à l'indice 3. En demandant d'effacer l'élément à l'indice 2 avec del my_list[2], tu supprimes donc la valeur 3 de la liste.

                            En revanche, dans un tableau associatif, les éléments ne sont pas ordonnés (l'ordre n'est pas conservé), et sont accessibles par une clé. La clé peut être du type que tu veux, et te permet d'accéder à la valeur associée: clé → valeur.

                            Exemple ici avec un tableau associatif utilisant une chaîne de caractères comme clé. Voici comment supprimer la valeur 'coeur' du tableau.

                            >>> couleur = {'C': 'coeur', 'K': 'carreau', 'T': 'trèfle', 'P': 'pique'}
                            >>> couleur
                            {'K': 'carreau', 'T': 'trèfle', 'C': 'coeur', 'P': 'pique'}
                            >>> del couleur['C']
                            >>> couleur
                            {'K': 'carreau', 'T': 'trèfle', 'P': 'pique'}

                            Revenons à ton problème. Ce que tu veux faire toi, c'est supprimer la couleur pour chaque carte de la main triée b. del b[0] ne fonctionnera pas, parce que b est une main, pas une carte. del b[0] supprimerait juste la première carte de la main triée.

                            Je te conseille aussi avant d'aller plus loin de lire des tutoriels python, parce tu ne maîtrises pas les types de base du langage (listes, chaînes, tuples tableaux associatifs, etc.), ce qui te limite forcément. Autre chose, si tu veux voir les opérations possibles sur un objet, fais utilise la commande help. help(b) ou help(list) (puisque b est de type list) te donnera la liste des méthodes de b.
                            https://docs.python.org/fr/3.5/tutorial/introduction.html

  • # Commentaire supprimé

    Posté par  . Évalué à -3. Dernière modification le 31 août 2018 à 10:40.

    Ce commentaire a été supprimé par l’équipe de modération.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.