Tirage aléatoire en fonction d'un nombre

Bonjour
je veux développer un programme de bridge 52 cartes et j'aimerais trouver un moyen de faire un tirage d'une donne en fonction d'un nombre.
Mais le nombre saisi donnera toujours la même donne.

Je m'explique, j'aimerais qu'un nombre saisi donne toujours la même donne.
Et le top serait qu'une donne aléatoire (ou même une donne saisie) me donne un no de donne.

Merci de votre aide.

Réponses

  • Bonjour.

    Il y a de nombreuses façons d'associer à une donne un nombre tel que des donnes différentes correspondent à des nombres différents. Mais en général, un nombre pris au hasard, même de la bonne taille, ne correspondra à aucune donne.
    par exemple, on numérote les cartes trèfle de 1 à 13 (1 pour l'as, 13 pour le roi), puis carreau de 14 à 26 (14 pour l'as, 15 pour le 2, ..26 pour le roi), puis les cœurs de 27 à 39 et les piques de 40 à 52. Une donne est définie quand on connaît les cartes de trois joueurs (donc ceux qui ne sont pas le donneur) dans l'ordre de ces trois joueurs (échanger des jeux correspond à une autre donne). Par exemple supposons que le premier a 7,8,V à trèfle, 1, 2,5 à carreaux, etc. On construit la suite 07,08,11,14,15, 18,... qu'on transforme en le nombre 070811141518... A partir du nombre, on peut retrouver la donne. Mais :
    * C'est un nombre à 78 chiffres. On peut en réduire le nombre de chiffres, mais il faudra un traitement mathématique.
    * la plupart des nombres de 78 chiffres ne sont pas associés à des donnes. Par exemple 070711141518... n'est pas un nombre associé à une donne, 10125442... non plus.

    Une solution possible est de faire une table de toutes les donnes possibles (je te laisse les compter) numérotées par leur place dans la table, et de tirer au hasard dans les numéros de la table.

    Cordialement.

    NB : On sait parfaitement tirer des donnes au hasard. En particulier avec un jeu de 52 cartes ;-)
  • On peut réduire en utilisant la base factorielle qui permet de numéroter les permutations.
    Ça réduit le nombre de cas à 52!=80658175170943878571660636856403766975289505440883277824000000000000 (qui a 68 chiffres).
    Mon premier script est faux.

    Voici un script qui te permet de calculer la permutation associée à un nombre :
    def num2perm(n,f):
      p=1
      while p<n:#fact(f)<n:
        f+=1
        p*=f
      p=list(range(f))
      f-=1
      l=[]
      while p:#len(p)>1:
        e,n=divmod(n,fact(f))
        l.append(p.pop(e))
        f-=1
      return l
    

    Et un script réciproque :
    def perm2num(p):
      pp=list(p)
      p1=sorted(p)
      r=0
      for i in range(len(pp)):
        d=p1.index(pp[ i])
        r+=d*fact(len(pp)-i-1)
        del p1[d]
      return r
    
    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
  • def permute(t: 'iterable', k: int) -> 'iterable': 
        """Renvoie la k-ème permutation de l'objet itérable t."""
    
        n = len(t)
        p = math.factorial(n)
        for i in range(n, 0, -1):
            k %= p
            p //= i
            q = k // p
            t = t[: q] + t[q + 1:] + t[q: q + 1]
        return t
    
    Si on part de l'objet "t" qui est la liste des 52 cartes alors chaque nombre entier entre 1 et 52! donnera une permutation différente de cette liste, toujours la même.
  • Le nombre de donnes différentes est plus faible que ça, c'est $\frac{52!}{13!^4}$
    Ce qui donne un nombre à 29 chiffres.
    A ça, il faudrait ajouter 2 informations : qui est donneur et qui est vulnérable, ce qui revient à multiplier par 16.

    Pour la 1ère question, (et si on renonce à la 2ème question, savoir retrouver un n° à partir de la donne) les fonctions random ont une fonctionnalité pour ça. Il faut 'initialiser le hasard' (planter une graine avec un n° de ton choix), et une fois cette graine choisie, tu as un résultat figé.
    Le mot clé pour rechercher de la documentation sur ça , c'est ' RANDOM SEED'

    Pour la 1ème question (retrouver un n° à partir d'une donne), c'est beaucoup plus compliqué.
    Le fait qu'il n'y ait que (!) $5.36*10^{29}$ donnes n'est pas vraiment exploitable, il faut passer par ce qu'on appelle 'la base factorielle', et donc le code de bisam.
    Mais il faudra donc un nombre de 68 chiffres pour identifier une donne.

    Une solution simple, avec quelques défauts.
    Les cartes sont numérotées de 1 à 52 ( 1=le 2 de trèfle, 52 = l'as de pique)
    Tu prends un nombre du type : 1112223334441112223334441112223334441112223334441234
    -52 chiffres
    -que des chiffres entre 1 et 4
    - Chacun des chiffres 1 à 4 apparaît exactement 13 fois.
    Ce nombre dit que le joueur n°1 a les 2,3 et 4 de trèfle, le joueur n°2 a les 5,6 et 7 de trèfles etc etc.

    On peut réduire la longueur de ce nombre...
    Tu me dis, j'oublie. Tu m'enseignes, je me souviens. Tu m'impliques, j'apprends. Benjamin Franklin
  • Bonjour.

    Pardon, mais ça me semble beaucoup plus simple que cela. Il faut revenir au sens de cette quantité.

    On tire 13 cartes parmi 52, puis 13 parmi 39, puis 13 parmi 26 et les 13 dernières cartes tombent sous le sens. On obtient 53644737765488792839237440000 cas, effectivement. Mais tirer 13 parmi 52, c'est simplement se mettre à la ligne 52 du triangle de Pascal et chercher à atteindre la colonne 13 en partant du sommet. Autrement dit, pour chaque carte, on dit si on la prend ou si on ne la prend pas. Et il faut 13 "oui" à la fin et 39 "non". Ceci n'est jamais que l'écriture d'un nombre binaire de taille 52 dans le quel on doit avoir 13 "1" et 39 "0". Je fais remarquer que dans un système 64 bits, il est facile de considérer un entier de 52 bits...

    Après, si on veut brouiller les pistes, il suffit de faire une bijection de l'ensemble des nombres de 52 bits vers l'ensemble des nombres de 52 bits.

    Bonne chance.
    Ce site est fatigant. Les gens modifient sans cesse leurs messages passés, et on ne comprend plus rien à la discussion. Je suis nostalgique du temps où, si on postait une bêtise, on devait l'assumer. Et si on cite le passage pour l'ancrer, l'administrateur supprime en disant qu'on n'a pas besoin de recopier le message passé.
Connectez-vous ou Inscrivez-vous pour répondre.