编码德州扑克的逻辑子锅系统

时间:2012-09-27 07:19:01

标签: c++ containers poker

编辑似乎我对游戏实际运作方式有不同的反应,在阅读官方规则后,与众多扑克伙伴交谈,我想我自己也不了解规则。任何澄清将不胜感激。

我正在使用MSVC ++ 2010 Express中的小型扑克游戏,并且一直试图想出一种方法来编写子锅系统。出于某种原因,我无法理解它应该如何工作,并且想知道是否可以发布一些方法来解决它。这是一种特殊的情况,可能会发生在德州扑克游戏中。

情况:

玩家A首次采取行动,筹码50美元,并决定全押。玩家B加注到150美元。玩家C只有价值70美元的筹码并且决定全押。玩家D只有20美元并全押。现在,我如何设计一个子锅机制来跟踪所有这些。

根据我的理解,会发生什么:

玩家A以50美元创造主要底池。你将B和C的50美元组合起来,使主要的底池价格达到150美元。然后你将玩家B的剩余物100美元分成80美元和20美元。然后为玩家B和C制作一个价值40美元的子底池(玩家C从70美元的剩余部分),然后你回馈玩家B的80美元正弦无人能够覆盖它。玩家D的20美元投注进入玩家B,Cs $ 40子投注,现在价值60美元。 * (或者这不会被添加吗?它不会被添加到任何赌注中,因为它无法覆盖50美元的主要底池,如果是这样,那么它们就不会被添加到任何东西中*

现在,当它进行评估时。如果玩家A获胜,他将赢得玩家A,B和C的150美元。接下来,玩家B,C和D将使用他们的子底池价值60美元。

如果球员B获胜,他将赢得一切。

如果玩家C获胜,他将赢得玩家A,B和C的150美元。然后他挑战玩家B,D玩60美元。

玩家D只能赢得60美元,而当有人下降到这么远时,有人会赢得玩家A,B和C底池。 (取决于是否将此添加到B和C的底池,因为它不包括主要的50 $赌注)

这一切应该如何运作?我正在努力弄清楚如何跟踪每个赌注和子底池。任何想法或实现它的逻辑方法都会有很大帮助。感谢您的时间。 : - )

我正在考虑让每个赌注都是一个唯一的ID,或者每一轮都有一个id,然后将每个赌注添加到要评估的数组中,该数组也指向具有玩家信息的容器。我还必须考虑到一些玩家可能在子底池中并且已经在手中并且折叠,这意味着,我也必须跟踪它。

3 个答案:

答案 0 :(得分:2)

在这个例子中,主壶和侧壶的计算都是错误的。

规则:执政的原则是,每个球员都会像对手的赌注那样匹配对手的赌注。

计算:

1)首先,我们考虑一个筹码最少的玩家(全押)。在当前示例中,这是一个20美元的玩家D.

2)接下来我们从每个玩家(A,B,C,D)总结20美元,主要筹码等于80美元,所有玩家都有争议。

3)球员的筹码留下A - $ 30,B - $ 130,C - $ 50,D - $ 0

4)接下来我们考虑第二小筹码,在当前示例中,这是剩下30美元的玩家A。侧罐1形成等于30美元(A)+ 30美元(B)+ 30美元(C)= 90美元。玩家D因为没钱而无法赢得这个底池。

5)玩家的筹码留下A - $ 0,B - $ 100,C - $ 20

6)侧罐2的形成等于20美元(B)+ 20美元(C)= 40美元。玩家A因为没钱而无法赢得这个底池。

7)玩家B剩下80美元,这笔款项将归还给他。

所以我们终于得到了:

主力杯= 80美元,由所有球员A,B,C,D提出质疑

Side pot1 = $ 90,由A,B,C提出异议

Side pot2 = 40美元,由B,C提出质疑

$ 80返回玩家B

答案 1 :(得分:0)

你的例子自己说话。在第一次下注或每次下注与初始下注不同时创建子牌。有一些属性:

  • 一次投注是单身子投注
  • 如果新金额不同,现有的底池应该可以拆分
  • 可以合并相同数量的花盆

所以对于Subpot类的想法:

  • 一个子牌由一个独特的金额和几个玩家组成
  • 一次投注是单身子投注
  • 两个具有相同金额(金钱)的子点可以合并形成一个新的子库(如套)
  • 子邮箱可以分为两个supbot,amount = amount1 + amount2;
  • 每次添加新赌注时,首先按差价分割,然后合并相同金额的底池。 即

    //laughable attempt
    class Subpot{
      int amount; //oops i mean bet
      int pot; //actually function = amount x participants
      std::vector<Players*> participants;
    
      bool split(int amounta, int amountb, Subpot& a, Subpot& b);
      static bool merge(Subpot& a, Subpot& b , Subpot& dest);
    }
    

现在,每当有一只新手时,你就可以使用之前稳定的子集,并创建下一代子点

  • 创建子手牌
  • 添加到subpot集(什么设置?见下文)
  • 选择较小的赌注betSmall
  • 将所有现有的大小分配给betSmall,并下注 - betSmall
  • 合并大小betSmall
  • 如果我没有弄错,现在你有一套稳定的subPot

答案 2 :(得分:0)

我这样做的方法是制作一个单独的容器,该容器可以保存下注,跟踪谁下注和多少。

std::list<std::map<PlayerID, Chips>> wagers;
unsigned n_raises;  // to keep track of number of raises, useful in limit holdem

我假设您手中有一个活跃玩家列表/数组。

现在,如果玩家拨打电话,您只需将其ID和筹码金额插入位于列表后面的地图中。

如果玩家加注,则在列表后面的地图中插入ID和匹配的筹码金额,然后推回另一张地图。您插入在此新背面中筹集的金额。相应地更新n_raisesto_call

当插入玩家的赌注时,你需要从列表的开头迭代并在你第一次遇到没有该玩家筹码的地图时开始插入。前面可能有多次加注,所以你显然不能总是只插入最后一张地图。

棘手的情况是当玩家没有足够的筹码来覆盖整个电话。在这种情况下,你可以找到他发射筹码的地图,在其后面插入一张新地图,然后转移玩家无法在这张新地图中覆盖的所有筹码(其他玩家)。 (在这种情况下,我们不会更新n_raises

以下是4名球员A,B,C,D的全部外观:

Player A bet 100

    map0:  (A,100)    

Player B calls:

    map0: (A, 100) (B,100)

Player C raises to 300:

    map0: (A, 100) (B,100) (C,100)
    map1: (C, 200)

Player D calls:

    map0: (A, 100) (B,100) (C,100) (D,100)
    map1: (C, 200) (D,200)

Player A's turn, he folds.
Player B calls, but he's got only 50 left:

    map0: (A, 100) (B,100) (C,100) D(100): 
    map1: (B, 50) (C, 50) (D,50)           <--- here we have split the map in two   
    map2: (C, 150) (D, 150)

The betting round is over.

你可以为每轮下注单独列出一个单独的列表,或只保留一个并保留迭代器的副本以便开始新一轮下注。

现在很容易划分底池。你确定最好的牌并开始弹出列表前面的地图,同时拥有最佳牌局的玩家参与地图。如果之后列表为空,那么你就完成了。否则,确定第二个最佳牌并重复。

在上面的例子中,如果玩家B以最好的牌结束,你将他推送到map0和map1。 map2将成为C和D的获胜者。

让我们试试你的例子:

  

玩家A首次采取行动,筹码50美元,并决定全押。玩家B加注到150美元。玩家C只有价值70美元的筹码并且决定全押。玩家D只有20美元而全押。

map0: (A,50)
---------------------
map0: (A,50) (B,50)
map1: (B,100)
---------------------
map0: (A,50) (B,50) (C, 50)
map1: (B,20) (C,20)
map2: (B,80)
--------------------
map0: (A,20) (B,20) (C,20) (D,20)
map1: (A,30) (B,30) (C,30)
map2: (B,20) (C,20)
map3: (B,80)

我认为这与我们在实际扑克桌上的表现非常相似,如果我要写扑克游戏,我可能会这样做。希望它有所帮助:)