Tidak seperti permainan ModTen yang bagus

27

Penafian: ModTen adalah permainan kartu fiksi yang dibuat untuk tujuan tunggal tantangan ini.

Aturan ModTen

ModTen dimainkan dengan dek 52 kartu standar. Karena aturan lengkap belum ditemukan, kita akan fokus pada peringkat tangan secara eksklusif.

Jack & Three, cocok

Kemenangan di ModTen. Grafik dari Wikipedia .

Nilai kartu

Kartu memiliki nilai-nilai berikut:

  • 2 hingga 9 : layak nilai nominalnya
  • Sepuluh : 0 poin
  • Jack : 3 poin
  • Ratu atau Raja : 8 poin
  • As : 9 poin

Nilai tangan

  • Kartu ModTen dibuat dari dua kartu . Nilai dasar tangan diperoleh dengan mengalikan nilai kedua kartu bersama-sama dan menjaga digit terakhir saja (yaitu menerapkan modulo 10).

    6(7×8)mod10=6

  • Satu-satunya aturan lain di ModTen adalah kartu yang cocok bernilai lebih dari yang tidak cocok. Dengan konvensi, kita akan menambahkan "s" ke nilai jika kedua kartu memiliki jenis yang sama.

    Misalnya, nilai 9 ♠ - 5 ♠ akan dicatat sebagai " ", karena dan kartunya cocok.5s(9×5)mod10=5

Peringkat tangan dan pemenang

Aturan di atas menghasilkan 18 peringkat tangan yang berbeda yang dirangkum dalam tabel berikut, dari yang terkuat hingga terendah (atau terlangka hingga paling umum). Probabilitas diberikan hanya untuk informasi.

Diberi dua tangan, tangan dengan pangkat terendah menang. Jika kedua tangan memiliki peringkat yang sama, maka itu seri (tidak ada 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%

Tantangan

Diberi dua tangan ModTen , hasilkan satu dari tiga nilai konsisten pilihan Anda untuk mengetahui apakah:

  • pemain pertama menang
  • pemain kedua menang
  • ini seri

Aturan berikut ini berlaku:

  • Kartu harus dijelaskan oleh peringkatnya dalam huruf ( 2, 3, ..., 9, T, J, Q, Katau A) diikuti dengan suit dalam huruf kecil ( c, d, hatau s, untuk klub, berlian, hati dan sekop).
  • Anda dapat menggunakan "10"alih-alih "T"tetapi pengganti lainnya dilarang.
  • Selama aturan di atas diikuti, Anda dapat mengambil tangan dalam format yang masuk akal dan tidak ambigu. Anda diizinkan untuk mengambil peringkat dan setelan sebagai dua karakter berbeda daripada satu string.

    Beberapa format input yang valid adalah:

    • "7c Qh 8s Ks"
    • [["7c","Qh"], ["8s","Ks"]]
    • [[['7','c'], ['Q','h']], [['8','s'], ['K','s']]]
    • dll.
  • Alih-alih menggunakan 3 nilai berbeda yang konsisten, output Anda mungkin juga negatif , positif atau nol . Silakan tentukan format output yang digunakan dalam jawaban Anda.

  • Ini adalah .

Uji kasus

Pemain 1 menang

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

Pemain 2 menang

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

Seri

["Js","3s"], ["3d","Jd"]
["Ah","Ac"], ["3d","9s"]
["Qc","Kc"], ["6d","4d"]
["2d","3d"], ["3s","2s"]
["Ts","9c"], ["4h","5d"]
Arnauld
sumber
Bagaimana dengan mengambil enum sebagai masukan? Haskell memiliki sistem tipe yang cukup kuat ; Saya cukup yakin sesuatu seperti ini bisa dibuat langsung di dalamnya.
wizzwizz4
Ini bukan Haskell, tapi tidak {{J, s}, {3, s}}apa-apa?
wizzwizz4
1
@ wizzwizz4 Ya, tidak apa-apa.
Arnauld
2
Ini mungkin lebih jelas dengan "tangan kartu dengan pakaian yang cocok" daripada "kartu yang cocok".
chrylis -on strike-

Jawaban:

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]

Cobalah online!

@Arnauld mengusulkan ide untuk menggabungkan nilai kartu dan string tabel peringkat. Setelah beberapa upaya saya berhasil membuat string yang digabungkan R="T 2J45UNK9RL<3SLM;QAK:O>=/678", yang memiliki panjang yang sama dengan string nilai kartu asli. Substring R[6:25]="UNK9RL<3SLM;QAK:O>=/"berfungsi sebagai meja peringkat serta nilai kartu tabel untuk 3, 9, A, K, dan Q. Decoding nilai ASCII dari tabel peringkat baru memiliki efek peringkat yang sama dengan tabel peringkat sebelumnya.

Menggunakan string byte sebagai input menghemat 4 byte.

Menggunakan cmpdalam Python 2 dapat mengurangi solusi hingga 102 byte, seperti yang ditunjukkan oleh solusi @ xnor .


Python 3 , 165 142 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])

Cobalah online!

-23 byte terima kasih kepada @Jonathan Allan

-2 byte terima kasih kepada @ovs

-1 byte terima kasih kepada @mypetlion

Tidak Disatukan:

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

Fungsi ini fmengambil dua argumen yang mewakili tangan pemain 1 dan pemain 2. Ia mengembalikan nilai positif, negatif, atau nol dalam kasus kemenangan pemain 1, kemenangan pemain 2, atau hasil seri. Setiap tangan dikodekan sebagai string tunggal, misalnya "7cQh".

Joel
sumber
3
Hai Joel, selamat datang di CGCC! Ide yang sangat pintar membelah array peringkat tangan menjadi dua! Terus mereka datang!
640KB
1
@ Jonathan Allan Terima kasih. Saya telah memasukkan ide Anda menggunakan pendekatan yang sedikit berbeda.
Joel
1
Anda dapat menyimpan 2 byte dengan menyimpan tabel peringkat dalam satu string:"HC92FA51GAB4E893D760"[s==t::2]
Ov
1
Dan 4 byte lainnya lebih pendek jika Anda ingin beralih ke Python 2. ( cmptidak tersedia dalam Python 3)
Ov
1
Anda dapat menggunakan str.findalih-alih str.indexmenyimpan satu byte. Satu-satunya perbedaan perilaku antara kedua metode adalah yang indexmelempar kesalahan ketika elemen tidak ditemukan, sementara findkembali -1. Jadi itu tidak akan menjadi masalah untuk kode Anda.
mypetlion
11

x86-16 Majelis, 87 83 byte

Biner:

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

Belum dirakit:

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

Input adalah sebagai string seperti Js3sKsKh, pada pointer di SI. Output adalah ZF = 0 and SF = OF(uji dengan JG) jika pemain 1 menang, SF ≠ OF(uji dengan JL) jika pemain 2 menang atau ZF(uji dengan JE) jika seri.

Output menggunakan program uji DOS:

masukkan deskripsi gambar di sini

Unduh dan uji MODTEN.COM untuk DOS.

640KB
sumber
7

05AB1E , 41 37 byte

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

-4 byte terima kasih kepada @Grimy .

Input sebagai daftar daftar karakter, seperti contoh format input ketiga dalam deskripsi tantangan. Yaitu P1 7c Qh& P2 8s Ksakan menjadi input sebagai [[["7","c"],["Q","h"]],[["8","s"],["K","s"]]]. (Dan kegunaan "10"untuk 10.)

Menghasilkan bilangan bulat negatif jika pemain 1 menang; bilangan bulat positif jika pemain 2 menang; atau 0 jika itu seri.

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

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)

Lihat tip tambang 05AB1E ini (bagian Bagaimana cara menggunakan kamus? Cara kompres bilangan bulat besar? Dan Cara daftar bilangan bulat kompres? ) Untuk memahami mengapa•V›{₆Ÿ&∊WÍj¸•adalah36742512464916394906012008,•V›{₆Ÿ&∊WÍj¸•19вadalah[18,10,16,6,17,12,15,10,14,7,13,3,11,2,11,5,9,4,8,1],‘ߌQ‘adalah"JAKEQ", danŽćSini39808.

Kevin Cruijssen
sumber
Pertanyaannya secara eksplisit memungkinkan mengambil input Tsebagai 10, jadi Anda bisa langsung saja drop Tdari JTQKA(dan menggunakan integer 3889 bukannya 30889). Juga, T* ... +bisa ... «.
Grimmy
1
10T10nmod10=0T*...+...«
1
37 (sekarang benar-benar berfungsi!)
Grimmy
@ Grimy Ah, penggunaan kamus yang bagus seperti itu!
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};

Cobalah online!

  • -7 byte terima kasih kepada @ Night2!
  • -29 bytes oleh ASCII yang mengkode tabel alih-alih array

Input melalui baris perintah. Output ke STDOUTadalah negatif jika pemain 1 menang, positif jika pemain 2 menang, 0jika dasi. Contoh:

$ php modten.php Js3s KsKh
-1
640KB
sumber
1
@ Night2 Saya kira jika saya bersedia memberi kami operator pesawat ruang angkasa (maksud saya, seberapa sering Anda bisa menggunakannya?), Saya bisa -2 byte dan hanya mengembalikan negatif, positif atau nol, bukan -1, 1atau 0.
640KB
Saya kagum (dalam cara yang baik) untuk melihat operator pesawat ruang angkasa di jawaban sebelumnya.
Night2
2

Jelly , 46 byte

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

Cobalah online!

Sebuah program penuh mengambil sebagai argumennya misalnya ["7h","Ks"],["4s","Ts"]dan mencetak nol jika kedua pemain menggambar, positif jika pemain 1 menang dan negatif jika pemain 2 menang.

Nick Kennedy
sumber
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);}

Cobalah online!

2 byte dicukur berkat @ceilingcat!

Pada dasarnya port dari solusi Python3 @ Joel, tetapi tanpa pengkodean base18. Mengharapkan input sebagai satu string dengan spasi yang memisahkan tangan kedua pemain, dan menghasilkan bilangan bulat yang positif, negatif atau nol untuk menunjukkan pemain 1 menang, pemain 2 menang atau jika itu seri.

G. Sliepen
sumber
2

Perl 6 , 101 100 94 88 byte

-1 byte terima kasih kepada Jo King

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

Cobalah online!

Mengambil input sebagai f(((<J ♠>, <3 ♠>), (<10 ♠>, <K ♥>)))gunakan 10untuk Sepuluh. Mengembalikan nilai <0 jika pemain 1 menang,> 0 jika pemain 2 menang, 0 jika itu seri.

Penjelasan

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

Arang , 97 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Mengambil input sebagai dua string 4 karakter, misalnya QcKc 6d4ddan mengeluarkan integer yang ditandatangani. Penjelasan:

≔”)¶&sNψU↓”ζ

String yang dikompresi 2345678903889mewakili nilai kartu.

F¹³F¹³

Simpulkan setiap kemungkinan pasangan nilai.

F⁻⁴⁼ικ

Lingkari setiap setelan kartu kedua yang mungkin. Tanpa kehilangan keumuman, kita dapat mengasumsikan bahwa kartu pertama memiliki setelan 3, sehingga setelan kartu kedua dapat berkisar dari 0 hingga 3 kecuali nilainya sama sehingga hanya berkisar dari 0 hingga 2.

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

Hitung skor tangan yang dimodifikasi, yang merupakan nilai tangan dua kali lipat, ditambah 1 jika suitnya sama (yaitu kartu kedua memiliki suit 3).

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

String terkompresi 23456789TJQKAmewakili karakter kartu. Kartu input dilihat dalam string ini dan kemudian posisi digunakan untuk mengindeks ke dalam string pertama untuk mendapatkan nilai kartu.

≔⁰δ

Inisialisasi hasilnya ke 0.

F⟦θη⟧

Lingkarkan kedua tangan.

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

Hitung skor tangan yang dimodifikasi, dan dengan demikian frekuensinya, dan kurangi hasilnya dari ini.

Iδ

Keluarkan perbedaan frekuensi.

Neil
sumber
0

Perl 5 -p , 107 byte

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

Cobalah online!

Memasukkan:

As 4d,Th 8c

(Sebenarnya, koma dapat berupa karakter apa saja.)

Keluaran:

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