德州扑克AI--Programming Poker AI(译)

2023-05-16

 

前言:
  最近在研究德州扑克的AI, 也想由浅入深的看下, 在网上找了一圈, 发现很多文章都提到了一篇文章: Programming Poker AI. 仔细拜读了一下, 觉得非常不错. 这里作下简单的翻译工作, 可能加些自己的一些理解, 权当做一回大自然的搬运工, ^_^.

 

扑克数据模型抽象(Poker Data Type):
  本文的作者倾向于使用位/字节级别来描述牌的数据模型(Hand=玩家手牌+公共牌), 也算一种高阶的抽象.
  花色(Suit), 其值范围为0..3, 并假定梅花(Clubs)=0, 方块(Diamonds)=1, 红心(Hearts)=2, 黑桃(Spades)=3.
  等级(rank), 其值范围为0..12, 赋予 2(deuce)=0, 3=1, ..., King=11, Ace=12.
  牌(Card)其就对应一个0..51的整数, 三者满足如下等式:


card = suit*13 + rank.
Suit = card/13
Rank = card%13   

  Hand就可以用一个52bit的表示, 其中每一位都代表一个具体的牌. 可以借用4个16位字节来简单实现, 其中每个16位字节(word)覆盖一组花色牌.
  
  对于牌类型(Hand Type), 这边设定:

高牌(no pair) = 0
一对(pair) = 1
两对(two pair) = 2
三条(trips) = 3
顺子(straight) = 4
同花(flush) = 5
葫芦(full house) = 6
金刚(quads) = 7
同花顺(straight flush) = 8

  注: 这边的Hand, 我的理解是对应玩家手牌+公共牌组合后的结果.

 

牌力编码(Encoding Hand Values):
  牌力的编码可以用32位正整数来标识, 其值的大小和牌力是正相关.
  牌力编码设计为6个半字节(4位)的组合, 最高的半字节代表牌类型, 接下来的5个半字节代表依序的数值.
  

  样例一: AH,QD,4S,KH,8C 是高high牌型, 所以牌型半字节为0. 数值排序为(A, K, Q, 8, 4), 其经值转换后为(12, 11, 10, 6, 2). 用16进制来表示, 则变为(C, B, A, 6, 2). 最终的32位整数为: 0x000CBA62.
  样例二: 4D,JD,3D,4C,AD 是一对牌型, 所以牌型半字节为1. 数值排序为(4, A, J, 3), 16进制表示为(2, C, 9, 1). 最终的32位整数位: 0x0012C910.
  样例三: 7C,6C,5C,4C,3D 是顺子牌型, 所以牌型半字节为4. 数值排序(7), 16进制表示为(5). 最终的32位整数位: 0x00450000. 注: 顺子类型选取最高的数值代表.
  结合这些样例, 你会发现, 其牌力和代表的数值, 是符合正相关的. 因此牌力的比较变得非常的容易.

 

计算牌力(Calculating Hand Values):
  我们需要定义一个函数, 能够快速的计算hand到牌力值的转换. 这边提供了一些思路.
  比如同一花色的13位可以有8192种组合(2的13次方=8192), 这个数值不大. 它给我们了一种思路去优化计算, 就是提供一个预计算好的8K大小的table表, 用于加速评估. 比如快速找到同花, 顺子等等.
  再比如计算每个牌数的不同花色数, 利用有不同花色的rank, 然后快速确定牌型.
  这个函数最终涉及按位操作, 表查询和简单比较, 那它的性能将非常的快.

 

计算胜率(Calculating Hand Strength):
  胜率(HS)是一个0.0到1.0之间的一个数值, 它代表赢得当前局的概率. 比如HS=0.33意味着, 33%的概率赢得胜率.
  这边胜率计算方式, 采用了模拟法(俗称的蒙特卡洛算法). 比如随即模拟1000次, 你赢得423局, 那么你的HS为423/1000=0.423.
  这个模拟过程, 可以用如下伪代码来表示:

Create a pack of cards
Set score = 0
Remove the known cards (your hole cards, and any community cards)
Repeat 1000 times (or more, depending on CPU resources and desired accuracy)
    Shuffle the remaining pack
    Deal your opponent's hole cards, and the remaining community cards
    Evaluate all hands, and see who has the best hands
    If you have the best hand then
        Add 1/(number of people with the same hand value) to your score (usually 1)
    End if
end repeat
Hand Strength = score/number of loops (1000 in this case).

  真实的胜率评估可能要比这要复杂, 你需要考虑其他玩家位置, 行为, 筹码量, 盲注等. 所以计算胜率的过程, 需要一定程度的修改. 当然这是个开放性的话题. 

 

底池赔率(Pot Odds):
  底池赔率是指你的加注/跟注和最终底池的比例值.
  比如你加注$20, 加注前底池总额为$40. 那么底池赔率为20/(40+20)=0.333.

 

收益率(Rate Of Return):
  收益率也可以称为回报率, 我们如下定义它:

 Rate Of Return = Hand Strength / Pot Odds.

   

决策(The Fold/Call/Raise Decision):
  定义FCR为每一轮棋牌/跟住/加注的策略行动. 同时定义RR为回报率(Rate Of Return).

If RR < 0.8 then 95% fold, 0 % call, 5% raise (bluff)
If RR < 1.0 then 80%, fold 5% call, 15% raise (bluff)
If RR <1.3 the 0% fold, 60% call, 40% raise
Else (RR >= 1.3) 0% fold, 30% call, 70% raise
If fold and amount to call is zero, then call.

  对于上面的阈值, 可以适当的进行调整.
  同时这边也加入一些模糊策略, 包括在牌力不强情况下的诈唬.
  注: 这边的诈唬, 某种角度也可以理解为半诈唬, 是自带防守, 就算诈唬失败依旧有机会逆转.

 

筹码保护(Stack Protection):
  当你的筹码很深且盲注很小时, 上述的简单规则会表现的很出色. 但是自身处于短筹或者盲注变高时, 需要做些保护策略, 否则很容易All-In而失去所有.
  比如你手牌为AD, 2D, 此时公共牌为QC, KC, 2C. 此时你2一对, 但对手可能是同花牌. 如果底池为$500, 而对家raise $100. 刚好你筹码只有$100. 这种情况下, 你的Pot Odds(底池赔率)为100/(500+100)=0.1666, HS(胜率)为0.297. 这样RR=0.297/0.1666=1.8, 按照上述决策, 应该call. 但是这种情况下, 你有70%的大概率会失去所有, 请不要这样决策.
  为了处理这种情况, 引入一个简答的启发式条件: 除非大概率胜率, 否则不轻易压上全部/大部分筹码.
  添加如下规则:

if (stack- bet) < (blind * 4) and (HS < 0.5) then fold

  

更多的工作(More Work):
  当前的AI策略, 还有如下需要加强的地方:
  1). 翻前手牌胜率预估(Pre-flop hand strength tables)
  2). 对手模型(Opponent modeling)
  3). 隐含赔率(Implied Odds)
  4). 个性化建模(Personality modeling)
  5). 基于位置的策略(Positional play)
  6). 概率搜索空间(Probabilistic search space)
  7). 游戏理论和纳什均衡(Game theory and Nash Equilibrium)

 

AI测试:
  总的来说, AI效果还是很赞的. 包括网上的很大大拿, 实现了该算法之后, 都竖起了大拇指. 当然这个算法, 遇到蛮不讲理的玩家, 把把All In, 它的弃牌率有些高. 其实真实玩家去玩, 也会是类似的囧境, 只不过人是可以根据对手的打法动态的调整策略, 这一点确实是该AI算法的不足. 还有就是对玩家的反raise, 该算法没有相应策略应对.

  

评价:
  其实这个AI算法, 最让我眼前一亮的, 其实是它的数据模型抽象, 以及牌力值函数设计, 对于快速计算也提供一种很好思路, 确实很赞. 算法本身借助蒙特卡洛算法, 隐含了当前牌力/发展面(抽牌命中率), 对手的可能牌力分布, 这些综合的因素, 完美而简洁地现实了效果. 总的来说, 这是一个很好的文章, 其数据模型可被后续很多AI算法继续沿用.

 

个人站点:


  个人游戏作品集站点(尚在建设中...): www.mmxfgame.com  
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

德州扑克AI--Programming Poker AI(译) 的相关文章

随机推荐

  • 头文件中的(全局)变量只能放声明,不能定义

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 头文件中的变量只能声明 xff0c 不能定义 xff0c 否则其他多个 c文件包含该头文件 xff0c 出现重复定义 xff0c 导致链接出错 ifndef define
  • 程序启动时的堆栈

    程序启动时 xff0c Linux把4种类型的信息存放到程序堆栈中 xff1a xff08 1 xff09 命令行参数 xff08 包括程序名称 xff09 的数目 xff08 2 xff09 从shell提示符执行的程序的名称 xff08
  • suse linux双网卡双网关配置

    公司有台SUSE LINUX服务器需要用到2个网络 xff0c 一个网段是192的 xff0c 用来上OP管理平台系统 一个是B网络 xff0c 网段是202的 xff0c 用来上外网 我们都知道一台电脑拥有两个网关是不可能的 xff0c
  • 统计学中抽样比例一般占百分之多少

    要具体问题具体分析 一般和要求的误差限 置信区间及总体方差有关系 比如最基本的简单随机抽样 其样本量确定公式就是1 n 61 1 N 43 d 2 u 2 S 2 样本量和误差限成反比 和置信区间及总体方差成正比 请问一堆url怎么算方差
  • emqtt 试用(二)验证 emq 和 mosquito 的共享订阅

    本地订阅 Local Subscription 本地订阅 Local Subscription 只在本节点创建订阅与路由表 xff0c 不会在集群节点间广播全局路由 xff0c 非常适合物联网数据采集应用 使用方式 订阅者在主题 Topic
  • spring security实现动态配置url权限的两种方法

    缘起 标准的RABC 权限需要支持动态配置 xff0c spring security默认是在代码里约定好权限 xff0c 真实的业务场景通常需要可以支持动态配置角色访问权限 xff0c 即在运行时去配置url对应的访问角色 基于sprin
  • 干货!2018年你值得一看的网页设计作品集赏析

    网页设计作品集 61 门面 43 能力 网页设计作品集对网页设计师而言 xff0c 既是网页门面 xff0c 也是个人专业素养的体现 那么在作品集设计上万不能掉以轻心 无论是制作一份简约大方还是极具表现力的精良作品集 xff0c 设计师们都
  • ElasticSearch在原索引基础上添加字段和修改字段

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 业务场景 xff1a 现在的系统设计不满足业务需求时就需要升级服务 xff0c 为了满足业务需求有时需要对ES中 字段进行添加或修改操作 xff0c 接下来我们查看为 ma
  • echarts中关于字体设置的配置

    1 legend字体大小的配置 2 x轴和y轴上的刻度值的字体大小的配置 3 visualMap的字体大小的配置 4 饼状图上的文字大小的配置 其对应的是 转载于 https blog 51cto com 11871779 2401302
  • 堡垒机 jumpserver

    堡垒机介绍 在一个特定网络环境下 xff0c 为了保障网络和数据不受外界入侵和破坏 xff0c 而运用各种技术手段实时收集和监控网络环境中每一个组成部分的系统状态 安全事件 网络活动 xff0c 以便集中报警 及时处理及审计定责 我们又把堡
  • vim替换命令

    在VIM中进行文本替换 xff1a 1 替换当前行中的内容 xff1a s from to xff08 s即substitude xff09 s from to xff1a 将当前行中的第一个from xff0c 替换成to 如果当前行含有
  • xxxxxxxxxxxxxxxxxxxxxxxxxxxx

    Get Authorization code Request https accounts google com o oauth2 v2 auth redirect uri 61 https 3A 2F 2Fdevelopers googl
  • linux 系统密码忘记后的 5 种方法【转】

    如果你既没做系统启动软盘 xff0c 同时多系统的引导LILO 和GRUB 又被删除 xff0c 那么只能使用Linux 系统安装盘来恢复root的密码 xff0c 步骤如下 一 lilo引导在出现 lilo 提示时键入 linux sin
  • 理解程序内存

    内存对很多人来说感觉是个很熟悉的东西 xff0c 因为我们在用VC调试程序时 xff0c 很多时候都会察看内存中变量的值 但是 xff0c 很多时候我们的思维也就因此局限在有源码的模块 xff0c 当遇到一些跨模块或是没有源代码的Bug x
  • 内核调试

    转载一篇文章 xff1a http my oschina net fgq611 blog 113249 linux内核调试方法总结 1 二分法与printk AB之间有个bug xff0c 在AB之间找个中间点C xff0c 使用print
  • 提供一个免费的CSDN下载账号

    账号 xff1a windforce05 password xff1a w12345678 请下载了资源后评价一下资源 xff0c 以便赚回分数
  • 答读者问(7):相关实习、在软件开发和测试等论文和关系问题

    最近收到一个研究生朋友的电子邮件 xff0c 让我想起自己毕业前 xff0c 我们已经有很多的疑惑 xff0c 人谁想要的答案 互联网不仅是我们最好的老师 同一时候也是最好的桥梁 我们都要感谢并善于利用它 闲话不说 xff0c 言归正传 邮
  • 安装完office2016 64位后,在安装visio时,报错,无法安装,

    安装环境要求 xff1a 系统要求 xff1a win8 win10等 xff1b office要求 xff1a sw 批量版 不能和cn xff08 零售版 xff09 365版混装 重点注意事项一定要注意批量版和零售版的区别 xff0c
  • tex中把参考文献标题删除

    如果是book类 lt br gt renewcommand bibname lt br gt 如果是article类 lt br gt renewcommand refname
  • 德州扑克AI--Programming Poker AI(译)

    前言 最近在研究德州扑克的AI 也想由浅入深的看下 在网上找了一圈 发现很多文章都提到了一篇文章 Programming Poker AI 仔细拜读了一下 觉得非常不错 这里作下简单的翻译工作 可能加些自己的一些理解 权当做一回大自然的搬运