德州扑克AI(译)

前言:
  最近在研究德州扑克的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)

原文地址:https://www.cnblogs.com/mumuxinfei/p/8759481.html

时间: 2024-10-27 12:39:27

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

德州扑克AI实现 TexasHoldem Poker

参考了一下这篇文献,http://cowboyprogramming.com/2007/01/04/programming-poker-ai/ 自己用go实现了一个德州扑克AI,效果还可以. 正常和它玩耍的时候,互动性还不错.但是也有一点点问题,比如玩家乱来,把把都ALL IN(反正不是真的要钱),这其实就是在赌运气了,这种情况下测试AI丢牌的概率有点大,如何对付这种赖皮玩家,后期还要改进. 另外现在的实现其实是主要是概率运算,如何增加学习机制是一个努力方向,目前的想法是每一局结束以后,都去分析

德州扑克AI简介——2015华为软件精英赛小结

2015华为软件精英挑战赛的比赛目的是设计德州扑克比赛的牌手程序,采用的是无限注的比赛规则.具体比赛规则见下面链接.在接到这个赛题之初,我们做的第一件事情是熟悉德州扑克的比赛规则,并尽可能去寻找现有的开源项目或者程序.具体来说,着手点主要有四点:维基.论文.比赛和开源项目. 首先阅读的是维基,这里参考的主要是英文的维基百科.通过维基百科,大致了解了德州扑克的发展历史和现状,并且得知在现在每年的都会有人与机器的德州扑克比赛和机器与机器之间的德州扑克比赛.此外,通过维基百科,还了解到当前主流学术界对

德州扑克AI WEB版

继续之前的德州扑克话题,上次的DOS界面确实没法看,我女朋友说这是什么鬼.哈哈,估计只有自己能玩了 这两天重构了一下界面,基于web服务器和浏览器来交互. 服务器和客户端之间用websocket通信,这种全双工长连接更方便服务器及时的将整个游戏数据向客户端推送. 这篇随笔主要记录一下做前端界面的时候遇到的一些坑,至于德州扑克游戏的具体逻辑以及AI的逻辑可以查看我前两篇随笔 说道web服务器,go语言对这方面封装的非常好,用起来太爽了.而使用websocket,我们需要用到google提供的一个w

德州扑克AI

德州扑克: 1:outs数,就是所听的牌的数量. 例子: 1:听顺子 4567 outs数就是8,能够成顺子的牌为3和8. 5689 outs数就是4,能够成顺子的牌只有7. 2:听同花     359J outs数就是9,能够成牌的是同一种花色的'A','2','4','6','7','8','10','Q','K'. 3:听同花顺 4567 outs数就是2,能够成牌的是同一种花色的'3','8'. 5689 outs数就是1,能够成牌的是同一种花色的'7'. 4:听同花或顺子 4567 o

在写德州扑克AI的时候想到的一种实现模糊决策的方法

目前的AI决策方式是线性的,给定了一个条件X,代入一条曲线获得一个Y后直接作为决策值.略略灵活一点的,从两条曲线中取得两个值Y1,Y2,然后随机从两者中间的区域中取得一个值. 但是,这样做会使AI表现出非常明显的"边界",与AI交流能够明显的感觉的AI的限度在哪里.感觉会比较"僵硬".原因在于人类的决策过程并没有这种边界.当我们面对某一个条件X的时候,我们的决策"曲线"应该是这个样子的 如图,人类的决策没有明显的边界,所以看起来非常的模糊.模糊处

德州扑克游戏

哇,好久好久没写东西啦... 这两天实现了一个简单的游戏引擎,可以发牌,可以比较两手牌的大小 由于最近都在倒腾Golang,所以用GO实现的.这阶段过后准备用这个引擎来实现一个简单的AI对战,现在先记录一下 接下来我假设你已经懂游戏规则和俗语了 首先是牌的储存,2~~A,一共13张牌,我用的是一个14位的二进制区间来储存的,比如2-A,将表示为:11111111111110,辣么第一位是干啥的呢,请继续看下面 这样的储存方式除了省空间外还有什么优势呢?我们顺子的判断为例:例如顺子10JQKA,在

分享一个德州扑克的算法

德州扑克想必很多人都玩过,当然对于新手需要说明的是,德州指的是德克萨斯州,而不是山东德州. 这几个月一直在做一个德州扑克的服务器,分享下在计算最大牌型,比牌逻辑的算法和洗牌的方法,希望对大家有帮助. 首先我们定义一下Poker类 public class Poker { private String tag; // 图片扑克花色的表示(代表的是红桃.黑桃,梅花.方块 private int num; // 表示扑克牌面的大 public Poker(String tag, int num) {

模拟德州扑克对战游戏

================================================================ 注意:本文参考"巧妙的Python数据结构玩法|实战德州扑克"的相关内容,并在此基础之上完成模拟扑克对战游戏. 原文网址:http://mp.weixin.qq.com/s/JQ0zJGf7Tz49Xn78x7Z40g ================================================================ 我们写了两

德州扑克 2015 华为软件精英挑战赛

概述 华为2015软件挑战赛比赛总结,跟队友当时奋斗了15天吧,最后差点进32强了,第三轮遇到的对手太厉害,止步64强了.这次官方提供 Ubuntu 纯命令行镜像和庄家 Server,选手编写德州扑克选手机器人程序互相 PK(8人一组)500轮后钱多者胜出.运行只要运行华为提供的ne">dist_check_and_run.sh 脚本 即可,里面会给自动运行每个game程序.最近快要找工作了一些项目还是要总结一下的,感觉欠缺的地方还是有很多的,下面进入正题. 梳理一下主干主要这次比赛项目主