Ничего подобного хорошей старой игре 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"]

Как насчет принятия перечислений в качестве входных данных? У 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».


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.


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

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

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.