홀덤 또는 폴드 엠?


17

친구가 마지막 순간에 고 지능 포커 게임에 초대했으며 컴퓨터 과학자로서 게임 기술을 사용하여 게임에서 우위를 점하기로 결정했습니다. 당신의 임무는 2 cards(손)과 0, 3, 4 or 5 cards(처리 된 카드)가 주어지며 , 당신이 얻을 수있는 가장 좋은 손이 무엇인지 결정해야합니다. 7 장의 카드가 모두 인수로 주어지면 답은 분명합니다. 덜 줄이면 문제가 더 복잡해집니다. 그러나 이것은 당신이 찾고있는 우위를 제공하기에 충분하지 않으며, 상대방이 가질 수있는 것을 이해하기 위해 나머지 카드에서 가능한 최고의 손을 계산해야합니다.


홀덤 리프레셔

홀덤에 대해 모른다면 게임의 각 플레이어는 2 장의 카드를 '손'으로 시작합니다. 3 턴 동안, 추가 카드가 모든 플레이어들과 공유되는 것으로 밝혀졌습니다. 첫 턴에는 3 장의 카드가 공개됩니다. 두 번째, 하나 더, 세 번째로 최종 카드가 공개됩니다. 주어진 두 카드는 먼저 당신의 손을 나타내고, 다른 카드는 연속 턴에서 주어진 0, 3, 4 또는 5 카드를 나타냅니다.


가능한 숫자 :

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

가능한 정장 :

[S,C,H,D]

풀 데크 :

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

핸드 랭킹 :

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

한두 가지 예를 들어서 살펴 보겠습니다.

간단한 예 :

[AS, AC],[AH,AD,9S,9C,9H]-> 3(4 가지), 3(4 가지)

이 설정에서 사용할 수있는 가장 좋은 손은 4 가지 종류입니다. KQJ10을 2 장의 카드로 사용할 수 없기 때문에 상대방이 가질 수있는 가장 좋은 손은 4 종입니다.


[5C,2C],[6C,4C,JH,JD]-> 2(스트레이트 플러시), 3(4 가지 종류)

당신은 똑바로 플러시 될 위험이 있지만, 당신의 손에 2 / 5C를 가지고 있기 때문에, 아무도 당신이 두 카드를 모두 들고 있기 때문에 아무도 없습니다. 그들이 기대할 수있는 최선은 2 개의 포켓 잭이 있고 플롭에서 잭을 얻는 것입니다.


[JS,JC],[]-> 1(로얄 플러시), 1(로얄 플러시)

당신이 그들에 대해 사용할 수있는 정보가 주어지지 않았습니다. 현재 당신이 말할 수있는 것은 다이아몬드 / 하트로만 왕실 플러시를 가질 수 있다는 것입니다. 실제로 플롭이 아직 발생하지 않은 모든 입력은 1-1 답변이되어야합니다.


[2C,4S],[3C,7S,9D,AH,JD]-> 10(높은 카드), 7(3 가지 종류)

이것은 당신이 절대적으로 조여진 곳의 예이며, 강이 똑 바르거나 플러시 될 가능성은 없습니다. 여기서 가장 좋은 핸드는 포켓 에이스로 3 가지 종류의 결과물입니다.


I / O 요구 사항

  • 입력은 당신의 손과 공개 지식 사이에 분리되어야합니다. 구현에 관계 없이이 방법이 더 쉬울 것입니다.
    • 카드는 튜플 또는 문자열 일 수 있습니다.
    • 손과 경기장은 배열 또는 구분 된 문자열이 될 수 있습니다.
  • 내가 제공 한 손 목록에서 두 개의 색인을 출력해야합니다 (EG [2,1]).
    • 함수의 일부로 리턴되거나 콘솔에 인쇄되거나 적절한 방식으로 출력 될 수 있습니다.
    • 최선의 손길을위한 값과 가능한 최선의 값을위한 값, 두 가지로 구분되어야합니다.
  • 10은 T또는로 표시 될 수 있습니다 10.
  • 표준 허점은 허용되지 않습니다.

승리 기준


2
이 단지의 하나 안 A하고 1가능한 허용 카드에서를? 또한과 같은 숫자 값에 대한 얼굴 약어가 필요한 설득력있는 이유가 있다고 생각하지 않습니다 11.
FryAmTheEggman


9
나는 가진 갑판 본 적이 A과를 1. 다른 모든 것이 좋아 보인다.
isaacg

1
Poker가 아닌 플레이어의 경우 두 번째 카드 그룹이 당신과 상대방 사이에서 공유되는 반면, 볼 수없는 두 개의 카드가 있다는 질문에 설명하십시오. pocket , flopriver 용어를 정의하는 빠른 용어집 이 도움이 될 것입니다.
DLosc

1
또한 도움이됩니다 : 라운드의 전체 순서를 설명합니다. (각 플레이어는 자신에게만 알려진 두 장의 카드로 시작하고, 세 장의 카드가 앞면으로 처리 된 다음, 네 번째, 다섯 번째로 처리됩니다.이 시점에서 각 플레이어는 7 장 중 5 장의 카드 중 "손"을 형성합니다. .) 왜 7 장의 카드가 있지만 1 장의 카드가 5 장인지는 분명하지 않을 수 있습니다.
DLosc

답변:


3

하스켈 , 433 430 바이트

@Laikoni 덕분에 -5 바이트

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)

온라인으로 사용해보십시오!

Ungolfed (같은 아이디어, 약간 다른 구조) :

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)

특별한 케이싱이 전혀 없기 때문에 매우 느립니다 (예 : 카드가 표시되지 않으면 항상 플러시가 가능합니다). 대부분의 골프 활동은 rank_hand기능에 들어갔습니다 . #지도 등을 결합하여 훨씬 더 골프를 칠 수 있습니다.

hand#table당신과 당신의 상대에 대한 최적의 점수를 계산합니다. 오류 점검이 없습니다.


나는 당신이을 s/elem/e/g정의 한 후에 잊어 버렸 e=elem으므로 9ish 바이트를 절약해야합니다. 특히 식별자가 숫자를 직접 따르는 경우 공백을 제거 할 수 있다고 생각합니다.
Julian Wolf

@JulianWolf 여전히 Haskell을 처음 사용하지만 어떤 이유로 든 e=elemInt-> Bool 유추 유형 처럼 보이기 때문에 정수가 아닌 elem 호출에 e를 사용할 때 컴파일되지 않았습니다. 왜 뭔지 알아 내려고 노력하고 있습니다. 공간에 대한 팁 감사합니다!
vroomfondel

아 맞아. Haskell은 때때로 다형성 유형을 유추하는 데 어려움을 겪습니다. 유연한 유형 플래그를 추가하는 것 외에도 쉽게 고칠 수 있는지 내 머리 꼭대기에서 확실하게 알 수 없습니다
Julian Wolf

1
h#t=let[...]in[...]로 단축 할 수 있습니다 h#t|let[...]=[...]. 또한 head n입니다 n!!0. 경비원 &&은 간단하게 할 수 있습니다 ,.
Laikoni 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.