Nichts wie ein gutes altes Spiel von ModTen

27

Haftungsausschluss: ModTen ist ein fiktives Kartenspiel, das ausschließlich für diesen Zweck entwickelt wurde.

Die Regeln von ModTen

ModTen wird mit einem Standardstapel von 52 Karten gespielt. Da die vollständigen Regeln erst noch erfunden werden müssen, konzentrieren wir uns ausschließlich auf das Handranking.

Jack & Three, passend

Eine gewinnende Hand in ModTen. Grafiken aus Wikipedia .

Kartenwerte

Die Karten haben folgende Werte:

  • 2 bis 9 : Wert ihren Nennwert
  • Zehn : 0 Punkte
  • Jack : 3 Punkte
  • Königin oder König : 8 Punkte
  • Ass : 9 Punkte

Handwerte

  • Eine ModTen- Hand besteht aus zwei Karten . Der Basiswert einer Hand wird erhalten, indem der Wert beider Karten multipliziert wird und nur die letzte Ziffer beibehalten wird (dh ein Modulo 10 angewendet wird).

    Zum Beispiel ist der Wert von 7 ♥ - Q ♣ " 6 ", weil (7×8)mod10=6 .

  • Die einzige andere Regel in ModTen ist, dass geeignete Karten mehr wert sind als ungeeignete. Konventionell werden wir ein "s" an den Wert anhängen, wenn beide Karten die gleiche Farbe haben.

    Zum Beispiel wird der Wert von 9 ♠ - 5 s als " 5s " notiert , da (9×5)mod10=5 und die Karten geeignet sind.

Hand Ranking und Gewinner

Die obigen Regeln führen zu 18 verschiedenen Hand-Rängen, die in der folgenden Tabelle zusammengefasst sind, vom stärksten zum niedrigsten (oder seltensten zum häufigsten). Die Wahrscheinlichkeiten sind nur zur Information angegeben.

Bei zwei Händen gewinnt die Hand mit dem niedrigsten Rang. Wenn beide Hände den gleichen Rang haben, ist es ein Unentschieden (es gibt keinen Tie Breaker).

 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%

Die Herausforderung

Wenn Sie zwei ModTen- Hände haben, geben Sie einen von drei konsistenten Werten Ihrer Wahl aus, um festzustellen, ob:

  • der erste Spieler gewinnt
  • der zweite Spieler gewinnt
  • es ist eine Zeichnung

Es gelten folgende Regeln:

  • Eine Karte muss von seinem Rang in Großbuchstaben beschrieben werden ( 2, 3, ..., 9, T, J, Q, Koder A) durch seine Klage in Kleinbuchstabe gefolgt ( c, d, hoder s, für Vereine, Karo, Herz und Pik).
  • Sie können "10"anstelle von verwenden, "T"aber jede andere Ersetzung ist verboten.
  • Solange die oben genannten Regeln befolgt werden, dürfen Sie die Hände in jedem vernünftigen und eindeutigen Format nehmen. Sie dürfen den Rang und die Farbe als zwei verschiedene Zeichen anstatt als einzelne Zeichenfolge annehmen.

    Einige gültige Eingabeformate sind:

    • "7c Qh 8s Ks"
    • [["7c","Qh"], ["8s","Ks"]]
    • [[['7','c'], ['Q','h']], [['8','s'], ['K','s']]]
    • etc.
  • Anstatt 3 konsistente unterschiedliche Werte zu verwenden, kann Ihre Ausgabe auch negativ , positiv oder null sein . Bitte geben Sie das in Ihrer Antwort verwendete Ausgabeformat an.

  • Das ist .

Testfälle

Spieler 1 gewinnt

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

Spieler 2 gewinnt

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

Zeichnen

["Js","3s"], ["3d","Jd"]
["Ah","Ac"], ["3d","9s"]
["Qc","Kc"], ["6d","4d"]
["2d","3d"], ["3s","2s"]
["Ts","9c"], ["4h","5d"]
Arnauld
quelle
Was ist mit Aufzählungen als Eingabe? Haskell hat ein ziemlich leistungsfähiges Typensystem ; Ich bin mir ziemlich sicher, dass so etwas direkt darin gemacht werden könnte.
wizzwizz4
Das ist nicht Haskell, aber wäre {{J, s}, {3, s}}okay?
wizzwizz4
1
@ wizzwizz4 Ja, das ist in Ordnung.
Arnauld
2
Dies könnte mit "Händen von Karten mit passenden Farben" klarer sein als mit "passenden Karten".
chrylis -on strike-

Antworten:

13

Python 3 , 114 110 Bytes

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]

Probieren Sie es online!

@Arnauld schlug die Idee vor, den Kartenwert und die Rangfolge der Tabellen zusammenzuführen. Nach einigen Versuchen konnte ich eine zusammengeführte Zeichenfolge herstellen R="T 2J45UNK9RL<3SLM;QAK:O>=/678", die dieselbe Länge wie die ursprüngliche Kartenwertzeichenfolge hat. Der Teil R[6:25]="UNK9RL<3SLM;QAK:O>=/"dient als Rang Tabelle sowie eine Nachschlagetabelle Kartenwert für 3, 9, A, K, und Q. Die ASCII-Wert-Dekodierung der neuen Rangliste hat den gleichen Ranglisteneffekt wie die vorherige Rangliste.

Durch die Verwendung von Byte-Zeichenfolgen als Eingabe werden 4 Byte gespart.

Die Verwendung cmpin Python 2 kann die Lösung auf 102 Byte reduzieren, wie die Lösung von @ xnor zeigt .


Python 3 , 165 142 130 129 Bytes

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

Probieren Sie es online!

-23 Bytes danke an Jonathan Allan

-2 Bytes dank @ovs

-1 Byte dank @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])

Die Funktion verwendet fzwei Argumente, die die Hand von Spieler 1 und Spieler 2 darstellen. Sie gibt einen positiven, negativen oder Nullwert zurück, wenn Spieler 1 gewinnt, Spieler 2 gewinnt oder entsprechend unentschieden spielt. Jede Hand ist als einzelne Zeichenfolge codiert, z. B. "7cQh".

Joel
quelle
3
Hallo Joel, willkommen bei CGCC! Sehr clevere Idee, das Handrang-Array in zwei Teile zu teilen! Lass sie kommen!
23.
1
@ Jonathan Allan Danke. Ich habe Ihre Idee mit etwas anderen Ansätzen aufgenommen.
Joel
1
Sie können 2 Bytes sparen, indem Sie die Rangliste in einer einzigen Zeichenfolge speichern:"HC92FA51GAB4E893D760"[s==t::2]
ovs
1
Und weitere 4 Bytes kürzer, wenn Sie zu Python 2 wechseln möchten. (Ist cmpin Python 3 nicht verfügbar)
ovs
1
Sie können str.findanstelle von str.indexein Byte speichern. Der einzige Unterschied zwischen den beiden Methoden besteht darin, dass indexein Fehler ausgegeben wird, wenn das Element nicht gefunden wird, während es findzurückgegeben wird -1. Es ist also kein Problem für Ihren Code.
Mypetlion
11

x86-16-Baugruppe, 87 83 Bytes

Binär:

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

Zerlegt:

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

Die Eingabe erfolgt als Zeichenfolge, z. B. Js3sKsKham Zeiger in SI. Ausgang ist ZF = 0 and SF = OF(Test mit JG), wenn Spieler 1 gewinnt, SF ≠ OF(Test mit JL), wenn Spieler 2 gewinnt oder ZF(Test mit JE), wenn ein Unentschieden.

Ausgabe mit DOS-Testprogramm:

Bildbeschreibung hier eingeben

Laden Sie MODTEN.COM für DOS herunter und testen Sie es .

640 KB
quelle
7

05AB1E , 41 37 Bytes

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

-4 Bytes dank @Grimy .

Eingabe als Liste der Liste der Zeichen, wie im dritten Beispiel für das Eingabeformat in der Herausforderungsbeschreibung. Dh P1 7c Qh& P2 8s Kswürden als eingegeben [[["7","c"],["Q","h"]],[["8","s"],["K","s"]]]. (Und verwendet "10"für 10.)

Gibt eine negative Ganzzahl aus, wenn Spieler 1 gewinnt. eine positive ganze Zahl, wenn Spieler 2 gewinnt; oder 0, wenn es ein Unentschieden ist.

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

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)

Sehen Sie sich meinen Tipp 05AB1E an (Abschnitte Verwendung des Wörterbuchs , Komprimieren großer Ganzzahlen und Komprimieren von Ganzzahllisten ), um zu verstehen, warum •V›{₆Ÿ&∊WÍj¸•ist 36742512464916394906012008, •V›{₆Ÿ&∊WÍj¸•19вist [18,10,16,6,17,12,15,10,14,7,13,3,11,2,11,5,9,4,8,1], ‘ߌQ‘ist "JAKEQ"und ŽćSist 39808.

Kevin Cruijssen
quelle
Die Frage ausdrücklich erlaubt unter Eingabe Tals 10, so dass Sie nur die Drop können Taus JTQKA(und anstelle von 30889 integer 3889 komprimiert verwenden). Könnte T* ... +auch sein ... «.
Grimmy
1
10T10nmod10=0T*...+...«
1
37 (funktioniert jetzt tatsächlich!)
Grimmy
@Grimy Ah, netter Gebrauch des Wörterbuchs so!
Kevin Cruijssen
3

PHP ,212 185 178 149 Bytes

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

Probieren Sie es online!

  • -7 Bytes dank @ Night2!
  • -29 Bytes nach ASCII-Codierung der Tabelle anstelle des Arrays

Die Eingabe erfolgt über die Befehlszeile. Die Ausgabe an STDOUTist negativ, wenn Spieler 1 gewinnt, positiv, wenn Spieler 2 gewinnt, 0wenn Gleichstand besteht. Beispiel:

$ php modten.php Js3s KsKh
-1
640 KB
quelle
1
@ Night2 Ich nehme an, wenn ich bereit wäre, uns den Raumschiffoperator zu geben (ich meine, wie oft darf man das benutzen?), Könnte ich -2 Bytes und statt -1, 1oder, einfach negativ, positiv oder null zurückgeben 0.
640 KB,
Ich war (auf eine gute Weise) erstaunt, den Raumschiffbetreiber in der vorherigen Antwort zu sehen.
Nacht,
2

Jelly , 46 Bytes

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

Probieren Sie es online!

Ein vollständiges Programm zum Beispiel ["7h","Ks"],["4s","Ts"], das Null ausgibt, wenn beide Spieler ziehen, positiv, wenn Spieler 1 gewinnt, und negativ, wenn Spieler 2 gewinnt.

Nick Kennedy
quelle
2

C (gcc) , 172 167 165 164 Bytes

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

Probieren Sie es online!

Dank @ceilingcat 2 Bytes weg rasiert!

Grundsätzlich ein Port von @ Joels Python3-Lösung, aber ohne die base18-Codierung. Erwartet die Eingabe als eine Zeichenfolge mit einem Leerzeichen zwischen den Händen der beiden Spieler und gibt eine Ganzzahl aus, die positiv, negativ oder null ist, um anzuzeigen, dass Spieler 1 gewinnt, Spieler 2 gewinnt oder ob es sich um ein Unentschieden handelt.

G. Sliepen
quelle
2

Perl 6 , 101 100 94 88 Bytes

-1 Byte danke an Jo King

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

Probieren Sie es online!

Übernimmt die Eingabe als f(((<J ♠>, <3 ♠>), (<10 ♠>, <K ♥>)))Verwendung10 Ten. Gibt einen Wert <0 zurück, wenn Spieler 1 gewinnt,> 0, wenn Spieler 2 gewinnt, 0, wenn es ein Unentschieden ist.

Erläuterung

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

Kohle , 97 Bytes

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

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Nimmt Eingaben als zwei Zeichenfolgen mit 4 Zeichen an QcKc 6d4dund gibt eine Ganzzahl mit Vorzeichen aus. Erläuterung:

≔”)¶&sNψU↓”ζ

Komprimierte Zeichenfolge 2345678903889repräsentiert die Kartenwerte.

F¹³F¹³

Schleife über jedes mögliche Wertepaar.

F⁻⁴⁼ικ

Schlinge über jede mögliche zweite Kartenfarbe. Ohne Einschränkung der Allgemeinheit können wir davon ausgehen, dass die erste Karte Farbe 3 hat, sodass die zweite Kartenfarbe im Bereich von 0 bis 3 liegen kann, sofern die Werte nicht gleich sind. In diesem Fall kann sie nur im Bereich von 0 bis 2 liegen.

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

Berechnen Sie die geänderte Punktzahl der Hand, dh den doppelten Wert der Hand plus 1, wenn die Farben gleich sind (dh die zweite Karte hat Farbe 3).

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

Die komprimierte Zeichenfolge 23456789TJQKArepräsentiert die Kartenzeichen. Die Eingabekarten werden in dieser Zeichenfolge nachgeschlagen und dann wird die Position verwendet, um in die erste Zeichenfolge zu indexieren, um den Wert der Karte zu erhalten.

≔⁰δ

Initialisiere das Ergebnis auf 0.

F⟦θη⟧

Schlaufe über die beiden Hände.

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

Berechnen Sie die modifizierte Punktzahl der Hand und damit deren Häufigkeit und subtrahieren Sie das Ergebnis davon.

Iδ

Frequenzdifferenz ausgeben.

Neil
quelle
0

Perl 5 -p , 107 Bytes

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

Probieren Sie es online!

Eingang:

As 4d,Th 8c

(Tatsächlich kann das Komma ein beliebiges Zeichen sein.)

Ausgabe:

-1  Player one wins
 0  Draw
 1  Player two wins
Xcali
quelle