最近,我对执行 21(二十一点)游戏的组合分析感兴趣,并尝试使用我的 AMD APU 尝试通过芯片上的 4 个内核对程序进行线程化。生成正确的策略和期望已被证明是成功的,并且只需几秒钟(大约 12 秒)即可计算出任何给定规则和套牌组合的最佳策略。然而,在计算其他套牌组合时,计算所有套牌状态需要 12.63 年……对于单个套牌。因此,另一种方法是通过蒙特卡洛方法模拟随机甲板子集的选择限制。这会奏效!但是,每次分析 12 秒是一个巨大的瓶颈!随机选择 10E6 个子集大约需要 139 天。即使使用线程,我当前的 CPU 也不可行。
关于我如何分析策略图表的入门:
1.) 我首先通过为玩家获取一组 n_cards 并列举所有可能的庄家手牌来计算对站立的总体期望是什么。我将每个特定经销商总数的结果与玩家手牌的当前手牌总数进行比较。
2.) 然后我通过选择玩家手组 {23} 并为 x:2->A 找到匹配的手组来计算击球期望,这样我们就可以计算击球到 {232}、{233} 的加权期望, {234},...,{23A}。我们首先计算所有硬 21,然后计算硬 20……直到所有硬 12;然后通过计算击中所有软 21 到软 13 来做同样的事情;然后计算所有硬 11 到硬 5;最后,我们计算击中所有对子牌({22}、{33}、...、{TT}、{AA}。)
3.) 加倍与击中相同,只是我们只抽一张牌并代表任何 2_card 玩家手牌。我们将抽牌的期望返回给特定的 3_card 手,并将期望乘以抽牌概率的 2 倍。
4.) 对于拆分,我们将执行步骤 1.) 到 3.),我们将重复 1->3 最多 11 次。为什么?我们通过删除我们要拆分的排名来计算拆分到新手的期望。(例如:我们想要拆分 {22}。我们将计算给定甲板子集的站立、击球、加倍,减去我们要拆分的排名之一。如果我们最初将 {22} 拆分为 {4 4 的甲板子集4 4 4 4 4 4 16 4: 2-A} 或 {3 1 4 3 4 4 3 1 14 3: 2-A},我们的新子集将是 {3 4 4 4 4 4 4 4 16 4: 2- A} 或 {2 1 4 3 4 4 3 1 14 3: 2-A}。)
5.) 在所有这一切之后,我们应该针对每个玩家手牌的每个可能决策的计算期望得到最优策略。
现在,我一直在研究是否有更快的方法来分析使用 GPGPU 或 FPGA/ASIC 的策略。我首先将 GPU 编程视为一种可能的途径,但是,我不确定它是否可行,因为有 3072 个独特的玩家手部状态,这意味着将有 3072 个独特的数据结构来计算站立、击球、加倍和分裂。
尽管如此,我希望有一种方法可以执行某种形式的同时处理,其中每个期望的状态会根据规则和/或套牌状态的变化而变化。也就是说,与其对 rules/deck_state 的每次变化重新计算每个期望值,不如对每个数据点的输出有一定的依赖性。例如:我们有名为 A、B 和 C 的三个数据点。我们还有状态数据 {1 2 3}。对于每个数据点,我们拥有一个状态方程:
A = 数据[0]
B = A + 数据[1]
C = B +数据[2]
在串行处理下,我们将首先评估 A 为 1,B 为 2 加 A,C 为 3 加 B。如果我们将数据更改为 {2 2 3},则 A 为 2,B 为 4,C将是 7。在串行处理下,对于每个数据点,每个数据点需要几个周期。FPGA下有没有一种方法可以瞬间改变状态?也就是说,如果我们改变任何一个数据点,A、B、C 会在数据改变后同时改变?
如果不是,FPGA/GPGPU 处理对想要在近乎瞬间准确快速地计算大量浮点数据的程序员有什么好处?基本上,有没有一种方法可以快速计算出比 12 秒长的多线程 CPU 处理更快的二十一点游戏的最佳策略?