Ничего подобного хорошей старой игре ModTen

27

Отказ от ответственности: ModTen это вымышленная карточная игра, которая была создана с единственной целью этого испытания.

Правила ModTen

В ModTen играют стандартной колодой из 52 карт. Поскольку полные правила еще не изобретены, мы сосредоточимся исключительно на ранжировании рук.

Jack & Three, подходит

Выигрышная комбинация в ModTen. Графика из Википедии .

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

Карты имеют следующие значения:

  • 2 до 9 : стоит их номинал
  • Десять : 0 баллов
  • Джек : 3 очка
  • Королева или король : 8 очков
  • Ace : 9 очков

Ручные ценности

  • ModTen рука состоит из двух карт . Базовое значение руки получается умножением стоимости обеих карт и сохранением только последней цифры (т. Е. Применением по модулю 10).

    Например, значение 7 ♥ - Q ♣ равно « », потому что .6(7×8)mod10=6

  • Единственное другое правило в ModTen состоит в том, что подходящие карты стоят больше, чем не подходящие. По соглашению мы добавим «s» к значению, если обе карты одной масти.

    Например, значение 9 ♠ - 5 ♠ будет отмечено как « », потому что и карты подходят.5s(9×5)mod10=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"]
Arnauld
источник
Как насчет принятия перечислений в качестве входных данных? У Haskell довольно мощная система типов ; Я уверен, что что-то подобное можно сделать прямо в нем.
wizzwizz4
Это не Хаскелл, но все {{J, s}, {3, s}}будет в порядке?
wizzwizz4
1
@ wizzwizz4 Да, все в порядке.
Арно
2
Это может быть понятнее с «руками карт с одинаковыми мастями» вместо «карт с одной мастью».
Хрилис - на забастовку -

Ответы:

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 байта благодаря Джонатану Аллану

-2 байта благодаря @ovs

-1 байт благодаря @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])

Функция fпринимает два аргумента, представляющих руку игрока 1 и игрока 2. Она возвращает положительное, отрицательное или нулевое значение в случае выигрыша игрока 1, выигрыша игрока 2 или ничьи, соответственно. Каждая рука закодирована как одна строка, например, «7cQh».

Joel
источник
3
Привет Джоэл, добро пожаловать в CGCC! Очень умная идея разбить массив рангов рук на две части! Продолжай!
640 КБ,
1
@ Джонатан Аллан Спасибо. Я включил вашу идею, используя несколько разные подходы.
Джоэл
1
Вы можете сохранить 2 байта, сохранив таблицу рангов в одной строке:"HC92FA51GAB4E893D760"[s==t::2]
ovs
1
И еще на 4 байта короче, если вы хотите перейти на Python 2. ( cmpнедоступно в Python 3)
ovs
1
Вы можете использовать str.findвместо того, str.indexчтобы сохранить один байт. Единственное различие в поведении между этими двумя методами состоит в том, что indexвыдает ошибку, когда элемент не найден, а findвозвращает -1. Так что это не будет проблемой для вашего кода.
Mypetlion
11

Сборка x86-16, 87 83 байта

Binary:

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.

640 КБ
источник
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* ... +может быть ... «.
Гримми
1
@ Грими А, я действительно знал, что 10вместо этого Tразрешено, но не думал о ! И то , что я вижу сейчас, очевидно ...>.> Спасибо! 10nmod10=0T*...+...«
Кевин Круйссен
1
37 (сейчас действительно работает!)
Grimmy
@Grimy Ах, как хорошо использовать словарь!
Кевин Круйссен
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
640 КБ
источник
1
@ Night2 Полагаю, если бы я хотел дать нам оператор космического корабля (я имею в виду, как часто вы его используете?), Я мог бы -2 байта и просто вернуть отрицательный, положительный или ноль вместо -1, 1или 0.
640KB
Я был поражен (в хорошем смысле) видеть оператора космического корабля в предыдущем ответе.
Night2
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для десяти. Возвращает значение <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
    ]
  }
}
nwellnhof
источник
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
Xcali
источник