GithubHelp home page GithubHelp logo

royalflush's Introduction

Royalflush德州扑克算牌器项目文档

  • Author: Sanhe Hu
  • Date: 2015-08-01
  • Copy Right: Sanhe Hu 2015, all copyright reserved

项目目标

在基本满足实时性的前提下, 也就是10秒以内, 能给出在当前局面下, 玩家输牌的概率。 具体来说, 有下面三种情况:

  1. 玩家有2张手牌, 桌面上有3张公牌, 在当前存活n名敌对玩家时, 玩家输牌的概率。
  2. 玩家有2张手牌, 桌面上有4张公牌, 在当前存活n名敌对玩家时, 玩家输牌的概率。
  3. 玩家有2张手牌, 桌面上有5张公牌, 在当前存活n名敌对玩家时, 玩家输牌的概率。

项目难度分析

桌面上牌越多, 则不确定性越小。所以我们从情况3开始分析起:

情况3

当前已知的公牌和玩家的牌的情况有: C(52, 2) * C(50, 5) = 2,809,475,760种情况。 而之后对手从剩下的45张牌拿到两张手牌的情况有: C(45, 2) = 990, 那么一共就有2,809,475,760 * 990 = 2.8 * 10^12。 这么多的情况即使是用硬盘储存, 假设一对Key, value的所占的空间为: 32(key的整数t) + 32(概率的小数) = 8 bytes, 那么需要的硬盘空间是: 2.8 * 8 = 22.4 PB。 如果假设计算每一种可能性只用0.001秒, 那么计算完所有的情况需要2.8 * 10^9秒, 等于88年。 这还是最简单的情况。

在情况2, 情况1有着更高的不确定性, 所以说用传统的方法是无法将所有的可能性都计算出来的。

下面我们来介绍一些简单的算法知识, 为介绍最终的实时概率算法做铺垫。

扑克牌的哈希

一张牌的哈希

对单张扑克牌的哈希有以下几点要求:

  1. 不同的牌hash值相同。
  2. 大一些的牌的hash值大。

我给出的算法是, 一张牌的哈希值等于: 4*rank + suit。

其中牌面2, 3, ..., Q, K, A的分值为2, 3, ..., 12, 13, 14。

而花色黑桃, 红桃, 梅花, 方片的分值分别为4, 3, 2, 1。

最大的牌是: 黑桃A = 14 * 4 + 4 = 60

多张牌的哈希

多张牌的哈希用于快速的将手牌映射为一个整数, 这样可以唯一将手牌映射为整数, 也能从整数反过来解析出手牌。

在这里我使用位图(bitmap)作为多张牌的hash值。这是因为在德州扑克中手牌不可能重复, 所以是一个集合的概念。

多张牌哈希算法如下:

  1. 由最低位初始化一串全0的二进制数
  2. 对于手牌中的所有牌求hash值, 例如三张手牌: [12, 34, 51]
  3. 将从低到高的第x位置1, 计算完所有牌后得到的数就是多张牌的hash值。(有可能是一个大整数)

计算结果哈希表缓存

5张牌的缓存

从52张牌随机选出5张牌, 有C(52, 5) = 2598960种组合。 计算出所有组合的分值(score)。计算出5张牌的hash值。那么我们可以得到一个大字典:

five_cards_score_dict = {5-bitmap: score} # dump this file to database and five_cards_score.pickle

这样我们就可以快速的获得每一种5张牌的分值了。

7张牌的缓存

从52张牌随机选出7张牌, 有C(52, 7) = 种组合。 对于每种组合, 计算出所有牌组中最大的那组, 并求得其hash值, 然后利用5张牌缓存哈希表直接求得手牌大小分值。 在数据库中, 我们保存: {7-bitmap: 5-bitmap}。 而在本地文件大字典中我们保存: {7-bitmap: score}。这样我们可以直接通过7张牌的hash值, 查表获得其手牌大小。

输牌概率算法

River round, 即5张公牌的情况

此时玩家有2张手牌, 还有52 - 5 - 2 = 45张牌未知。 那么对于任意一个对手, 他的手牌有C(45, 2) = 990种可能。 我们只需要遍历所有可能的手牌, 和公牌合并, 计算出对手的分数。然后比较有多少种可能性可以击败玩家。 然后用总数除以990就是玩家输的概率。 注意, 这个概率是场面上只有一个对手时的概率。

board_5_cards # 5张公牌
rest_45_cards # 剩余的45张牌
my_score # 我当前的分值
counter = 0
for two_cards in itertools.combinations(rest_45_cards, 2):
    enemy_all = board_5_cards + list(two_cards)
    
    # 计算敌人手牌的分值
    enemy_score = find_best_pocker_hand_score_using_cache(enemy_all)
    
    if enemy_score > my_score:
        counter += 1

lose_odd = counter/990
win_odd = 1 - lose_odd # 赢的概率

当此时场上还剩下N个对手时候, 此时玩家输的概率是:

lose_odd = 1 - win_odd ** N # 场上有N个玩家时输的概率

Note: 此算法在使用内存缓存的情况下, 平均耗时0.005秒

Turn round, 即4张公牌的情况

此时还有46张牌未知。 那么我们只需要遍历这46张牌, 然后与4张公牌凑成完整的5张公牌, 分别计算出每个情况下玩家赢的条件概率。求和之后除以46即是玩家的win_odd

同样使用下面公式求得在N个对手时, 玩家输的总概率:

lose_odd = 1 - win_odd ** N # 场上有N个玩家时输的概率

Flop round, 即3张公牌的情况

此时还有47张牌未知, 也就是说公牌还有C(47, 2) = 1081种可能性。 类似于Turn round, 对这1081种可能性遍历后用贝叶斯公式求得总概率, 即可得到玩家输的概率。

royalflush's People

Contributors

machu-gwu avatar

Watchers

 avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.