Нічого, як хороша гра ModTen


27

Відмова: ModTen - це вигадана карткова гра, створена для єдиної мети цього завдання.

Правила ModTen

ModTen грається зі стандартною колодою на 52 картки. Оскільки повні правила ще не винайдені, ми зупинимося лише на ранжируванні рук.

Джек і Три, підходить

Переможна рука в ModTen. Графіка з Вікіпедії .

Значення карт

Картки мають такі значення:

  • 2 - 9 : варто їх номіналу
  • Десять : 0 балів
  • Джек : 3 бали
  • Королева або Король : 8 балів
  • Туз : 9 балів

Значення рук

  • ModTen рука складається з двох карт . Базове значення руки отримується шляхом множення значення обох карт разом і збереження лише останньої цифри (тобто застосування модуля 10).

    6(7×8)мод10=6

  • Єдине інше правило в ModTen - це те, що відповідні карти коштують більше, ніж непридатні. За умовою, ми збираємось додати значення "s", якщо обидві картки мають однаковий костюм.

    Наприклад, значення 9 ♠ - 5 ♠ буде зазначено як " ", тому що і картки підходять.5с(9×5)мод10=5

Рейтинг рук та переможець

Наведені вище правила призводять до 18 різних рангових позицій, які узагальнені в наступній таблиці, від найсильнішого до найнижчого (або найрідкіснішого до найбільш поширеного). Ймовірності наведені лише для інформації.

Давши дві руки, перемагає рука з найнижчим рангом. Якщо обидві руки мають однаковий ранг, то це нічия (немає розриву краватки).

 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%

Змагання

Враховуючи дві руки ModTen , виведіть одне з трьох послідовних значень на ваш вибір, щоб сказати, чи:

  • виграє перший гравець
  • виграє другий гравець
  • це нічия

Діють такі правила:

  • Карта повинна бути описана його рангу в верхньому регістрі ( 2, 3, ..., 9, T, J,Q , Kабо A) , а потім його костюм в нижньому регістрі ( c, d, hабо s, для трефи, бубни, черви й лопатами).
  • Ви можете використовувати "10"замість цього, "T"але будь-яка інша заміна заборонена.
  • Поки дотримуються вищезазначені правила, ви можете взяти руки в будь-якому розумному та однозначному форматі. Вам дозволяється приймати звання і костюм як два різних символи, а не одну строку.

    Деякі допустимі вхідні формати:

    • "7c Qh 8s Ks"
    • [["7c","Qh"], ["8s","Ks"]]
    • [[['7','c'], ['Q','h']], [['8','s'], ['K','s']]]
    • тощо.
  • Замість використання 3 послідовних відмінних значень ваш вихід може також бути від'ємним , позитивним або нульовим . Вкажіть, будь ласка, формат виводу, використаний у вашій відповіді.

  • Це .

Тестові кейси

Гравець 1 перемагає

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

Гравець 2 виграє

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

Малюємо

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

А як же брати переписки як вхідні дані? Haskell має досить потужну систему типу ; Я впевнений, що щось подібне можна було б зробити безпосередньо в ньому.
wizzwizz4

Це не Хаскелл, але було {{J, s}, {3, s}}б добре?
wizzwizz4

1
@ wizzwizz4 Так, це добре.
Арнольд

2
Це може бути зрозуміліше, якщо "руки карт із відповідними костюмами" замість "підходящих карт".
chrylis -на страйк-

Відповіді:


13

Python 3 , 114 110 байт

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]

Спробуйте в Інтернеті!

@Arnauld запропонував ідею об'єднання значень карт і рядків таблиці таблиць. Після кількох спроб мені вдалося створити об'єднаний рядок R="T 2J45UNK9RL<3SLM;QAK:O>=/678", який має таку ж довжину, що і початковий рядок значення картки. Підрядки R[6:25]="UNK9RL<3SLM;QAK:O>=/"служать в якості таблиці рангу, а також довідкової таблиці значень карти для 3, 9, A, K, і Q. Розшифровка ASCII значення нової таблиці рангів має той же ефект ранжирування, що і попередня таблиця рангів.

Використовуючи рядки байтів як вхід, зберігається 4 байти.

Використання cmpв Python 2 може зменшити розчин до 102 байт, як показано рішення @ xnor .


Python 3 , 165 142 130 129 байт

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

Спробуйте в Інтернеті!

-23 байти завдяки @Jonathan Allan

-2 байти завдяки @ovs

-1 байт завдяки @mypetlion

Безголівки:

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

Функція fбере два аргументи, що представляють руку гравця 1 та гравця 2. Він повертає додатне, негативне або нульове значення у випадку перемоги гравця 1, виграшу гравця 2 або нічиї відповідно. Кожна рука кодується як один рядок, наприклад, "7cQh".


3
Привіт Джоел, ласкаво просимо до CGCC! Дуже розумна ідея розділити масив рейтингу рук на два! Продовжуйте їх!
640 Кб

1
@Jonathan Allan Дякую Я включив вашу ідею, використовуючи дещо інші підходи.
Джоель

1
Ви можете зберегти 2 байти, зберігаючи таблицю рангів в одному рядку:"HC92FA51GAB4E893D760"[s==t::2]
ов

1
І ще на 4 байти коротше, якщо ви бажаєте перейти на Python 2. ( cmpнедоступно в Python 3)
вів

1
Ви можете використовувати str.findзамість того, str.indexщоб зберегти один байт. Єдина різниця в поведінці між двома методами полягає в тому, що indexвидає помилку, коли елемент не знайдено, а findповертається -1. Отже, це не буде проблемою для вашого коду.
mypetlion

11

x86-16 збірка, 87 83 байти

Двійковий:

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

Не зібрано:

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

Введення є таким же рядком, як Js3sKsKh, за вказівником у SI. Результатом є ZF = 0 and SF = OF(тест з JG), якщо гравець 1 переможе, SF ≠ OF(тест з JL), якщо гравець 2 виграє або ZF(тест з JE), якщо нічия.

Вихід за допомогою тестової програми DOS:

введіть тут опис зображення

Завантажте та протестуйте MODTEN.COM для DOS.


7

05AB1E , 41 37 байт

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

-4 байти завдяки @Grimy .

Введіть як список списку символів, як третій приклад формату введення в описі завдання. Тобто P1 7c Qhі P2 8s Ksбудуть введені як [[["7","c"],["Q","h"]],[["8","s"],["K","s"]]]. (І використовує "10"для 10.)

Виводить від’ємне ціле число, якщо гравець 1 виграє; додатне ціле число, якщо гравець 2 виграє; або 0, якщо це нічия.

Спробуйте в Інтернеті або перевірте всі тестові випадки .

Пояснення:

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)

Дивіться цей 05AB1E наконечник шахти (розділи Як користуватися словником? Як стиснути великі цілі числа? І Як стиснути цілі списки? ) , Щоб зрозуміти , чому •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"і ŽćSце 39808.


Питання прямо дозволяє прийняти введення Tяк таке 10, тож ви можете просто скинути Tз JTQKA(і використовувати стиснене ціле число 3889 замість 30889). Також T* ... +може бути ... «.
Grimmy

1
10T10нмод10=0T*...+...«

1
37 (зараз насправді працює!)
Гриммі

@Grimy Ах, приємно користуватися таким словником!
Kevin Cruijssen

3

PHP ,212 185 178 149 байт

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

Спробуйте в Інтернеті!

  • -7 байт завдяки @ Night2!
  • -29 байт кодуванням ASCII таблиці замість масиву

Введення здійснюється через командний рядок. Вихід на STDOUTце негативний , якщо гравець 1 виграє, позитивний , якщо гравець 2 виграє, 0якщо краватку. Приклад:

$ php modten.php Js3s KsKh
-1

1
@ Night2 Я вважаю, що якби я був готовий надати нам оператора космічного корабля (я маю на увазі, як часто ви користуєтеся цим?), Я міг би байти і просто повернути мінус, позитив або нуль замість -1, 1або 0.
640 Кб

Я був здивований (гарним чином), побачивши оператора космічного корабля в попередній відповіді.
Ніч2

2

Желе , 46 байт

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

Спробуйте в Інтернеті!

Повна програма, яка бере в якості аргументу, наприклад, ["7h","Ks"],["4s","Ts"]та друкує нуль, якщо обидва гравці нічия, позитивне, якщо гравець 1 перемагає, і негативне, якщо гравець 2 перемагає.


2

C (gcc) , 172 167 165 164 байт

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

Спробуйте в Інтернеті!

2 байти поголилися завдяки @ceilingcat!

В основному це порт рішення Joel's Python3, але без кодування base18. Очікує введення як один рядок з пробілом, який розділяє руки двох гравців, і виводить ціле число, яке є додатним, від'ємним або нульовим, щоб вказати на перемогу гравця 1, гравця 2 перемоги або якщо це нічия.


2

Perl 6 , 101 100 94 88 байт

-1 байт завдяки Джо Кінгу

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

Спробуйте в Інтернеті!

Приймає введення як f(((<J ♠>, <3 ♠>), (<10 ♠>, <K ♥>)))використання 10для Ten. Повертає значення <0, якщо гравець 1 перемагає,> 0, якщо гравець 2 перемагає, 0, якщо це нічия.

Пояснення

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

Вугілля деревне , 97 байт

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

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Приймає вхід як два рядки з 4 символів, наприклад, QcKc 6d4dі виводить підписане ціле число. Пояснення:

≔”)¶&sNψU↓”ζ

Стислий рядок 2345678903889представляє значення карт.

F¹³F¹³

Переведіть петлю на кожну можливу пару значень.

F⁻⁴⁼ικ

Переведіть петлю на кожен можливий костюм другої картки. Без втрати загальності можна припустити, що перша картка має костюм 3, тому костюм другої картки може становити від 0 до 3, якщо значення не однакові, і в цьому випадку вона може становити лише від 0 до 2.

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

Обчисліть модифікований бал руки, який є значенням руки вдвічі, плюс 1, якщо костюми однакові (тобто друга карта має костюм 3).

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

Стислий рядок 23456789TJQKAпредставляє символи картки. Карти вводу переглядаються в цій рядку, а потім позиція використовується для індексації до першого рядка для отримання значення картки.

≔⁰δ

Ініціалізуйте результат до 0.

F⟦θη⟧

Петлю над двома руками.

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

Обчисліть модифіковану оцінку руки, а значить, її частоту, і відніміть результат від цього.

Iδ

Виведіть різницю частот.



0

Perl 5 -p , 107 байт

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

Спробуйте в Інтернеті!

Вхід:

As 4d,Th 8c

(Насправді комою може бути будь-який символ.)

Вихід:

-1  Player one wins
 0  Draw
 1  Player two wins
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.