Niente come un buon vecchio gioco di ModTen


27

Disclaimer: ModTen è un gioco di carte immaginario creato al solo scopo di questa sfida.

Le regole di ModTen

ModTen si gioca con un mazzo standard da 52 carte. Poiché le regole complete devono ancora essere inventate, ci concentreremo esclusivamente sulla classifica delle mani.

Jack & Three, adatto

Una mano vincente in ModTen. Grafica da Wikipedia .

Valori delle carte

Le carte hanno i seguenti valori:

  • 2 a 9 : vale il loro valore nominale
  • Dieci : 0 punti
  • Jack : 3 punti
  • Regina o re : 8 punti
  • Asso : 9 punti

Valori della mano

  • Una mano ModTen è composta da due carte . Il valore base di una mano si ottiene moltiplicando il valore di entrambe le carte e mantenendo solo l'ultima cifra (cioè applicando un modulo 10).

    6(7×8)mod10=6

  • L'unica altra regola in ModTen è che le carte adatte valgono più di quelle inadatte. Per convenzione, aggiungeremo una "s" al valore se entrambe le carte sono dello stesso seme.

    Ad esempio, il valore di 9 ♠ - 5 ♠ verrà indicato come " ", perché e le carte sono adatte.5S(9×5)mod10=5

Classifica delle mani e vincitore

Le regole di cui sopra danno luogo a 18 gradi di mani distinti che sono riassunti nella tabella seguente, dal più forte al più basso (o dal più raro al più comune). Le probabilità sono fornite solo a titolo informativo.

Date due mani, vince la mano con il rango più basso. Se entrambe le mani hanno lo stesso valore, allora si tratta di un pareggio (non c'è pareggio).

 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%

La sfida

Date due mani ModTen , emetti uno dei tre valori coerenti a tua scelta per dire se:

  • vince il primo giocatore
  • vince il secondo giocatore
  • è un pareggio

Si applicano le seguenti regole:

  • Una scheda deve essere descritto dal suo rango in maiuscolo ( 2, 3, ..., 9, T, J, Q, Ko A) seguito dal suo seme in minuscolo ( c, d, ho s, per fiori, quadri, cuori e picche).
  • È possibile utilizzare "10"invece di "T"ma qualsiasi altra sostituzione è vietata.
  • Finché vengono seguite le regole di cui sopra, puoi prendere le mani in qualsiasi formato ragionevole e inequivocabile. Ti è permesso prendere il grado e il seme come due personaggi distinti piuttosto che una singola stringa.

    Alcuni formati di input validi sono:

    • "7c Qh 8s Ks"
    • [["7c","Qh"], ["8s","Ks"]]
    • [[['7','c'], ['Q','h']], [['8','s'], ['K','s']]]
    • eccetera.
  • Invece di utilizzare 3 valori distinti coerenti, l'output può anche essere negativo , positivo o zero . Si prega di specificare il formato di output utilizzato nella risposta.

  • Questo è .

Casi test

Il giocatore 1 vince

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

Il giocatore 2 vince

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

Disegnare

["Js","3s"], ["3d","Jd"]
["Ah","Ac"], ["3d","9s"]
["Qc","Kc"], ["6d","4d"]
["2d","3d"], ["3s","2s"]
["Ts","9c"], ["4h","5d"]

Che dire di prendere enumerazioni come input? Haskell ha un sistema di tipo abbastanza potente ; Sono abbastanza sicuro che qualcosa del genere possa essere realizzato direttamente in esso.
wizzwizz4,

Questo non è Haskell, ma andrebbe {{J, s}, {3, s}}bene?
wizzwizz4,

1
@ wizzwizz4 Sì, va bene.
Arnauld,

2
Ciò potrebbe essere più chiaro con "mani di carte con semi corrispondenti" invece di "carte con seme".
Chrylis

Risposte:


13

Python 3 , 114 110 byte

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]

Provalo online!

@Arnauld ha proposto l'idea di unire il valore della carta e le stringhe della tabella dei ranghi. Dopo alcuni tentativi sono riuscito a creare una stringa unita R="T 2J45UNK9RL<3SLM;QAK:O>=/678", che ha la stessa lunghezza della stringa del valore della carta originale. La sottostringa R[6:25]="UNK9RL<3SLM;QAK:O>=/"funge da tabella di rango così come una tabella di ricerca valore di carta per 3, 9, A, K, e Q. La decodifica del valore ASCII della nuova tabella di classificazione ha lo stesso effetto di classificazione della tabella di classificazione precedente.

L'uso delle stringhe di byte come input consente di risparmiare 4 byte.

L'uso cmpin Python 2 può ridurre la soluzione a 102 byte, come mostrato dalla soluzione di @ xnor .


Python 3 , 165 142 130 130 129 byte

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])

Provalo online!

-23 byte grazie a @Jonathan Allan

-2 byte grazie a @ovs

-1 byte grazie a @mypetlion

Ungolfed:

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 funzione faccetta due argomenti che rappresentano la mano del giocatore 1 e del giocatore 2. Restituisce un valore positivo, negativo o zero nel caso di una vittoria del giocatore 1, una vittoria del giocatore 2 o un pareggio, di conseguenza. Ogni mano è codificata come una singola stringa, ad esempio "7cQh".


3
Ciao Joel, benvenuto in CGCC! Un'idea molto intelligente che divide la schiera della mano in due! Continuate a venire!
640 KB

1
@Jonathan Allan Grazie. Ho incorporato la tua idea usando approcci leggermente diversi.
Gioele il

1
È possibile salvare 2 byte memorizzando la tabella dei ranghi in una singola stringa:"HC92FA51GAB4E893D760"[s==t::2]
ovs

1
E altri 4 byte in meno se sei disposto a passare a Python 2. ( cmpnon è disponibile in Python 3)
ovs

1
È possibile utilizzare str.findinvece di str.indexsalvare un byte. L'unica differenza di comportamento tra i due metodi è che indexgenera un errore quando l'elemento non viene trovato, mentre findritorna -1. Quindi non sarà un problema per il tuo codice.
mypetlion il

11

x86-16 Assembly, 87 83 byte

Binario:

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                                  ...

smontato:

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'input è una stringa come Js3sKsKh, in corrispondenza del puntatore SI. L'output è ZF = 0 and SF = OF(test con JG) se il giocatore 1 vince, SF ≠ OF(test con JL) se il giocatore 2 vince o ZF(test con JE) se un pareggio.

Output usando il programma di test DOS:

inserisci qui la descrizione dell'immagine

Scarica e prova MODTEN.COM per DOS.


7

05AB1E , 41 37 byte

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

-4 byte grazie a @Grimy .

Inserisci come un elenco di un elenco di caratteri, come il formato di input del terzo esempio nella descrizione della sfida. Cioè P1 7c Qhe P2 8s Ksverrebbero inseriti come [[["7","c"],["Q","h"]],[["8","s"],["K","s"]]]. (E usa "10"per 10.)

Emette un numero intero negativo se il giocatore 1 vince; un numero intero positivo se vince il giocatore 2; o 0 se è un pareggio.

Provalo online o verifica tutti i casi di test .

Spiegazione:

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)

Vedi questo mio suggerimento 05AB1E (sezioni Come usare il dizionario? Come comprimere numeri interi grandi? E Come comprimere gli elenchi di numeri interi? ) Per capire perché •V›{₆Ÿ&∊WÍj¸•è 36742512464916394906012008, •V›{₆Ÿ&∊WÍj¸•19вè [18,10,16,6,17,12,15,10,14,7,13,3,11,2,11,5,9,4,8,1], ‘ߌQ‘è "JAKEQ"e ŽćSè 39808.


La domanda consente esplicitamente di accettare input Tcome 10, quindi puoi semplicemente rilasciare il Tda JTQKA(e usare l'intero compresso 3889 invece di 30889). Inoltre, T* ... +potrebbe essere ... «.
Grimmy,

1
10T10nmod10=0T*...+...«

1
37 (ora funziona davvero!)
Grimmy,

@Grimy Ah, buon uso del dizionario in quel modo!
Kevin Cruijssen,

3

PHP ,212 185 178 149 byte

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};

Provalo online!

  • -7 byte grazie a @ Night2!
  • -29 byte con ASCII che codifica la tabella anziché l'array

L'immissione avviene tramite riga di comando. L'output a STDOUTè negativo se il giocatore 1 vince, positivo se il giocatore 2 vince, 0se pareggia. Esempio:

$ php modten.php Js3s KsKh
-1

1
@ Night2 Suppongo che se fossi disposto a darci l'operatore dell'astronave (voglio dire, con quale frequenza riesci a usarlo?), Potrei -2 byte e restituire solo negativo, positivo o zero, invece di -1, 1o 0.
640 KB

Sono stato sorpreso (in senso buono) di vedere l'operatore dell'astronave nella risposta precedente.
Night2

2

Gelatina , 46 byte

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

Provalo online!

Un programma completo che prende ad esempio il suo argomento ["7h","Ks"],["4s","Ts"]e stampa zero se entrambi i giocatori pescano, positivo se il giocatore 1 vince e negativo se il giocatore 2 vince.


2

C (gcc) , 172 167 165 164 byte

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);}

Provalo online!

2 byte eliminati grazie a @ceilingcat!

Fondamentalmente una porta della soluzione Python3 di @ Joel, ma senza la codifica base18. Si aspetta l'input come una stringa con uno spazio che separa le mani dei due giocatori e genera un numero intero positivo, negativo o zero per indicare che il giocatore 1 vince, il giocatore 2 vince o se è un pareggio.


2

Perl 6 , 101 100 94 88 byte

-1 byte grazie a Jo King

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

Provalo online!

Accetta input come l' f(((<J ♠>, <3 ♠>), (<10 ♠>, <K ♥>)))utilizzo 10di Ten. Restituisce un valore <0 se il giocatore 1 vince,> 0 se il giocatore 2 vince, 0 se è un pareggio.

Spiegazione

{
  [-]  # 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
    ]
  }
}

1

Carbone , 97 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Prende l'input come due stringhe di 4 caratteri, ad esempio QcKc 6d4de genera un numero intero con segno. Spiegazione:

≔”)¶&sNψU↓”ζ

La stringa compressa 2345678903889rappresenta i valori della carta.

F¹³F¹³

Passa sopra ogni possibile coppia di valori.

F⁻⁴⁼ικ

Passa sopra ogni possibile secondo seme di carta. Senza perdita di generalità possiamo supporre che la prima carta abbia seme 3, quindi il seme della seconda carta può variare da 0 a 3 a meno che i valori non siano gli stessi, nel qual caso può variare solo da 0 a 2.

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

Calcola il punteggio modificato della mano, che è il valore della mano raddoppiata, più 1 se i semi sono uguali (cioè la seconda carta ha seme 3).

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

La stringa compressa 23456789TJQKArappresenta i caratteri della carta. Le carte di input vengono cercate in questa stringa e quindi la posizione viene utilizzata per indicizzare la prima stringa per ottenere il valore della carta.

≔⁰δ

Inizializza il risultato su 0.

F⟦θη⟧

Passa sopra le due mani.

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

Calcola il punteggio modificato della mano, e quindi la sua frequenza, e sottrai il risultato da questo.

Iδ

Emette la differenza di frequenza.



0

Perl 5 -p , 107 byte

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

Provalo online!

Ingresso:

As 4d,Th 8c

(In realtà, la virgola può essere qualsiasi carattere.)

Produzione:

-1  Player one wins
 0  Draw
 1  Player two wins
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.