如何以优雅高效的方式找到所有可能的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)?
答案 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)
此时,您可以决定如何处理指标。您可以将所有这些内容保存在内存中,即使大多数手机都应该有足够的内存。该循环应该产生不到一百万个值,您可以对其进行排序,筛选,切片或切块。
真正的工作是提出一种评估功能,可以很好地估计出手的价值。版税积分是一个很好的起点,但你需要更多的东西。