Hold'em atau Fold'em?

17

Teman Anda mengundang Anda ke permainan poker berisiko tinggi pada menit terakhir dan, sebagai ilmuwan komputer, Anda telah memutuskan untuk menggunakan keterampilan Anda untuk mendapatkan keunggulan dalam permainan. Tugas Anda akan, diberikan 2 cards(tangan Anda) dan 0, 3, 4 or 5 cards(kartu yang dibagikan), Anda harus memutuskan apa tangan terbaik yang bisa Anda dapatkan. Jika semua 7 kartu diberikan sebagai argumen, jawabannya cukup jelas. Jika diberikan lebih sedikit, masalahnya menjadi lebih kompleks. Namun, ini tidak cukup untuk memberi Anda keunggulan yang Anda cari, Anda juga harus menghitung kartu terbaik dari sisa kartu untuk memahami apa yang bisa dimiliki lawan Anda juga.


Penyegaran Hold'em

Jika Anda tidak tahu tentang hold'em, setiap pemain dalam permainan mulai dengan 2 kartu sebagai 'tangan' mereka. Selama 3 'putaran', kartu tambahan diturunkan untuk dibagikan di antara semua pemain. Giliran pertama, 3 kartu terungkap. Yang kedua, 1 lebih banyak, dan ketiga kalinya kartu terakhir terungkap. Dua kartu yang diberikan pertama mewakili tangan Anda, sedangkan yang kedua mewakili 0, 3, 4, atau 5 kartu yang diberikan secara bergantian.


Kemungkinan Nomor:

[2,3,4,5,6,7,8,9,T(10),J,Q,K,A]

Kemungkinan Setelan:

[S,C,H,D]

Dek Penuh:

[2S,3S,4S,5S,6S,7S,8S,9S,TS,JS,QS,KS,AS, # Spades.
 2C,3C,4C,5C,6C,7C,8C,9C,TC,JC,QC,KC,AC, # Clubs.
 2H,3H,4H,5H,6H,7H,8H,9H,TH,JH,QH,KH,AH, # Hearts.
 2D,3D,4D,5D,6D,7D,8D,9D,TD,JD,QD,KD,AD] # Diamonds.

Peringkat Tangan:

1:Royal Flush    (A-K-Q-J-10, all from the same suit).
2:Straight Flush (Sequential cards, all from the same suit).
3:Four-of-a-Kind (Self explanatory).
4:Full House     (3-of-a-kind and a 2-of-a-kind).
5:Flush          (All cards are from the same suit).
6:Straight       (Sequential Cards, any suits).
7:3-of-a-Kind    (Self explanatory).
8:2-Pair         (Double 2-of-a-Kind).
9:Pair           (2-of-a-Kind).
10:High Card     (You have absolutely nothing except a single card).

Mari kita ambil satu atau dua contoh dan telusuri:

Contoh sederhana:

[AS, AC],[AH,AD,9S,9C,9H]-> 3(Empat-of-a-Kind), 3(Empat-of-a-Kind)

Tangan terbaik yang mungkin Anda miliki dalam pengaturan ini adalah empat tangan yang baik. Tangan terbaik yang mungkin dimiliki lawan Anda adalah kartu 4-of-a-Kind, karena Anda tidak dapat memiliki KQJ10 di tangan 2 kartu mereka.


[5C,2C],[6C,4C,JH,JD] -> 2 (Straight Flush), 3(4-of-a-Kind)

Anda berisiko mengalami flush lurus, tetapi karena Anda memegang 2 / 5C di tangan Anda, tidak ada orang lain yang memegang kartu tengah Anda. Yang terbaik yang bisa mereka harapkan adalah memiliki 2 Jack saku dan mendapatkan Jack di kegagalan.


[JS,JC],[] -> 1 (Royal Flush), 1(Royal Flush)

Tidak ada informasi yang dapat Anda gunakan untuk melawan mereka telah diberikan, yang dapat Anda katakan pada saat ini adalah bahwa mereka hanya dapat memiliki royal flush di berlian / hati, tetapi mungkin saja Anda mendapatkan royal flush seperti yang mereka lakukan. Faktanya, semua input di mana kegagalan belum terjadi harus menghasilkan jawaban 1-1.


[2C,4S],[3C,7S,9D,AH,JD]-> 10(Kartu Tinggi), 7(3-of-a-Kind)

Ini adalah contoh di mana Anda benar-benar kacau, dan tidak ada kemungkinan lurus atau siram diberikan sungai. Berarti tangan terbaik di sini adalah kartu as yang menghasilkan 3-of-a-Kind.


Persyaratan I / O

  • Masukan harus dipisahkan antara apa yang ada di tangan Anda dan apa yang menjadi pengetahuan umum; kemungkinan akan lebih mudah dengan cara ini terlepas dari implementasi.
    • Kartu dapat berupa tupel atau string, terserah Anda.
    • The Hand dan the Playing Field dapat berupa array atau string yang dibatasi.
  • Keluaran harus dua indeks dari daftar tangan yang saya berikan (EG [2,1]).
    • Ini dapat dikembalikan sebagai bagian dari fungsi, dicetak ke konsol atau keluaran dengan cara yang sesuai.
    • Harus ada dua nilai berbeda, satu untuk tangan terbaik Anda, yang lain untuk yang terbaik.
  • 10 dapat direpresentasikan sebagai Tatau sebagai 10, mana yang masuk akal untuk Anda.
  • Celah standar tidak diijinkan.

Kriteria Menang

  • Ini adalah , byte-count terendah dengan tie-breaker tanggal posting.
Guci Gurita Ajaib
sumber
2
Bukankah seharusnya hanya ada satu Adan 1di dalam kartu yang diperbolehkan? Juga saya tidak berpikir benar-benar ada alasan kuat untuk meminta singkatan wajah lebih dari nilai numerik seperti 11.
FryAmTheEggman
9
Saya belum pernah melihat dek dengan Adan 1. Segalanya tampak bagus.
isaacg
1
Bagi kami yang bukan pemain Poker, tolong jelaskan dalam pertanyaan bahwa kelompok kartu kedua dibagikan antara Anda dan lawan, sedangkan mereka memiliki dua kartu mereka sendiri yang tidak dapat Anda lihat. Glosarium cepat yang mendefinisikan istilah pocket , flop , dan river akan sangat membantu.
DLosc
1
Juga membantu: menjelaskan seluruh urutan putaran. (Setiap pemain mulai dengan dua kartu yang hanya diketahui oleh mereka, kemudian tiga kartu dibagikan tertutup, lalu yang keempat, lalu yang kelima, di mana setiap pemain membentuk "tangan" dari lima kartu dari tujuh kartu yang terlihat oleh mereka. .) Mungkin tidak jelas bagi seseorang mengapa ada tujuh kartu tetapi tangan terdiri dari lima.
DLosc

Jawaban:

3

Haskell , 433 430 425 byte

-5 byte terima kasih kepada @Laikoni

import Data.List
q="23456789TJQKA"
e=elem
l=length
b=map
r p|z,elem 'A'u,elem 'K'u=1|z=2|e 4t=3|v<3=4|w=5|y=6|e 3t=7|v<4=8|v<5=9|1>0=10where u=[n!!0|n<-p];v=l$nub u;t=b(\n->l[x |x<-u,x==n])q;w=all(==(last$p!!0))[last s|s<-p];y=elem""[u\\s|s<-b(take 5.flip drop('A':q))[0..10]];z=y&&w
0%_=[[]]
n%(x:y)=b(x:)((n-1)%y)++n%y
_%_=[]
h#t|let p=h++t;c i=minimum$b r$concat$b(5%)$b(++i)((7-l i)%([n:[s]|n<-q,s<-"SCHD"]\\p))=(c p,c t)

Cobalah online!

Tidak digabungkan (ide yang sama, struktur yang sedikit berbeda):

import Data.List -- for (\\)
numbers = "23456789TJQKA"

e=elem

rank_hand hand
    |royal_flush=1
    |straight_flush=2
    |four_of_a_kind=3
    |full_house=4
    |flush=5
    |straight=6
    |three_kind=7
    |two_pair=8
    |pair=9
    |1>0=10
    where nums = [head n | n<-hand]
          unique = length $ nub nums
          counts = map (\n->length [x | x<-nums, x==n]) numbers
          pair = unique < 5
          two_pair = unique < 4 -- could also be 3 of a kind, but that's ok
          three_kind = e 3 counts
          flush = all (==(last$hand!!0)) [last s|s<-hand]
          straight = elem "" [nums\\s | s <- map (take 5.flip drop ('A':numbers))[0..10]]
          full_house = unique < 3
          four_of_a_kind = e 4 counts
          straight_flush = straight && flush
          royal_flush = straight_flush && elem 'A' nums && elem 'K' nums

-- taken from /codegolf//a/34496/66460
-- k%l finds combinations of size k from a list l
0%_=[[]]
n%(x:y)=map(x:)((n-1)%y)++n%y
_%_=[]

-- find every combination available to each player, and rank each one. 
-- could be golfed a lot more.
h#t=let p=h++t
        a=[n:[s]|n<-numbers,s<-"SCHD"]\\p
        c i=minimum $ map rank_hand $ concat $ map (5%) $ map (++i) ((7-length i)%a)
    in(c p,c t)

Sangat lambat, karena tidak ada casing khusus sama sekali (misalnya jika tidak ada kartu yang ditunjukkan, flush kerajaan selalu mungkin.) Sebagian besar upaya golf saya masuk ke dalam rank_hand berfungsi; #dapat bermain golf lebih banyak dengan menggabungkan peta dan semacamnya.

hand#tablemenghitung skor optimal untuk Anda dan lawan Anda. Tidak ada pengecekan error.

vroomfondel
sumber
Saya pikir Anda lupa s/elem/e/gsetelah mendefinisikan e=elem, sehingga seharusnya menghemat 9ish byte. Saya pikir Anda juga dapat menghapus beberapa spasi, terutama di mana pengidentifikasi mengikuti angka secara langsung
Julian Wolf
@JulianWolf Saya masih baru di Haskell, tapi untuk beberapa alasan sepertinya e=elemdisimpulkan tipe Int-> Bool jadi tidak dikompilasi ketika saya menggunakan e untuk panggilan elem non-integer. Saya mencoba mencari tahu mengapa apa itu. Terima kasih atas tipnya!
vroomfondel
Ah kamu benar Haskell memiliki masalah dalam meringkas tipe polimorfik kadang-kadang — tidak yakin dari atas kepala saya apakah ada perbaikan yang mudah, di luar menambahkan bendera tipe yang fleksibel
Julian Wolf
1
h#t=let[...]in[...]dapat disingkat menjadi h#t|let[...]=[...]. Juga head nadalah n!!0. Dalam penjaga &&bisa saja ,.
Laikoni