用蒙特卡洛计算德州扑克局势

unsplash.com

0.说明

学习德州扑克时,不可避免需要计算赔率来指导自己决策。

实战中计算赔率需要考虑很多因素,包括且不限于:价值赔率、对手打法、自己形象等等。

但其中价值赔率是最稳定且关键的赔率。

比如手握 ♠️A♦️A,桌面 ♦️K♦️Q♦️J,这种情况下期望胜率是多少?如果是 1v1 且笃定对手手牌为 ♦️T♥️T 的情况下胜率又是多少?

甚至有的时候我们还想知道我们的牌会以多大的概率输给高牌、对子或者葫芦?

总之能计算这些概率是非常重要的。德扑高手或者数学高手可能能较快地算出大致概率,网上也有一些工具可以帮助计算,不过自己实现定制化灵活度更高一些,可以根据需要随意改。

理论上是可以直接从牌局用数学的排列组合方法去计算概率的。

但这里个人采取更简单粗暴的蒙特卡洛方法:直接随机模拟很多次发牌,统计结果。

如果要求高精度,大可将模拟次数设高一些。

代码支持多线程,多核 CPU 可以并行计算更快地得到结果。

1.源代码

代码基于 Java 实现

Github 链接:https://github.com/Raytto/HoldemCaculator

2.工程结构

-- scr
    -- model 一些基本类
        -- Desk.java 牌桌类
        -- Player.java 玩家类
        -- PokerCard.java 一张牌
    -- processor 计算器
        -- BasicProcessor.java 各种牌型判断
        -- MCprocessor.java 蒙特卡洛模拟
    -- test 根据实际需要使用计算器进行情景模拟的一些例子
        -- MCprocessorTest1.java 一场五人局,知道自己和另一个对手的手牌下的胜负情况
        -- OnlyHoldCardsInfoSituationToFile.java 将结果输出至文件的实例
  

3.使用说明

类似 test 中的各种使用方式,如 MCprocessorTest1.java

package test;
 import model.Desk;
 import model.Player;
 import model.PokerCard;
 import processor.MCprocessor;
 public class MCprocessorTest1 {
 public static void main(String[] args) {     // TODO Auto-generated method stub     Player player1=new Player();     player1.setSerialNumber(0);     Player player2=new Player();     player2.setSerialNumber(1);     Player player3=new Player();     player2.setSerialNumber(2);     Player player4=new Player();     player2.setSerialNumber(3);     Player player5=new Player();     player2.setSerialNumber(4);     Player player6=new Player();     player2.setSerialNumber(5);     player1.getHoldCards().add(new PokerCard(14, PokerCard.Hearts));     player1.getHoldCards().add(new PokerCard(10, PokerCard.Dimonds));     player2.getHoldCards().add(new PokerCard(3, PokerCard.Dimonds));     player2.getHoldCards().add(new PokerCard(5, PokerCard.Dimonds));
 //        player3.getHoldCards().add(new PokerCard(3, PokerCard.Spades));
 //        player3.getHoldCards().add(new PokerCard(3, PokerCard.Hearts));
         Desk desk=new Desk();
         desk.getPlayers().add(player1);
         desk.getPlayers().add(player2);
 //        desk.getPlayers().add(player3);
 //        desk.getPlayers().add(player4);
 //        desk.getPlayers().add(player5);
 //        desk.getPlayers().add(player6);
 //        desk.getCommunityCards().add(new PokerCard(7,PokerCard.Dimonds));
 //        desk.getCommunityCards().add(new PokerCard(9,PokerCard.Dimonds));
 //        desk.getCommunityCards().add(new PokerCard(11,PokerCard.Dimonds));
 //        desk.getCommunityCards().add(new PokerCard(12,PokerCard.Dimonds));
 //        desk.getCommunityCards().add(new PokerCard(13,PokerCard.Dimonds));
         MCprocessor mc=new MCprocessor();
         System.out.println("------------start-----------");
         long startTime = System.nanoTime();
         try {
             int time=10000000;
             int[][][]result=mc.timesOfWinOfEachPlayers(time, desk);
             System.out.println("------------win info-----------");
             for(int p=0;p<desk.getPlayers().size();p++){
                 for(int i=0;i<=desk.getPlayers().size();i++){
                     System.out.print(result[0][p][i]+"("+(double)result[0][p][i]/time+")  ");
                 }
                 System.out.println();
             }
             System.out.println("------------win kind-----------");
             for(int p=0;p<desk.getPlayers().size();p++){
                 for(int i=0;i<=8;i++){
                     System.out.print(result[1][p][i]+"("+(double)result[1][p][i]/time+")  ");
                 }
                 System.out.println();
             }
             System.out.println("-----------lose kind-----------");
             for(int p=0;p<desk.getPlayers().size();p++){
                 for(int i=0;i<=8;i++){
                     System.out.print(result[2][p][i]+"("+(double)result[2][p][i]/time+")  ");
                 }
                 System.out.println();
             }
         } catch (Exception e) {
             // TODO Auto-generated catch block
             System.out.println(e.getMessage());
         }
         long consumingTime = System.nanoTime() - startTime;
         System.out.println(consumingTime/1000000+" ms");
     }
 }

运行即可打印出胜负情况,且可以知道胜利的情况下分别对手各牌型比例,以及输的情况下对手的各个牌型的比例

发表评论