德州扑克还是德州扑克?


17

您的朋友在最后一刻邀请您参加一场高风险的扑克游戏,作为计算机科学家,您决定利用自己的技能在游戏中取得优势。给定2 cards(您的手)和0, 3, 4 or 5 cards(已发牌),您的任务将必须决定,您能得到的最佳手牌是什么。如果将所有7张卡都作为参数给出,答案很明确。如果给予较少,问题将变得更加复杂。但是,这还不足以为您提供所需的优势,您还必须从其余的牌中计算出最好的一手牌,以了解对手的实力。


Hold'em刷新器

如果您不了解Hold'em,则游戏中的每个玩家都以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(四种),3(四种)

在此设置中,您最好的一手牌是四手牌。对手可能拥有的最好的一手也是4张一手,因为您的两张牌中没有KQJ10。


[5C,2C],[6C,4C,JH,JD]-> 2(同花顺),3(4种)

您有可能面临同花顺牌的风险,但是由于您手中有2 / 5C,因此没有其他人要同时持有两个中间牌。他们所希望的最好成绩是拥有2个口袋Jack并在翻牌圈拿到Jack。


[JS,JC],[]-> 1(皇家同花顺),1(皇家同花顺)

没有提供您可以用来对付他们的信息,目前您只能说他们只能在钻石/心形钻石上进行皇家同花顺,但是有可能像他们一样获得皇家同花顺。实际上,尚未发生翻牌的所有输入都应得到1-1的答案。


[2C,4S],[3C,7S,9D,AH,JD]-> 10(高级卡),7(3类)

这是您完全被拧死的示例,考虑到河流,不可能有平直或齐平的情况。这意味着最好的牌是口袋A,导致3类。


I / O要求

  • 输入必须在您掌握的知识和公共知识之间加以区分;无论采用哪种实现方式,这种方式都可能会更容易。
    • 卡可以是元组或字符串,由您决定。
    • 手和比赛场地可以是数组或定界字符串。
  • 输出必须是我提供的手牌列表(EG [2,1])中的两个索引。
    • 它可以作为函数的一部分返回,打印到控制台或以适当的方式输出。
    • 必须有两个不同的价值,一个是对您最好的帮助,另一个是对可能的最好的影响。
  • 10可能会以T或表示,这10对您有意义。
  • 不允许出现标准漏洞。

获奖标准

  • 这是,字节数最低,带有发布日期的平局。

2
不应该有只有一个A,并1在可能允许的卡?另外,我认为没有真正令人信服的理由要求对诸如的数字值使用面部缩写11
FryAmTheEggman'2


9
我从未见过带A和的牌组1。其他一切看起来都不错。
isaacg'2

1
对于我们的非扑克玩家,请在问题中说明第二组牌是您和对手共享的,而他们却拥有自己的两张看不见的牌。快速定义术语pocketflopriver的词汇表将很有帮助。
DLosc

1
也有帮助:解释一轮比赛的整个顺序。(每个玩家首先从两张只有他们知道的牌开始,然后将三张牌面朝上,然后第四张,再第五张,这时每位玩家从他们可见的七张牌中的任意五张牌组成“手牌” 。)对于某人来说可能不清楚,为什么会有七张牌,而一手却由五张牌组成。
DLosc

Answers:


3

Haskell433430425字节

-5字节感谢@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)

在线尝试!

空洞的(相同的想法,结构略有不同):

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,因此应该节省9个字节。我认为您也可以删除一些空格,特别是在标识符直接跟在数字
朱利安·沃尔夫

@JulianWolf我还是Haskell的新手,但是由于某种原因,它看起来像e=elem推断类型Int-> Bool,所以当我将e用于非整数elem调用时,它没有进行编译。我试图弄清楚为什么。感谢您在空格上的提示!
vroomfondel

啊,你是对的。Haskell有时很难推断出多态类型-除了添加灵活类型标志之外,不确定是否容易解决
朱利安·沃尔夫

1
h#t=let[...]in[...]可以缩短为h#t|let[...]=[...]。也head n就是n!!0。在后卫中&&可以简单地做到,
Laikoni
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.