一道算法题:德州扑克多家ALLIN如何分筹码?算法+代码

2023-08-18 17:03:53 浏览数 (1)

难点

虽然95%以上的场景,都是一家胜出,但是你要做系统,就要覆盖100%的场景。

给你举个特殊场景的例子:

  • 玩家1: ALLIN 100 牌最大
  • 玩家2: ALLIN 200 牌也最大
  • 玩家3: ALLIN 200 牌第二大
  • 玩家4: ALLIN 400 牌也第二大
  • 玩家5: ALLIN 1000 牌第三大
  • 玩家6: ALLIN 2000 牌第四大
  • 玩家7: ALLIN 400 牌最小

整个底池:4300,这时候怎么分筹码?

你先思考一下。即使你不知道,也可以想想,如果让你来设计分法,怎么分最公平?

我可以明确告诉你:不是玩家1和2平分4300,也不是玩家1和玩家2按1:2比例分这4300。

分法

先按照所有人拥有的筹码排序:玩家1、2、3、7、4、5、6。

然后,以每人下注100作为主池,做第一次分配。

第一次分配完毕后,每人还有剩余未分配的筹码,再选最小的下注,做第二次分配,这叫边池。

以此类推,直到分配结束。如下表:

至此,分配结束。你看懂分配算法了嘛?

数据结构

我们必须要记清楚,每个玩家本局总共投入了多少筹码,才方便后续计算。

以下变量类型都是python。

第一,定义room['players']是本房间(群聊)的玩家筹码总量信息,是个dict,key是用户ID,value是个dict,形如:

代码语言:javascript复制
{
  'chip': 1000,  # 手上有1000筹码(对局中下注时,这里的值会实时减少,对局结束后再把赢的部分加回来)
}

第二,定义playing_seats是本局的玩家信息,是个list,每一项是个dict,形如:

代码语言:javascript复制
{
  'i': 1,  # 座位号,从0开始
  'id': 'uuid',  # 用户ID,跟room['players']的key对应
  'all_chip': 100,  # 本局投入的所有筹码
  'action': SeatAction.Fold,  # 最终的行动
}

其中action包括:

代码语言:javascript复制
import enum

class SeatAction(enum.IntEnum):
    WAIT = 0
    CHECK = 1
    CALL = 2
    RAISE = 3
    ALLIN = 4
    FOLD = 5
    WIN = 6  # 胜利,不摊牌(适用其他人都Fold的情况)
    WIN_SHOW = 7  # 胜利,需要摊牌
    LOSE_SHOW = 8  # 失败,需要摊牌

开发

排序逻辑

注:cards就是所有牌,是一个长度52的list,每一项的值都是0-51,开局前会做一次shuffle(随机打乱顺序)。底牌、玩家的牌的信息,就藏在这个list中。

先计算5张底牌(PS:我是不是很严谨,按照了专业比赛的发牌顺序hhh

0 人点赞