Không có gì giống như một trò chơi hay của ModTen


27

Disclaimer: ModTen là một trò chơi thẻ hư cấu được tạo ra cho mục đích duy nhất của thử thách này.

Các quy tắc của ModTen

ModTen được chơi với bộ bài 52 lá tiêu chuẩn. Bởi vì các quy tắc đầy đủ vẫn chưa được phát minh, chúng tôi sẽ chỉ tập trung vào xếp hạng tay.

Jack & Three, phù hợp

Một tay chiến thắng trong ModTen. Đồ họa từ Wikipedia .

Giá trị thẻ

Các thẻ có các giá trị sau:

  • 2 đến 9 : giá trị mệnh giá của họ
  • Mười : 0 điểm
  • Jack : 3 điểm
  • Nữ hoàng hoặc vua : 8 điểm
  • Ace : 9 điểm

Giá trị tay

  • Một tay ModTen được làm bằng hai thẻ . Giá trị cơ bản của một bàn tay có được bằng cách nhân giá trị của cả hai thẻ với nhau và chỉ giữ chữ số cuối cùng (tức là áp dụng modulo 10).

    6(7×số 8)mod10= =6

  • Quy tắc duy nhất khác trong ModTencác thẻ phù hợp có giá trị cao hơn các thẻ không được sử dụng. Theo quy ước, chúng tôi sẽ nối thêm "s" vào giá trị nếu cả hai thẻ đều phù hợp.

    Chẳng hạn, giá trị của 9 - 5 sẽ được ghi chú là " ", bởi vì và các thẻ phù hợp.5S(9×5)mod10= =5

Xếp hạng tay và người chiến thắng

Các quy tắc trên dẫn đến 18 cấp bậc khác nhau được tóm tắt trong bảng sau, từ mạnh nhất đến thấp nhất (hoặc hiếm nhất đến phổ biến nhất). Các xác suất được đưa ra chỉ cho thông tin.

Đưa ra hai tay, tay nào có thứ hạng thấp nhất sẽ thắng. Nếu cả hai tay có cùng cấp bậc thì đó là một trận hòa (không có bộ ngắt kết nối).

 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%

Các thách thức

Đưa ra hai tay ModTen , xuất ra một trong ba giá trị nhất quán mà bạn chọn để biết liệu:

  • người chơi đầu tiên thắng
  • người chơi thứ hai thắng
  • đó là một trận hòa

Các quy tắc sau được áp dụng:

  • Một thẻ phải được mô tả bởi thứ hạng của nó trong trường hợp trên ( 2, 3, ..., 9, T, J, Q, Khoặc A) tiếp theo là phù hợp với mình trong trường hợp thấp hơn ( c, d, hhoặc s, đối với câu lạc bộ, kim cương, trái tim và Spades).
  • Bạn có thể sử dụng "10"thay vì "T"nhưng bất kỳ sự thay thế nào khác đều bị cấm.
  • Miễn là tuân theo các quy tắc trên, bạn có thể nắm trong tay bất kỳ định dạng hợp lý và rõ ràng nào. Bạn được phép lấy thứ hạng và bộ đồ làm hai ký tự riêng biệt thay vì một chuỗi.

    Một số định dạng đầu vào hợp lệ là:

    • "7c Qh 8s Ks"
    • [["7c","Qh"], ["8s","Ks"]]
    • [[['7','c'], ['Q','h']], [['8','s'], ['K','s']]]
    • v.v.
  • Thay vì sử dụng 3 giá trị riêng biệt nhất quán, đầu ra của bạn cũng có thể âm , dương hoặc bằng không . Vui lòng chỉ định định dạng đầu ra được sử dụng trong câu trả lời của bạn.

  • Đây là .

Các trường hợp thử nghiệm

Người chơi 1 thắng

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

Người chơi thắng 2

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

Vẽ tranh

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

Điều gì về việc lấy enums làm đầu vào? Haskell có một hệ thống loại khá mạnh mẽ ; Tôi khá chắc chắn một cái gì đó như thế này có thể được thực hiện trực tiếp trong đó.
wizzwizz4

Đây không phải là Haskell, nhưng sẽ {{J, s}, {3, s}}ổn chứ?
wizzwizz4

1
@ wizzwizz4 Vâng, điều đó tốt.
Arnauld

2
Điều này có thể rõ ràng hơn với "tay bài với bộ đồ phù hợp" thay vì "thẻ phù hợp".
chrylis -on đình công-

Câu trả lời:


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]

Hãy thử trực tuyến!

@Arnauld đề xuất ý tưởng hợp nhất giá trị thẻ và chuỗi bảng xếp hạng. Sau một số lần thử, tôi đã xoay sở để tạo ra một chuỗi hợp nhất R="T 2J45UNK9RL<3SLM;QAK:O>=/678", có cùng độ dài với chuỗi giá trị thẻ gốc. Các chuỗi R[6:25]="UNK9RL<3SLM;QAK:O>=/"phục vụ như là bảng thứ hạng cũng như một bảng tra cứu giá trị thẻ cho 3, 9, A, K, và Q. Giải mã giá trị ASCII của bảng xếp hạng mới có hiệu ứng xếp hạng tương tự như bảng xếp hạng trước đó.

Sử dụng chuỗi byte làm đầu vào tiết kiệm 4 byte.

Sử dụng cmptrong Python 2 có thể giảm giải pháp xuống 102 byte, như thể hiện bởi giải pháp của @ 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])

Hãy thử trực tuyến!

-23 byte nhờ @Jonathan Allan

-2 byte nhờ @ovs

-1 byte nhờ @mypetlion

Ung dung:

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

Hàm fnày có hai đối số đại diện cho tay của người chơi 1 và người chơi 2. Nó trả về giá trị dương, âm hoặc bằng 0 trong trường hợp người chơi 1 thắng, người chơi thắng 2 hoặc hòa, tương ứng. Mỗi tay được mã hóa dưới dạng một chuỗi, ví dụ "7cQh".


3
Xin chào Joel, chào mừng bạn đến với CGCC! Ý tưởng rất thông minh chia mảng xếp hạng tay trong hai! Hãy tiếp tục!
640KB

1
@Jonathan Allan Cảm ơn. Tôi đã kết hợp ý tưởng của bạn bằng cách sử dụng các phương pháp hơi khác nhau.
Joel

1
Bạn có thể lưu 2 byte bằng cách lưu trữ bảng xếp hạng trong một chuỗi:"HC92FA51GAB4E893D760"[s==t::2]
ovs

1
ngắn hơn 4 byte nếu bạn sẵn sàng chuyển sang Python 2. ( cmpkhông có sẵn trong Python 3)
17:51

1
Bạn có thể sử dụng str.findthay vì str.indexđể lưu một byte. Sự khác biệt duy nhất về hành vi giữa hai phương thức là indexđưa ra lỗi khi phần tử không được tìm thấy, trong khi findtrả về -1. Vì vậy, nó sẽ không phải là một vấn đề cho mã của bạn.
mypetlion

11

hội x86-16, 87 83 byte

Nhị phân:

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

Chưa được lắp ráp:

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

Đầu vào là một chuỗi như Js3sKsKh, tại con trỏ trong SI. Đầu ra là ZF = 0 and SF = OF(thử với JG) nếu người chơi 1 thắng, SF ≠ OF(thử với JL) nếu người chơi 2 thắng hoặc ZF(thử với JE) nếu hòa.

Đầu ra sử dụng chương trình thử nghiệm DOS:

nhập mô tả hình ảnh ở đây

Tải xuống và kiểm tra MODTEN.COM cho DOS.


7

05AB1E , 41 37 byte

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

-4 byte nhờ @Grimy .

Nhập dưới dạng danh sách danh sách các ký tự, như định dạng nhập ví dụ thứ ba trong mô tả thử thách. Tức là P1 7c Qh& P2 8s Kssẽ là đầu vào như [[["7","c"],["Q","h"]],[["8","s"],["K","s"]]]. (Và sử dụng "10"cho 10.)

Xuất ra một số nguyên âm nếu người chơi 1 thắng; một số nguyên dương nếu người chơi 2 thắng; hoặc 0 nếu đó là một trận hòa.

Hãy thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình:

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)

Xem 05AB1E mẹo này của tôi (phần Làm thế nào để sử dụng từ điển? Làm thế nào để nén các số nguyên lớn?Làm thế nào để liệt kê số nguyên nén? ) Để hiểu tại sao •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", và ŽćS39808.


Câu hỏi rõ ràng cho phép lấy đầu vào T10, vì vậy bạn chỉ có thể thả Ttừ JTQKA(và sử dụng số nguyên nén 3889 thay vì 30889). Ngoài ra, T* ... +có thể được ... «.
Grimmy

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

1
37 (bây giờ thực sự hoạt động!)
Grimmy

@Grimy Ah, sử dụng từ điển tốt đẹp như thế!
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};

Hãy thử trực tuyến!

  • -7 byte nhờ @ Night2!
  • -29 byte bằng ASCII mã hóa bảng thay vì mảng

Đầu vào là thông qua dòng lệnh. Đầu ra STDOUTâm nếu người chơi 1 thắng, dương nếu người chơi 2 thắng, 0nếu hòa. Thí dụ:

$ php modten.php Js3s KsKh
-1

1
@ Night2 Tôi cho rằng nếu tôi sẵn sàng cung cấp cho chúng tôi toán tử tàu vũ trụ (ý tôi là, bạn có thường xuyên sử dụng nó không?), Tôi có thể -2 byte và chỉ trả về âm, dương hoặc bằng 0, thay vì -1, 1hoặc 0.
640KB

Tôi đã rất ngạc nhiên (một cách tốt) khi thấy người vận hành tàu vũ trụ trong câu trả lời trước.
Đêm 2

2

Thạch , 46 byte

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

Hãy thử trực tuyến!

Một chương trình đầy đủ lấy ví dụ như đối số của nó ["7h","Ks"],["4s","Ts"]và in số 0 nếu cả hai người chơi hòa, tích cực nếu người chơi 1 thắng và âm nếu người chơi 2 thắng.


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

Hãy thử trực tuyến!

2 byte bị loại bỏ nhờ @ceilingcat!

Về cơ bản là một cổng của giải pháp Python3 của @ Joel, nhưng không có mã hóa base18. Yêu cầu đầu vào là một chuỗi có khoảng cách ngăn cách tay của hai người chơi và đưa ra một số nguyên dương, âm hoặc bằng 0 để chỉ ra người chơi 1 thắng, người chơi 2 thắng hoặc nếu đó là hòa.


2

Perl 6 , 101 100 94 88 byte

-1 byte nhờ Jo King

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

Hãy thử trực tuyến!

Có đầu vào như f(((<J ♠>, <3 ♠>), (<10 ♠>, <K ♥>)))sử dụng 10cho Mười. Trả về giá trị <0 nếu người chơi 1 thắng,> 0 nếu người chơi 2 thắng, 0 nếu đó là hòa.

Giải trình

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

Than , 97 byte

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

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Lấy đầu vào là hai chuỗi gồm 4 ký tự, ví dụ QcKc 6d4dvà xuất ra một số nguyên đã ký. Giải trình:

≔”)¶&sNψU↓”ζ

Chuỗi nén 2345678903889đại diện cho các giá trị thẻ.

F¹³F¹³

Lặp lại trên mỗi cặp giá trị có thể.

F⁻⁴⁼ικ

Vòng qua mỗi bộ đồ thẻ thứ hai có thể. Không mất tính tổng quát, chúng ta có thể giả sử rằng thẻ thứ nhất có bộ 3, vì vậy bộ thẻ thứ hai có thể nằm trong khoảng từ 0 đến 3 trừ khi các giá trị giống nhau trong trường hợp nó chỉ có thể nằm trong khoảng từ 0 đến 2.

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

Tính số điểm đã sửa đổi của tay, là giá trị của bàn tay nhân đôi, cộng thêm 1 nếu các bộ đồ giống nhau (ví dụ thẻ thứ hai có bộ 3).

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

Chuỗi nén 23456789TJQKAđại diện cho các ký tự thẻ. Các thẻ đầu vào được tra cứu trong chuỗi này và sau đó vị trí được sử dụng để lập chỉ mục vào chuỗi đầu tiên để lấy giá trị của thẻ.

≔⁰δ

Khởi tạo kết quả về 0.

F⟦θη⟧

Vòng qua hai tay.

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

Tính số điểm đã sửa đổi của bàn tay, và do đó tần số của bàn tay và trừ kết quả từ điều này.

Iδ

Xuất ra sự khác biệt tần số.



0

Perl 5 -p , 107 byte

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

Hãy thử trực tuyến!

Đầu vào:

As 4d,Th 8c

(Trên thực tế, dấu phẩy có thể là bất kỳ ký tự nào.)

Đầu ra:

-1  Player one wins
 0  Draw
 1  Player two wins
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.