Search code examples
c#poker

Fill poker pots


Essentially there is a table and player A raises to 100$, player B calls (accepts), player C only has 50$ so the pots are created as 100$ (between player A and B) and 150$ (between all three players because everyone chips in at 50$).

How would I implement such a function and handle all the pots properly? This is what I have so far:

static public void FillPots(Room r, decimal Val, int Player)
        {
            decimal NewRaise = Val;

            if (NewRaise > 0)
            {
                foreach (Program.Player pz in r.Seated)
                {
                    if (pz == null) { continue; }
                    if (pz.BuyIn < NewRaise)
                    {
                        Pot _pot = new Pot { PotSize = r.MaxPlayers, PotBuy = (NewRaise - pz.BuyIn), PotVal = new decimal[r.MaxPlayers] };
                        Array.Clear(_pot.PotVal, 0, r.MaxPlayers);
                        r.Pots.Add(_pot);
                        NewRaise -= (NewRaise - pz.BuyIn);
                    }
                }
            }

            for (int i = 0; i < r.Pots.Count; i++)
            {
                if (r.Pots[i].PotVal[Player] == 0m && NewRaise >= r.Pots[i].PotBuy)
                {
                    r.Pots[i].PotVal[Player] += r.Pots[i].PotBuy;
                    NewRaise -= r.Pots[i].PotBuy;
                }
            }

            if (NewRaise > 0)
            {
                Pot _pot = new Pot { PotSize = r.MaxPlayers, PotBuy = (NewRaise), PotVal = new decimal[r.MaxPlayers] };
                Array.Clear(_pot.PotVal, 0, r.MaxPlayers);
                _pot.PotVal[Player] += NewRaise;
                r.Pots.Add(_pot);
                NewRaise = 0;
            }
        }

It's all pretty confusing. It is critical to keep the position of every individual player relative to the player number (int Player) within the array.


Solution

  • I can't speak to C#, but since you have no answers here I'll tell you in general how to handle poker pots. There are two methods: pot-centric and player-centric. I generally prefer the latter since there is less data to manage.

    You need one variable for the "combined pot" (let's call it POT), one variable for the "current total bet amount" (CBET), one for last raise amount (LRAISE), and three variables for each player: stake (PSTAKE[N]), "current bet" (PBET[N]), "contribution to pot" (PCONTRIB[N]).

    When the hand is dealt, set POT and each player's PCONTRIB[] to 0. If there were antes, add them to POT and to each player's PCONTRIB[], removing them from PSTAKE[].

    At the start of each betting round, set CBET, LRAISE and all PBET[] to 0. If this is the first round, and there are blinds, set those players' PBET[] to the blind amounts, removing them from PSTAKE[].

    Each player in turn has three choices: (1) fold (you might want to disallow this if CBET is 0), (2) call, in which case he must make his PBET[] equal to CBET (if CBET is 0, this is called a "check", otherwise the call amount is CBET-PBET[], which must be moved from PSTAKE[] to PBET[]). (3) raise, in which the player must increase the CBET amount by at least LRAISE (and obeying any other limits, this amount becoming the new LRAISE), moving the needed amount from his stake. Note: you also need to keep track of who the last raiser was, so that he is not allowed to raise himself.

    If the player's stake is insufficient to call or raise, he can go "all in" (if otherwise allowed) moving his entire stake to his PBET[]. When all players have called CBET or gone all in, the betting round is over. If one player raised, all the others folded, and none is all in, then just award the pot to the raiser. Otherwise for each player, add his PBET[] to his PCONTRIB[] and to the POT.

    If hand continues to showdown, award the pot like this: Start with the best hand: his winnable amount (W) is his PCONTRIB[]. Go to each player (including him), subtract from POT the lesser of W and that player's PCONTRIB[], and award it to winner. Remove winner from player list, remove any players whose PCONTRIB[] is now 0, and continue with next best hand. Remove that winner, etc., and continue until POT is 0.


    The pot-centric method I think is more complex. Instead of keeping each player's contribution, you keep a list of central pot and side pots, and for each pot a list of players involved in that pot (there might be as many pots as players). Then the pots are awarded outside-in, instead of inside-out as above. This is more like how dealers are taught to do it in real games.