找到N卡所有可能牌的高效算法? (OFC fantasyland)

时间:2015-07-22 23:12:35

标签: algorithm poker

如何以优雅高效的方式找到所有可能的N< 16卡扑克牌?

例如:Ncards(N = 6):Ah,Ad,2h,3h,4h,5s

所有(22+)扑克手:AhAd,Ad2h3h4h5s,Ah2h3h4h5s

常规查找表似乎不是一个选项,但我仍然希望它非常快。对于这个问题,最有效的卡表示(64位或int []或...)是什么?

上下文

我试图用C ++实现open face chinese扑克,这很容易。

有一个名为fantasyland的奖金游戏,你可以不时玩。

您可以一次获得13张,14张或15张卡片。这个奖金游戏很容易解决问题。对于一个人类玩家,所以我想让游戏引擎建议一个可能的游戏。最好的比赛是(+/-)具有最多奖励积分的比赛。

轻松实现,但出于教育目的,我想找到解决此问题的优雅方案。

暴力解决方案:

1)find  $pokerhands=getAllPossiblePokerHands($cards) (contains overlapping combinations, eg AhAc and Ah2x3x4x5x)

2)for each $pokerhand:

 - place the hand randomly on the board
 - redefine $cards as the cards that you haven't placed on the board
 - recursively repeat 1) and 2) untill the (13card board) board is
   filled, than call getBoardRoyalties($finalboard). Store this board and  
   its points for later use.

After all combinations have been tried, find the board with highest value, this is the solution.

这种强力解决方案似乎是解决这个问题的唯一方法吗?

由于getBoardRoyalties()是计算上廉价的函数(查找表),并且可以优化迭代,唯一的问题是:

如何以优雅的方式实现getAllPossiblePokerHands($ cards)?

1 个答案:

答案 0 :(得分:0)

我实际上已经完成了这个练习,是蛮力是唯一的方法。在正面,您可以通过观察手不得被污染来修剪大部分搜索空间。

最简单的方法是使用嵌套组合生成器。例如,如果您正在考虑14张牌,您可能会执行以下操作:

foreach front in C(14,3) possible front settings:
  foreach middle in C(11,5) possible middle settings:
    if middle fouls hand:
      continue
    foreach back in C(6,5) possible back settings:
      if back fouls hand:
        continue
      metric = evaluate(front, middle, back)

此时,您可以决定如何处理指标。您可以将所有这些内容保存在内存中,即使大多数手机都应该有足够的内存。该循环应该产生不到一百万个值,您可以对其进行排序,筛选,切片或切块。

真正的工作是提出一种评估功能,可以很好地估计出手的价值。版税积分是一个很好的起点,但你需要更多的东西。