Rien de tel qu'un bon vieux jeu de ModTen

27

Avertissement: ModTen est un jeu de cartes fictif qui a été créé dans le seul but de ce défi.

Les règles de ModTen

ModTen se joue avec un jeu de 52 cartes standard. Parce que les règles complètes n'ont pas encore été inventées, nous allons nous concentrer exclusivement sur le classement des mains.

Jack & Three, adapté

Une main gagnante dans ModTen. Graphiques de Wikipedia .

Valeurs des cartes

Les cartes ont les valeurs suivantes:

  • 2 à 9 : valent leur valeur nominale
  • Dix : 0 point
  • Jack : 3 points
  • Reine ou roi : 8 points
  • As : 9 points

Valeurs des mains

  • Une main ModTen est composée de deux cartes . La valeur de base d'une main est obtenue en multipliant la valeur des deux cartes ensemble et en gardant le dernier chiffre uniquement (c'est-à-dire en appliquant un modulo 10).

    6(7×8)moddix=6

  • La seule autre règle de ModTen est que les cartes adaptées valent plus que les cartes non adaptées. Par convention, nous allons ajouter un "s" à la valeur si les deux cartes sont de la même couleur.

    Par exemple, la valeur de 9 ♠ - 5 ♠ sera notée comme " ", car et les cartes conviennent.5s(9×5)moddix=5

Classement des mains et vainqueur

Les règles ci-dessus donnent 18 rangs de mains distincts qui sont résumés dans le tableau suivant, du plus fort au plus bas (ou du plus rare au plus courant). Les probabilités sont données à titre indicatif.

Étant donné deux mains, la main avec le rang le plus bas gagne. Si les deux mains sont du même rang, alors c'est un match nul (il n'y a pas de bris d'égalité).

 hand rank | hand value(s) | deal probability
-----------+---------------+------------------
     1     | 9s            | 0.30%
     2     | 3s            | 0.60%
     3     | 1s            | 0.90%
     4     | 7s            | 1.21%
     5     | 5s            | 1.51%
     6     | 3             | 1.81%
     7     | 9             | 2.26%
     8     | 8s            | 2.71%
     9     | 6s            | 3.02%
    10     | 1 or 7        | 3.62% each
    11     | 2s or 4s      | 3.92% each
    12     | 5             | 4.98%
    13     | 0s            | 5.43%
    14     | 8             | 8.14%
    15     | 6             | 9.95%
    16     | 2             | 11.76%
    17     | 4             | 13.57%
    18     | 0             | 16.74%

Le défi

Étant donné deux aiguilles ModTen , affichez l' une des trois valeurs cohérentes de votre choix pour savoir si:

  • le premier joueur gagne
  • le deuxième joueur gagne
  • c'est un match nul

Les règles suivantes s'appliquent:

  • Une carte doit être décrit par son rang en majuscules ( 2, 3, ..., 9, T, J, Q, Kou A) suivi de son costume en minuscules ( c, d, hou s, pour les clubs, diamants, coeurs et piques).
  • Vous pouvez utiliser à la "10"place de "T"mais toute autre substitution est interdite.
  • Tant que les règles ci-dessus sont respectées, vous pouvez prendre les mains dans n'importe quel format raisonnable et sans ambiguïté. Vous êtes autorisé à prendre le rang et la combinaison en deux caractères distincts plutôt qu'en une seule chaîne.

    Certains formats d'entrée valides sont:

    • "7c Qh 8s Ks"
    • [["7c","Qh"], ["8s","Ks"]]
    • [[['7','c'], ['Q','h']], [['8','s'], ['K','s']]]
    • etc.
  • Au lieu d'utiliser 3 valeurs distinctes cohérentes, votre sortie peut également être négative , positive ou nulle . Veuillez spécifier le format de sortie utilisé dans votre réponse.

  • C'est du .

Cas de test

Le joueur 1 gagne

["Js","3s"], ["Ks","Kh"]
["7h","9h"], ["9s","7c"]
["Ah","5s"], ["Ts","8s"]
["Ts","8s"], ["Jh","2s"]
["4h","8s"], ["Qh","Ks"]

Le joueur 2 gagne

["Th","8d"], ["6s","Kd"]
["Jc","5c"], ["3s","9s"]
["Jc","Jd"], ["9h","Ah"]
["2d","4d"], ["3h","3s"]
["5c","4c"], ["3c","2c"]

Dessiner

["Js","3s"], ["3d","Jd"]
["Ah","Ac"], ["3d","9s"]
["Qc","Kc"], ["6d","4d"]
["2d","3d"], ["3s","2s"]
["Ts","9c"], ["4h","5d"]
Arnauld
la source
Qu'en est-il de prendre les énumérations comme données d'entrée? Haskell a un système de type assez puissant ; Je suis assez sûr que quelque chose comme ça pourrait être fait directement dedans.
wizzwizz4
Ce n'est pas Haskell, mais {{J, s}, {3, s}}ça irait ?
wizzwizz4
1
@ wizzwizz4 Oui, ça va.
Arnauld
2
Cela pourrait être plus clair avec des «mains de cartes avec des combinaisons assorties» au lieu de «cartes assorties».
chrylis -on strike-

Réponses:

13

Python 3 , 114 110 octets

lambda m,n:p(*n)-p(*m)
R=b"T 2J45UNK9RL<3SLM;QAK:O>=/678"
v=R.find
p=lambda i,s,j,t:R[s==t::2][v(j)*v(i)%10+3]

Essayez-le en ligne!

@Arnauld a proposé l'idée de fusionner les chaînes de valeur des cartes et de classement. Après quelques tentatives, j'ai réussi à créer une chaîne fusionnée R="T 2J45UNK9RL<3SLM;QAK:O>=/678", qui a la même longueur que la chaîne de valeur de la carte d'origine. Le sous - chaîne R[6:25]="UNK9RL<3SLM;QAK:O>=/"sert la table de rang ainsi qu'une valeur de la carte table de recherche pour 3, 9,A , Ket Q. Le décodage en valeur ASCII de la nouvelle table de classement a le même effet de classement que la table de classement précédente.

L'utilisation de chaînes d'octets en entrée permet d'économiser 4 octets.

L'utilisation cmpdans Python 2 peut réduire la solution à 102 octets, comme le montre la solution @ xnor .


Python 3 , 165 142 142 130 129 octets

lambda m,n:p(*n)-p(*m)
v="T 23456789   J    QA        K".find
p=lambda i,s,j,t:ord("HC92FA51GAB4E893D760"[s==t::2][v(j)*v(i)%10])

Essayez-le en ligne!

-23 octets grâce à @Jonathan Allan

-2 octets grâce à @ovs

-1 octet grâce à @mypetlion

Non golfé:

f = lambda hand1, hand2: get_rank(*hand2) - get_rank(*hand1)
def get_rank(v1, suit1, v2, suit2):
    get_card_value = "T 23456789   J    QA        K".find
    # rank_table = [[17,9,15,5,16,11,14,9,13,6],[12,2,10,1,10,4,8,3,7,0]]
    # rank_table = ("H9F5GBE9D6","C2A1A48370") # Base-18 encoding of ranks
    rank_table = "HC92FA51GAB4E893D760" # Interleaved base-18 encoding

    # ASCII-value decoding has the same ranking effect as base-18 decoding
    return ord(rank_table[suit1 == suit2::2][get_card_value(v2) * get_card_value(v1) % 10])

La fonction fprend deux arguments représentant la main du joueur 1 et du joueur 2. Elle renvoie une valeur positive, négative ou nulle dans le cas d'une victoire de joueur 1, de victoire de joueur 2 ou d'un match nul, en conséquence. Chaque main est codée comme une chaîne unique, par exemple "7cQh".

Joel
la source
3
Salut Joel, bienvenue au CGCC! Idée très intelligente de diviser le tableau de classement des mains en deux! Laissez-les venir!
640 Ko
1
@Jonathan Allan Merci. J'ai intégré votre idée en utilisant des approches légèrement différentes.
Joel
1
Vous pouvez économiser 2 octets en stockant le tableau de classement dans une seule chaîne:"HC92FA51GAB4E893D760"[s==t::2]
ovs
1
Et un autre de 4 octets plus court si vous êtes prêt à passer à Python 2. cmp(n'est pas disponible en Python 3)
OVS
1
Vous pouvez utiliser str.findau lieu de str.indexpour enregistrer un octet. La seule différence de comportement entre les deux méthodes est que indexgénère une erreur lorsque l'élément n'est pas trouvé, tandis que findrenvoie -1. Ce ne sera donc pas un problème pour votre code.
mypetlion
11

Assemblage x86-16, 87 83 octets

Binaire:

00000000: e807 0050 e803 005a 3ac2 ad2c 3092 ad2c  ...P...Z:..,0..,
00000010: 30bb 3501 3af4 7503 bb3f 01e8 0a00 92e8  0.5.:.u..?......
00000020: 0600 f6e2 d40a d7c3 b106 bf49 01f2 aee3  ...........I....
00000030: 038a 4504 c312 0a10 0611 0c0f 0a0e 070d  ..E.............
00000040: 030b 020b 0509 0408 0124 1a21 1b11 0003  .........$.!....
00000050: 0808 09                                  ...

Non assemblé:

E8 010A         CALL GET_HAND           ; score first hand, ranked score into AL 
50              PUSH AX                 ; save score
E8 010A         CALL GET_HAND           ; score second hand 
5A              POP  DX                 ; restore first hand into DL 
3A C2           CMP  AL, DL             ; compare scores - result in CF, OF and ZF

            GET_HAND PROC               ; 4 char string to ranked score ("9s7c" -> 6)
AD              LODSW                   ; load first card string 
2C 30           SUB  AL, '0'            ; ASCII convert 
92              XCHG DX, AX             ; store in DX 
AD              LODSW                   ; load second card string 
2C 30           SUB  AL, '0'            ; ASCII convert 
BB 0139         MOV  BX, OFFSET R       ; first, point to non-suited table 
3A F4           CMP  DH, AH             ; is it suited?
75 03           JNZ  NO_SUIT 
BB 0143         MOV  BX, OFFSET RS      ; point to suited table 
            NO_SUIT: 
E8 012C         CALL GET_VALUE          ; get face card value in AL 
92              XCHG DX, AX             ; swap first and second cards 
E8 012C         CALL GET_VALUE          ; get face card value in AL 
F6 E2           MUL  DL                 ; multiply values of two cards 
D4 A0           AAM                     ; AL = AL mod 10
D7              XLAT                    ; lookup value in rank score table 
C3              RET 
            GET_HAND ENDP

            GET_VALUE PROC              ; get value of a card (2 -> 2, J -> 3, A -> 9)
B1 06           MOV  CL, 6              ; loop counter for scan
BF 014D         MOV  DI, OFFSET V       ; load lookup table 
F2/ AE          REPNZ SCASB             ; scan until match is found 
E3 03           JCXZ NOT_FOUND          ; if not found, keep original numeric value
8A 45 04        MOV  AL, BYTE PTR[DI+4] ; if found, get corresponding value 
            NOT_FOUND:
C3              RET                     ; return to program 
            GET_VALUE ENDP

R   DB 18, 10, 16, 6, 17, 12, 15, 10, 14, 7     ; unsuited score table
RS  DB 13, 3, 11, 2, 11, 5, 9, 4, 8, 1          ; suited score table
V   DB 'J'-'0','Q'-'0','K'-'0','A'-'0','T'-'0'  ; face card score table
    DB 3, 8, 8, 9, 0

L'entrée est une chaîne telle que Js3sKsKh, au pointeur dans SI. La sortie est ZF = 0 and SF = OF(test avec JG) si le joueur 1 gagne, SF ≠ OF(test avec JL) si le joueur 2 gagne ou ZF(test avec JE) si un match nul.

Sortie à l'aide du programme de test DOS:

entrez la description de l'image ici

Téléchargez et testez MODTEN.COM pour DOS.

640 Ko
la source
7

05AB1E , 41 37 octets

•V›{₆Ÿ&∊WÍj¸•19вyεø`Ës‘ߌQ‘ŽćS‡Pθ«}èÆ

-4 octets grâce à @Grimy .

Entrez sous forme de liste de liste de liste de caractères, comme le troisième exemple de format d'entrée dans la description du défi. C'est-à-dire P1 7c Qhet P2 8s Ksserait entré comme [[["7","c"],["Q","h"]],[["8","s"],["K","s"]]]. (Et utilise "10"pour 10.)

Produit un entier négatif si le joueur 1 gagne; un entier positif si le joueur 2 gagne; ou 0 si c'est un match nul.

Essayez-le en ligne ou vérifiez tous les cas de test .

Explication:

V›{₆Ÿ&∊WÍj¸•  # Push compressed integer 36742512464916394906012008
 19в           # Convert it to base-19 as list:
               #   [18,10,16,6,17,12,15,10,14,7,13,3,11,2,11,5,9,4,8,1]
Iε             # Push the input, and map each of its hands to:
  ø            #  Zip/transpose the hand; swapping rows/columns
               #   i.e. [["8","s"],["K","s"]] → [[["8","K"],["s","s"]]
   `           #  Push them separated to the stack
    Ë          #  Check if the two suits in the top list are equal (1/0 for truthy/falsey)
    s          #  Swap to get the list with the two values
     ‘ߌQ     #  Push dictionary string "JAKEQ"
     ŽćS       #  Push compressed integer 39808
              #  Transliterate these characters to these digits
      P        #  Now take the product of the two values in the list
       θ       #  Only leave the last digit (basically modulo-10)
    «          #  And merge it to the 1/0
               #  (now we have the hand values of both players,
               #   where instead of a trailing "s" we have a leading 1)
             # After the map: index each value into the earlier created integer-list
               # (now we have the hand rank of both players)
   Æ           # And then reduce the resulting integers by subtracting
               # (after which the result is output implicitly)

Voir cette astuce 05AB1E (sections Comment utiliser le dictionnaire? Comment compresser les grands entiers? Et Comment compresser les listes d'entiers? ) Pour comprendre pourquoi •V›{₆Ÿ&∊WÍj¸•est 36742512464916394906012008, •V›{₆Ÿ&∊WÍj¸•19вest [18,10,16,6,17,12,15,10,14,7,13,3,11,2,11,5,9,4,8,1], ‘ߌQ‘est "JAKEQ"et ŽćSest 39808.

Kevin Cruijssen
la source
La question permet explicitement de prendre l'entrée Tcomme 10, vous pouvez donc simplement supprimer le Tde JTQKA(et utiliser un entier compressé 3889 au lieu de 30889). , Aussi T* ... +pourrait être ... «.
Grimmy
1
10Tdixnmoddix=0T*...+...«
1
37 (fonctionne actuellement!)
Grimmy
@Grimy Ah, bonne utilisation du dictionnaire comme ça!
Kevin Cruijssen
3

PHP ,212 185 178 149 octets

while($p=$argv[++$x])$$x=ord(rjpfqlojngmckbkeidha[(($v=[J=>3,Q=>8,K=>8,A=>9])[$p[0]]?:$p[0])*($v[$p[2]]?:$p[2])%10+($p[1]==$p[3])*10]);echo${1}-${2};

Essayez-le en ligne!

  • -7 octets grâce à @ Night2!
  • -29 octets par codage ASCII de la table au lieu du tableau

L'entrée se fait via la ligne de commande. La sortie vers STDOUTest négative si le joueur 1 gagne, positive si le joueur 2 gagne, en 0cas d'égalité. Exemple:

$ php modten.php Js3s KsKh
-1
640 Ko
la source
1
@ Nuit2 Je suppose que si j'étais prêt à nous donner à l'opérateur de vaisseau spatial (je veux dire, combien de fois faites - vous l' utiliser?), Je pouvais -2 octets et juste retour négatif, positif ou nul, au lieu de -1, 1ou 0.
640 Ko
J'ai été étonné (dans le bon sens) de voir l'opérateur du vaisseau spatial dans la réponse précédente.
Night2
2

Gelée , 46 octets

“T0J3Q8K8A9”yⱮZV€P$Eƭ€)%⁵UḌị“©N¿!Æßvṅ?żṀ’b18¤I

Essayez-le en ligne!

Un programme complet prenant comme argument par exemple ["7h","Ks"],["4s","Ts"]et affichant zéro si les deux joueurs tirent au sort, positif si le joueur 1 gagne et négatif si le joueur 2 gagne.

Nick Kennedy
la source
2

C (gcc) , 172 167 165 164 octets

p(l,v)char*l,*v;{v="T 23456789   J    QA        K";return"A<92?:51@:;4>893=760"[(l[1]==l[3])+(index(v,l[2])-v)*(index(v,*l)-v)%10*2];}f(char*s){return p(s+5)-p(s);}

Essayez-le en ligne!

2 octets rasés grâce à @ceilingcat!

Fondamentalement, un port de la solution Python3 de @ Joel, mais sans l'encodage base18. Attend l'entrée comme une chaîne avec un espace séparant les mains des deux joueurs, et produit un entier positif, négatif ou nul pour indiquer que le joueur 1 gagne, le joueur 2 gagne ou s'il s'agit d'un match nul.

G. Sliepen
la source
2

Perl 6 , 101 100 94 88 octets

-1 octet grâce à Jo King

{[-] .map:{'HC92FA51GAB4E893D76'.ords[[*](.[*;0]>>.&{TR/JQKA/3889/})%10*2+[eq] .[*;1]]}}

Essayez-le en ligne!

Prend l'entrée comme f(((<J ♠>, <3 ♠>), (<10 ♠>, <K ♥>)))utilisant 10pour Ten. Renvoie une valeur <0 si le joueur 1 gagne,> 0 si le joueur 2 gagne, 0 s'il s'agit d'un match nul.

Explication

{
  [-]  # subtract values
  .map:{  # map both hands
    'HC92FA51GAB4E893D76'.ords[  # lookup rank in code point array
      [*](  # multiply
        .[*;0]  # card ranks
        >>.&{TR/JQKA/3889/}  # translate J,Q,K,A to 3,8,8,9
      )
      %10*2  # mod 10 times 2
      +[eq] .[*;1]  # plus 1 if suited
    ]
  }
}
nwellnhof
la source
1

Fusain , 97 octets

≔”)¶&sNψU↓”ζF¹³F¹³F⁻⁴⁼ικ⊞υ⁺÷λ³⊗﹪Π⁺§ζι§ζκχ≔”A↘τ[⁵PkxτG”ε≔⁰δF⟦θη⟧≦⁻№υ⁺⁼§ι¹§ι³⊗﹪Π⁺§ζ⌕ε§ι⁰§ζ⌕ε§ι²χδIδ

Essayez-le en ligne! Le lien est vers la version détaillée du code. Prend l'entrée sous la forme de deux chaînes de 4 caractères, par exemple QcKc 6d4det génère un entier signé. Explication:

≔”)¶&sNψU↓”ζ

La chaîne compressée 2345678903889représente les valeurs de la carte.

F¹³F¹³

Faites une boucle sur chaque paire de valeurs possible.

F⁻⁴⁼ικ

Faites une boucle sur chaque deuxième combinaison de cartes possible. Sans perte de généralité, nous pouvons supposer que la première carte a la couleur 3, de sorte que la deuxième couleur de la carte peut aller de 0 à 3, sauf si les valeurs sont les mêmes, auquel cas elle ne peut aller que de 0 à 2.

⊞υ⁺÷λ³⊗﹪Π⁺§ζι§ζκχ

Calculez le score modifié de la main, qui est la valeur de la main doublée, plus 1 si les couleurs sont les mêmes (c'est-à-dire que la deuxième carte a la couleur 3).

≔”A↘τ[⁵PkxτG”ε

La chaîne compressée 23456789TJQKAreprésente les caractères de la carte. Les cartes d'entrée sont recherchées dans cette chaîne, puis la position est utilisée pour indexer dans la première chaîne pour obtenir la valeur de la carte.

≔⁰δ

Initialisez le résultat à 0.

F⟦θη⟧

Boucle sur les deux mains.

≦⁻№υ⁺⁼§ι¹§ι³⊗﹪Π⁺§ζ⌕ε§ι⁰§ζ⌕ε§ι²χδ

Calculez le score modifié de la main, et donc sa fréquence, et soustrayez-en le résultat.

Iδ

Sortez la différence de fréquence.

Neil
la source
0

Perl 5 -p , 107 octets

$a=A;y/ATJQK/90388/;${$a++}=substr"IAG6HCFAE7D3B2B59481",($1eq$3).$&*$2%10,1while/.(.) (.)(.)/g;$_=$A cmp$B

Essayez-le en ligne!

Contribution:

As 4d,Th 8c

(En fait, la virgule peut être n'importe quel caractère.)

Sortie:

-1  Player one wins
 0  Draw
 1  Player two wins
Xcali
la source