ModTenの古き良きゲームのようなものはありません


27

免責事項:ModTenは、このチャレンジの唯一の目的のために作成された架空のカードゲームです。

ModTenのルール

ModTenは、標準の52カードデッキでプレイされます。完全なルールはまだ発明されていないため、ハンドランキングのみに焦点を当てます。

ジャック&スリー、スーテッド

ModTenの勝ち手。ウィキペディアのグラフィック。

カードの値

カードには次の値があります。

  • 2から9:額面価値
  • 10:0ポイント
  • ジャック:3点
  • クイーンまたはキング:8ポイント
  • エース:9ポイント

手の価値

  • ModTenの手がで作られている2枚のカード。ハンドのベース値は、両方のカードの値を乗算し、最後の桁のみを保持することで得られます(モジュロ10を適用するなど)。

    6(7×8mod10=6

  • 唯一の他のルールModTenは、ということです適しカードはより適さないものより価値があります。慣例により、両方のカードが同じスーツである場合、値に「s」を追加します。

    たとえば、9-5 valueの値は、「」として示され。これは、あり、カードが適しているためです。5s9×5mod10=5

ハンドランキングと勝者

上記の規則により、18の異なるハンドランクが得られます。これらのランクは、最強から最低(または最もまれなものから最も一般的なもの)まで、次の表にまとめられています。確率は情報提供のみを目的としています。

2つのハンドが与えられると、最低ランクのハンドが勝ちます。両手が同じランクの場合、それは引き分けです(タイブレーカーはありません)。

 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%

チャレンジ

2つのModTenハンドが与えられた場合、選択した3つの一貫した値のいずれかを出力して、次のことを確認します

  • 最初のプレイヤーが勝ちます
  • 2番目のプレーヤーが勝ちます
  • それは引き分けです

次の規則が適用されます。

  • カードは大文字でその順位によって説明(しなければならない23、...、 、9T、、J または)(小文字でそのスーツに続いて、、または、クラブ、ダイヤ、ハートやスペードのため)。QKAcdhs
  • "10"代わりに使用できます"T"が、他の代替は禁止されています。
  • 上記の規則が守られている限り、あなたは合理的で明確な形式で手を取ります。ランクとスーツは、単一の文字列ではなく、2つの異なる文字として使用できます。

    有効な入力形式は次のとおりです。

    • "7c Qh 8s Ks"
    • [["7c","Qh"], ["8s","Ks"]]
    • [[['7','c'], ['Q','h']], [['8','s'], ['K','s']]]
  • 3つの一貫した個別の値を使用する代わりに、出力はnegativepositiveまたはzeroになる場合があります。回答で使用される出力形式を指定してください。

  • これはです。

テストケース

プレイヤー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

これはHaskellではありませんが{{J, s}, {3, s}}、大丈夫でしょうか?
wizzwizz4

1
@ wizzwizz4はい、大丈夫です。
アルノー

2
これは、「スーテッドカード」ではなく、「スーツに一致するカードの手」を使用する方が明確になる場合があります。
クリリス

回答:


13

Pythonの3114の 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>=/"ランクテーブルならびにためのカード値のルックアップテーブルとして機能する39AK、およびQ。新しいランクテーブルのASCII値のデコードは、前のランクテーブルと同じランキング効果があります。

入力としてバイト文字列を使用すると、4バイト節約されます。

cmpPython 2で使用すると、@ xnorのソリューションが示すように、ソリューションを102バイトに減らすことができます。


Pythonの3165の 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バイト

@ovsのおかげで-2バイト

@mypetlionのおかげで-1バイト

ゴルフをしていない:

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のハンドを表す2つの引数を取ります。プレーヤー1が勝った場合、プレーヤー2が勝った場合、引き分けの場合は、正、負、またはゼロの値を返します。各手は、「7cQh」などの単一の文字列としてエンコードされます。


3
こんにちはジョエル、CGCCへようこそ!ハンドランク配列を2つに分割する非常に賢いアイデアです!来てください!
640KB

1
@ジョナサン・アランありがとう。少し異なるアプローチを使用して、あなたのアイデアを取り入れました。
ジョエル

1
:あなたは、単一の文字列にランクテーブルを格納することにより、2つのバイトを保存することができます"HC92FA51GAB4E893D760"[s==t::2]
OVS

1
Python 2に切り替えたい場合は、さらに4バイト短くなります(cmpPython 3では使用できません)
ovs

1
str.find代わりにstr.index1バイトを保存するために使用できます。2つのメソッドの唯一の動作の違いはindex、要素が見つからないときにエラーをスローする一方で、をfind返すこと-1です。したがって、コードにとっては問題になりません。
マイペトリオン

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テストプログラムを使用した出力:

ここに画像の説明を入力してください

DOS用MODTEN.COMをダウンロードしてテストします。


7

05AB1E41 37 バイト

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

@Grimyのおかげで-4バイト。

チャレンジの説明の3番目の入力形式の例のように、文字のリストのリストのリストとして入力します。つまり、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ため、Tfromを削除できますJTQKA(30889の代わりに圧縮整数3889を使用できます)。また、T* ... +可能性があります... «
グリムミー

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

1
37(現在は実際に動作しています!)
Grimmy

@Grimy Ah、そのような辞書をうまく使って!
ケビンクルーッセン

3

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

オンラインでお試しください!

  • @ Night2のおかげで-7バイト!
  • 配列の代わりにテーブルをエンコードするASCIIによる-29バイト

入力はコマンドライン経由です。出力STDOUTは、プレイヤー1が勝った場合は、プレイヤー2が同点の場合はです0。例:

$ php modten.php Js3s KsKh
-1

1
@ Night2宇宙船のオペレーターを提供したいなら(つまり、どれくらいの頻度でそれを使用しますか?)、-2バイトで-11またはの代わりに負、正、またはゼロを返すことができます0
640KB

前の回答で宇宙船のオペレーターを見て驚いた(良い意味で)。
ナイト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);}

オンラインでお試しください!

@ceilingcatのおかげで2バイト削り取られました!

基本的に@JoelのPython3ソリューションの移植ですが、base18エンコーディングはありません。入力は、2人のプレイヤーの手を区切る1つの文字列として期待され、プレイヤー1が勝った、プレイヤー2が勝った、または引き分けかどうかを示す正、負、またはゼロの整数を出力します。


2

Perl 6の101 100 94 88バイト

ジョー・キングのおかげで-1バイト

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

オンラインでお試しください!

Tenのf(((<J ♠>, <3 ♠>), (<10 ♠>, <K ♥>)))使用として入力を受け取ります10。プレーヤー1が勝った場合<0、プレーヤー2が勝った場合> 0、引き分けの場合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δ

オンラインでお試しください!リンクは、コードの詳細バージョンです。たとえばQcKc 6d4d、4文字の2つの文字列として入力を受け取り、符号付き整数を出力します。説明:

≔”)¶&sNψU↓”ζ

圧縮された文字列2345678903889は、カードの値を表します。

F¹³F¹³

値の可能な各ペアをループします。

F⁻⁴⁼ικ

考えられるそれぞれの2番目のカードスーツをループします。一般性を失うことなく、最初のカードにスーツ3があると仮定できます。したがって、値が同じでない限り、2番目のカードスーツは0から3の範囲になります。

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

修正されたハンドのスコアを計算します。これはハンドの値を2倍し、スーツが同じ場合(つまり、2番目のカードにスーツ3がある場合)に1を加えます。

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

圧縮された文字列23456789TJQKAは、カードの文字を表します。入力カードはこの文字列で検索され、位置は最初の文字列にインデックスを付けてカードの値を取得するために使用されます。

≔⁰δ

結果を0に初期化します。

F⟦θη⟧

両手でループします。

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

修正された手のスコア、ひいてはその頻度を計算し、これから結果を引きます。

Iδ

周波数差を出力します。



0

Perl -p 5、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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.