ModTen'in iyi bir ol oyunu gibisi yok


27

Feragatname: ModTen, bu mücadelenin tek amacı için oluşturulmuş kurgusal bir kart oyunudur.

ModTen kuralları

ModTen standart 52 kart desteyle oynanır. Kuralların tamamı henüz icat edilmediğinden, yalnızca el sıralamasına odaklanacağız.

Jack & Three, uygun

ModTen'de kazanan bir el. Wikipedia'dan grafikler .

Kart değerleri

Kartlar aşağıdaki değerlere sahiptir:

  • 2 ila 9 : yüz değerlerine değer
  • On : 0 puan
  • Jack : 3 puan
  • Kraliçe veya Kral : 8 puan
  • Ace : 9 puan

El değerleri

  • Bir ModTen eli iki karttan yapılır . Bir elin temel değeri, her iki kartın değeri ile çarpılarak ve sadece son rakamı tutularak elde edilir (yani, bir modulo 10 uygulayarak).

    Örneğin, 7 ♥ - Q ♣ değeri " 6 " dır , çünkü (7x8)şık10=6 .

  • ModTen'deki tek kural , uygun kartların uygun olmayan kartlardan daha değerli olmasıdır. Her iki kart da aynı şekilde ise, konvansiyonel olarak değere bir "s" ekleyeceğiz .

    Örneğin, 9 ♠ - 5 ♠ değeri " 5s " olarak not edilecektir , çünkü (9x5)şık10=5 ve kartlar uygundur.

El sıralaması ve kazanan

Yukarıdaki kurallar, aşağıdaki tabloda özetlenen en güçlüden en alta (veya en nadir görülene) kadar 18 ayrı el rütbesiyle sonuçlanır. Olasılıklar sadece bilgi amaçlı verilmiştir.

İki el verildiğinde, en düşük dereceye sahip olan el kazanır. Eğer iki el de aynı değerdeyse, berabere çekilir (beraberlik kopmaz).

 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%

Meydan okuma

İki ModTen eli göz önüne alındığında , seçiminizi yapmak için seçtiğiniz üç tutarlı değerden birini verin:

  • ilk oyuncu kazanır
  • ikinci oyuncu kazanır
  • bu bir beraberlik

Aşağıdaki kurallar geçerlidir:

  • Bir kart harf sıralamaya tarafından tarif edilmelidir ( 2, 3, ..., 9, T, J, Q, Kveya A) küçük harflerle onun takım tarafından takip ( c, d, hveyas , kulüpleri, karo, kupa ve maça için).
  • Yerine kullanabilirsiniz "10", "T"ancak başka bir ikame yasaktır.
  • Yukarıdaki kurallara uyulduğu sürece, ellerinizi makul ve net bir biçimde alabilirsiniz. Rütbe ve kıyafeti tek bir dize yerine iki ayrı karakter olarak kabul etmenize izin verilir.

    Bazı geçerli giriş biçimleri:

    • "7c Qh 8s Ks"
    • [["7c","Qh"], ["8s","Ks"]]
    • [[['7','c'], ['Q','h']], [['8','s'], ['K','s']]]
    • vb.
  • Tutarlı 3 farklı değer kullanmak yerine, çıktınız da negatif , pozitif veya sıfır olabilir . Lütfen cevabınızda kullanılan çıktı biçimini belirtin.

  • Bu .

Test durumları

Oyuncu 1 kazanır

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

2. Oyuncu kazanır

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

Çekmek

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

Enumları girdi olarak almaya ne dersiniz? Haskell'in oldukça güçlü bir tür sistemi var ; Bunun gibi bir şeyin doğrudan içinde yapılabileceğinden oldukça eminim.
wizzwizz4

Bu Haskell değil, ama olur {{J, s}, {3, s}}mu?
wizzwizz4

1
@ wizzwizz4 Evet, sorun değil.
Arnauld

2
Bu, "uygun kartlar" yerine "eşleşen takımlara sahip kartların elleri" ile daha net olabilir.
chrylis

Yanıtlar:


13

Python 3 , 114 110 bayt

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]

Çevrimiçi deneyin!

@Arnauld, kart değerini ve sıralama tablosu dizgilerini birleştirme fikrini önerdi. Bazı denemelerden sonra R="T 2J45UNK9RL<3SLM;QAK:O>=/678", orijinal kart değer dizgisiyle aynı uzunlukta olan birleştirilmiş bir dizeyi oluşturmayı başardım . Alt dize R[6:25]="UNK9RL<3SLM;QAK:O>=/"sıralaması tablonun yanı sıra bir kart değeri arama tablosunda görevi görür 3, 9, A, K, ve Q. Yeni sıralama tablosunun ASCII-değeri kod çözme işlemi önceki sıralama tablosuyla aynı sıralama etkisine sahiptir.

Bayt dizelerini giriş olarak kullanmak 4 bayttan tasarruf sağlar.

cmpPython 2'de kullanmak , @ xnor çözümünde gösterildiği gibi çözümü 102 bayta indirebilir .


Python 3 , 165 142 130 129 bayt

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

Çevrimiçi deneyin!

-Jonathan Allan sayesinde -23 bayt

@Ovs sayesinde -2 bayt

@Mypetlion sayesinde -1 bayt

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

Fonksiyon f, oyuncu 1 ve oyuncu 2'nin elini temsil eden iki argüman alır. Buna göre, oyuncu 1, oyuncu 2, galibiyet durumunda pozitif, negatif veya sıfır değeri döndürür. Her bir el tek bir dize olarak kodlanır, örneğin "7cQh".


3
Joel, CGCC'ye hoş geldiniz! Elini ikiye bölmek çok zekice bir fikir! Gelmeye devam et!
640KB

1
@Jonathan Allan Teşekkürler. Fikrinizi biraz farklı yaklaşımlar kullanarak birleştirdim.
Joel,

1
Sıralama tablosunu tek bir dizede depolayarak 2 bayttan tasarruf edebilirsiniz:"HC92FA51GAB4E893D760"[s==t::2]
ovs

1
Python 2'ye geçmeye istekliysen ve başka bir 4 bayt daha kısa . ( cmpPython 3'te mevcut değil)
ovs

1
Bir bayt kaydetmek str.findyerine kullanabilirsiniz str.index. İki yöntem arasındaki tek davranış farkı index, öğe bulunmadığında findgeri dönerken hata atandır -1. Bu yüzden kodunuz için bir sorun olmayacak.
mypetlion

11

x86-16 Meclisi, 87 83 bayt

İkili:

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

unassembled:

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

Giriş, Js3sKsKhpointer içindeki gibi bir dize gibidir SI. Çıktı ise ZF = 0 and SF = OF(test JGoyuncu 1 galibiyet ise), SF ≠ OF(test JLçalar 2 galibiyet) veya ZF(test JE) bir beraberlik durumunda.

DOS test programını kullanarak çıktı:

görüntü tanımını buraya girin

DOS için MODTEN.COM'u indirip test edin .


7

05AB1E , 41 37 bayt

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

@Grimy sayesinde -4 bayt .

Meydan açıklamadaki üçüncü örnek giriş formatı gibi karakter listesinin bir listesi olarak giriş yapın. Yani P1 7c Qhve P2 8s Ksolarak girilirdi [[["7","c"],["Q","h"]],[["8","s"],["K","s"]]]. (Ve kullanımlar "10"için 10.)

Oyuncu 1 kazanırsa negatif bir tamsayı çıkarır; 2. oyuncu kazanırsa pozitif bir tamsayı; veya eğer berabere 0 ise.

Çevrimiçi deneyin veya tüm test durumlarını doğrulayın .

Açıklama:

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)

Benim bu 05AB1E ucu bakın (bölümler nasıl sözlüğü? Kullanmayı ne kadar büyük tamsayılar sıkıştırmak için? Ve kompres tamsayı listelerine nasıl? ) Anlamak için •V›{₆Ÿ&∊WÍj¸•ise 36742512464916394906012008, •V›{₆Ÿ&∊WÍj¸•19вolduğu [18,10,16,6,17,12,15,10,14,7,13,3,11,2,11,5,9,4,8,1], ‘ߌQ‘olduğunu "JAKEQ", ve ŽćSbir 39808.


Sorusu açıkça girişi atılmasına olanak tanır Tolarak 10sadece damla böylece, Tgelen JTQKA(ve 3889 yerine 30889 tamsayı sıkıştırılmış kullanın). Ayrıca, T* ... +olabilir ... «.
Grimmy

1
10T10nşık10=0T*...+...«

1
37 (şimdi aslında çalışıyor!)
Grimmy

@Grimy Ah, bu sözlüğün güzel kullanımı!
Kevin Cruijssen

3

PHP ,212 185 178 149 bayt

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

Çevrimiçi deneyin!

  • @ Night2 sayesinde -7 bayt!
  • Tablo yerine ASCII kodlayan -29 bayt, diziyi değil

Giriş komut satırı üzerinden. Çıktı STDOUTise negatif ise oyuncu 1 galibiyet, pozitif oyuncu 2 galibiyet, eğer 0kravat eğer. Örnek:

$ php modten.php Js3s KsKh
-1

1
Bize uzay gemisi operatörü vermeye istekli olsaydı night2 herhalde @ (Bunu? Kullanmayı ne sıklıkla yaptığı bir şey), ben -2 bayt ve sadece yerine, negatif, pozitif veya sıfır geri dönebilirler -1, 1ya 0.
640KB

Önceki cevabında uzay gemisi operatörünü görünce (iyi bir şekilde) şaşırdım.
Gece2

2

Jöle , 46 bayt

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

Çevrimiçi deneyin!

Örneğin argümanı olarak alan tam bir program ["7h","Ks"],["4s","Ts"]ve her iki oyuncu da çekilirse sıfıra basar, oyuncu 1 kazanırsa pozitif, oyuncu 2 kazanırsa negatif.


2

C (gcc) , 172 167 165 164 bayt

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

Çevrimiçi deneyin!

@Ceilingcat sayesinde 2 bayt tıraş edildi!

Temel olarak @ Joel'in Python3 çözümünün bir limanı, ancak base18 kodlaması olmadan. Girdiyi iki oyuncunun ellerini ayıran bir boşluğa sahip bir dize olarak bekler ve oyuncu 1'in kazandığını, oyuncu 2'nin kazandığını veya berabere olup olmadığını göstermek için pozitif, negatif veya sıfır olan bir tamsayı çıkarır.


2

Perl 6 , 101 100 94 88 bayt

Jo King sayesinde -1 bayt

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

Çevrimiçi deneyin!

Olarak girişi alır f(((<J ♠>, <3 ♠>), (<10 ♠>, <K ♥>)))kullanılarak 10Ten. Oyuncu 1 kazanırsa <0, oyuncu 2 kazanırsa> 0, berabere 0 alır.

açıklama

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

Kömür , 97 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. Girdiyi 4 karakterlik iki karakter dizisi olarak alır QcKc 6d4dve işaretli bir tamsayı çıkarır. Açıklama:

≔”)¶&sNψU↓”ζ

Sıkıştırılmış dize 2345678903889 , kart değerlerini gösterir.

F¹³F¹³

Her olası değer çifti üzerinde döngü yapın.

F⁻⁴⁼ικ

Mümkün olan her ikinci kart giysisinin üzerine gelin. Genel kayıp olmadan, ilk kartın 3. sıraya sahip olduğunu varsayabiliriz; bu nedenle, değerler aynı olmadıkça ikinci kartın 0 ila 3 arasında değişebileceğini, bu durumda sadece 0 ila 2 arasında olabileceğini varsayabiliriz.

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

Elin değeri olan elin değiştirilmiş skorunu iki katına çıkar, artı takım elbiselerin aynı olması durumunda 1 değerini hesapla (yani, ikinci kartta 3 takımı var).

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

Sıkıştırılmış dize 23456789TJQKAkart karakterlerini temsil eder. Giriş kartları bu dizgede aranır ve sonra kartın değerini almak için ilk dizgide indeksleme yapmak için pozisyon kullanılır.

≔⁰δ

Sonucu 0'a sıfırlayın.

F⟦θη⟧

İki elin üzerinde dolaş.

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

Elin değiştirilmiş skorunu ve dolayısıyla sıklığını hesaplayın ve sonucu buradan çıkarın.

Iδ

Frekans farkını çıkartın.



0

Perl 5 -p , 107 bayt

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

Çevrimiçi deneyin!

Giriş:

As 4d,Th 8c

(Aslında, virgül herhangi bir karakter olabilir.)

Çıktı:

-1  Player one wins
 0  Draw
 1  Player two wins
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.