在扑克中分配边池
Distributing side pots in poker
你好,我正在开发一个扑克应用程序,我在分配边池时遇到了一些问题。
主要问题是我不知道如何分配弃牌(死筹码)玩家的筹码。
现在我的代码执行以下操作:
- 获得全押玩家的最小投注。
- 将其乘以下注超过该金额的玩家人数。
- 将彩池分给下注超过金额的玩家中的赢家。
- 将全押减去以下边池。
- 重复第 1 步,直到没有更多的罐子可以分配。
这在所有玩家都全押时有效,但如果有人弃牌,事情就会变得棘手。
例如:
A bet(200).
B all-in (80).
C all-in (400).
A folds.
B wins the hand.
那么第一锅就是B(80)+C(80)剩下的给C
答:+0。
乙:+80。
摄氏度:+520。
显然这里做错了,因为 B 有权争夺 A 下注的 80 个筹码。
考虑每位玩家下注的第 n 个筹码。有资格获得该筹码的玩家是那些没有弃牌且至少下注 n 的玩家。将筹码分配给持有最佳手牌的合格玩家。
在你的例子中:
A 200 fold
B 80 call [best hand]
C 400 call
- A 的筹码 1-80 有 2 名符合条件的玩家(B 和 C),B 有最好的一手牌。所以B取80.
- A 的筹码 81-200 有 1 名符合条件的玩家 (C)。 C取120.
- B 的筹码 1-80 有 2 名符合条件的玩家(B 和 C),B 有最好的一手牌。所以B取80.
- C 的筹码 1-80 有 2 名符合条件的玩家(B 和 C),B 有最好的一手牌。所以B取80.
- C 的筹码 81-400 有 1 名符合条件的玩家 (C)。 C取320.
总的来说,B取240,C取440
我把描述写成一个筹码一个筹码,但你可以优化(就像我在工作示例中所做的那样)通过考虑所有未弃牌玩家的下注大小下的筹码削减范围(即:在在您的示例中为 80 和 400)。
此代码应处理所有情况,并负责向弃牌玩家分配筹码。我猜你的代码已经完成了很长时间,但我无法在 Whosebug 上找到在我处理这个扑克边罐问题时有意义的代码示例,所以我分享我自己的...
using System;
using System.Collections.Generic;
public class Player
{
public ulong potCommitment;
public uint handStrength;
public ulong chipsRemaining;
public bool folded = false;
public Player(ulong pc, uint hs, ulong chipsBehind, bool isFolded): this(pc, hs, chipsBehind)
{
folded = isFolded;
}
public Player(ulong pc, uint hs, ulong chipsBehind)
{
potCommitment = pc;
handStrength = hs;
chipsRemaining = chipsBehind;
}
}
public class Program
{
public static List<Player> winners = new List<Player>();
public static List<Player> players = new List<Player>();
public static void Main()
{
players.Add(new Player(200, 60, 0, true));
players.Add(new Player(80, 100, 0));
players.Add(new Player(400, 85, 0, false));
// Loop through players until no unclaimed chips in pot.
while (PotChipsRemaining(players) > 0)
PayOutWinners(CalculateAndSortWinners(players), players);
// Refund players if remaining chips in pot (bigger/folded stacks)
foreach (var player in players)
{
player.chipsRemaining += player.potCommitment;
player.potCommitment = 0;
}
Console.WriteLine($"***********************\nFinal results:");
PotChipsRemaining(players);
}
public static List<Player> CalculateAndSortWinners(List<Player> playersInHand)
{
uint highHand = 0;
// Get highHand, skipping folded and empty pots
foreach (var player in players) if (player.potCommitment > 0 && !player.folded)
{
if (player.handStrength > highHand)
{
winners.Clear();
highHand = player.handStrength;
winners.Add(player);
}
else if (player.handStrength == highHand)
{
winners.Add(player);
}
}
winners.Sort((x, y) => x.potCommitment.CompareTo(y.potCommitment));
return winners;
}
public static void PayOutWinners(List<Player> winners, List<Player> playersInHand)
{
ulong collectedSidePot;
ulong currentCommitment, collectionAmount;
List<Player> paidWinners = new List<Player>();
foreach (var playerPot in winners)
{
collectedSidePot = 0;
currentCommitment = playerPot.potCommitment;
// Collect from all players who have money in pot
foreach (var player in playersInHand) if (player.potCommitment > 0)
{
collectionAmount = Math.Min(currentCommitment, player.potCommitment);
player.potCommitment -= collectionAmount;
collectedSidePot += collectionAmount;
}
int winnersToPay = 0;
Console.WriteLine($"winners.count {winners.Count}");
foreach (var player in winners) if (paidWinners.IndexOf(player) == -1) winnersToPay++;
Console.WriteLine($"collectedSidePot: {collectedSidePot} winnersToPay: {winnersToPay}");
// Pay unpaid winners, tip dealer with remainders...
foreach (var player in winners) if (paidWinners.IndexOf(player) == -1)
{
player.chipsRemaining += collectedSidePot / (ulong)winnersToPay;
if (player.potCommitment <= 0)
{
paidWinners.Add(player);
Console.WriteLine($"Player {players.IndexOf(player)} paid out.");
}
}
}
winners.Clear();
}
// Only count potchips for unfolded players. Also prints status to Console.
public static ulong PotChipsRemaining(List<Player> playersInHand)
{
ulong tally = 0;
foreach (var player in playersInHand) if (!player.folded)
{
Console.WriteLine($"Player {players.IndexOf(player)} chips: {player.chipsRemaining} Commitment: {player.potCommitment} \tHandStrength: {player.handStrength}\tFolded: {player.folded}");
tally += player.potCommitment;
}
foreach (var player in playersInHand) if (player.folded)
Console.WriteLine($"Player {players.IndexOf(player)} chips: {player.chipsRemaining} Commitment: {player.potCommitment} \tHandStrength: {player.handStrength}\tFolded: {player.folded}");
return tally;
}
}
根据你的例子,我得到了这个结果:
Final results:
Player A chips: 0 HandStrength: 60 Folded: True
Player B chips: 240 HandStrength: 100 Folded: False
Player C chips: 440 HandStrength: 85 Folded: False
如果您有任何问题,请告诉我。
这里是fiddle,可以测试场景:
https://dotnetfiddle.net/P0wgR5
你好,我正在开发一个扑克应用程序,我在分配边池时遇到了一些问题。
主要问题是我不知道如何分配弃牌(死筹码)玩家的筹码。
现在我的代码执行以下操作:
- 获得全押玩家的最小投注。
- 将其乘以下注超过该金额的玩家人数。
- 将彩池分给下注超过金额的玩家中的赢家。
- 将全押减去以下边池。
- 重复第 1 步,直到没有更多的罐子可以分配。
这在所有玩家都全押时有效,但如果有人弃牌,事情就会变得棘手。
例如:
A bet(200).
B all-in (80).
C all-in (400).
A folds.
B wins the hand.
那么第一锅就是B(80)+C(80)剩下的给C
答:+0。
乙:+80。
摄氏度:+520。
显然这里做错了,因为 B 有权争夺 A 下注的 80 个筹码。
考虑每位玩家下注的第 n 个筹码。有资格获得该筹码的玩家是那些没有弃牌且至少下注 n 的玩家。将筹码分配给持有最佳手牌的合格玩家。
在你的例子中:
A 200 fold
B 80 call [best hand]
C 400 call
- A 的筹码 1-80 有 2 名符合条件的玩家(B 和 C),B 有最好的一手牌。所以B取80.
- A 的筹码 81-200 有 1 名符合条件的玩家 (C)。 C取120.
- B 的筹码 1-80 有 2 名符合条件的玩家(B 和 C),B 有最好的一手牌。所以B取80.
- C 的筹码 1-80 有 2 名符合条件的玩家(B 和 C),B 有最好的一手牌。所以B取80.
- C 的筹码 81-400 有 1 名符合条件的玩家 (C)。 C取320.
总的来说,B取240,C取440
我把描述写成一个筹码一个筹码,但你可以优化(就像我在工作示例中所做的那样)通过考虑所有未弃牌玩家的下注大小下的筹码削减范围(即:在在您的示例中为 80 和 400)。
此代码应处理所有情况,并负责向弃牌玩家分配筹码。我猜你的代码已经完成了很长时间,但我无法在 Whosebug 上找到在我处理这个扑克边罐问题时有意义的代码示例,所以我分享我自己的...
using System;
using System.Collections.Generic;
public class Player
{
public ulong potCommitment;
public uint handStrength;
public ulong chipsRemaining;
public bool folded = false;
public Player(ulong pc, uint hs, ulong chipsBehind, bool isFolded): this(pc, hs, chipsBehind)
{
folded = isFolded;
}
public Player(ulong pc, uint hs, ulong chipsBehind)
{
potCommitment = pc;
handStrength = hs;
chipsRemaining = chipsBehind;
}
}
public class Program
{
public static List<Player> winners = new List<Player>();
public static List<Player> players = new List<Player>();
public static void Main()
{
players.Add(new Player(200, 60, 0, true));
players.Add(new Player(80, 100, 0));
players.Add(new Player(400, 85, 0, false));
// Loop through players until no unclaimed chips in pot.
while (PotChipsRemaining(players) > 0)
PayOutWinners(CalculateAndSortWinners(players), players);
// Refund players if remaining chips in pot (bigger/folded stacks)
foreach (var player in players)
{
player.chipsRemaining += player.potCommitment;
player.potCommitment = 0;
}
Console.WriteLine($"***********************\nFinal results:");
PotChipsRemaining(players);
}
public static List<Player> CalculateAndSortWinners(List<Player> playersInHand)
{
uint highHand = 0;
// Get highHand, skipping folded and empty pots
foreach (var player in players) if (player.potCommitment > 0 && !player.folded)
{
if (player.handStrength > highHand)
{
winners.Clear();
highHand = player.handStrength;
winners.Add(player);
}
else if (player.handStrength == highHand)
{
winners.Add(player);
}
}
winners.Sort((x, y) => x.potCommitment.CompareTo(y.potCommitment));
return winners;
}
public static void PayOutWinners(List<Player> winners, List<Player> playersInHand)
{
ulong collectedSidePot;
ulong currentCommitment, collectionAmount;
List<Player> paidWinners = new List<Player>();
foreach (var playerPot in winners)
{
collectedSidePot = 0;
currentCommitment = playerPot.potCommitment;
// Collect from all players who have money in pot
foreach (var player in playersInHand) if (player.potCommitment > 0)
{
collectionAmount = Math.Min(currentCommitment, player.potCommitment);
player.potCommitment -= collectionAmount;
collectedSidePot += collectionAmount;
}
int winnersToPay = 0;
Console.WriteLine($"winners.count {winners.Count}");
foreach (var player in winners) if (paidWinners.IndexOf(player) == -1) winnersToPay++;
Console.WriteLine($"collectedSidePot: {collectedSidePot} winnersToPay: {winnersToPay}");
// Pay unpaid winners, tip dealer with remainders...
foreach (var player in winners) if (paidWinners.IndexOf(player) == -1)
{
player.chipsRemaining += collectedSidePot / (ulong)winnersToPay;
if (player.potCommitment <= 0)
{
paidWinners.Add(player);
Console.WriteLine($"Player {players.IndexOf(player)} paid out.");
}
}
}
winners.Clear();
}
// Only count potchips for unfolded players. Also prints status to Console.
public static ulong PotChipsRemaining(List<Player> playersInHand)
{
ulong tally = 0;
foreach (var player in playersInHand) if (!player.folded)
{
Console.WriteLine($"Player {players.IndexOf(player)} chips: {player.chipsRemaining} Commitment: {player.potCommitment} \tHandStrength: {player.handStrength}\tFolded: {player.folded}");
tally += player.potCommitment;
}
foreach (var player in playersInHand) if (player.folded)
Console.WriteLine($"Player {players.IndexOf(player)} chips: {player.chipsRemaining} Commitment: {player.potCommitment} \tHandStrength: {player.handStrength}\tFolded: {player.folded}");
return tally;
}
}
根据你的例子,我得到了这个结果:
Final results:
Player A chips: 0 HandStrength: 60 Folded: True
Player B chips: 240 HandStrength: 100 Folded: False
Player C chips: 440 HandStrength: 85 Folded: False
如果您有任何问题,请告诉我。
这里是fiddle,可以测试场景: https://dotnetfiddle.net/P0wgR5