dkforest

A forum and chat platform (onion)
git clone https://git.dasho.dev/n0tr1v/dkforest.git
Log | Files | Refs | LICENSE

commit b9a598cf0a8b995cfdf2f394a8474b34c6964965
parent 78e8a718c1c0e6a5c30770f85f4a4de90ef390f3
Author: n0tr1v <n0tr1v@protonmail.com>
Date:   Fri,  8 Dec 2023 03:53:46 -0500

better split pot algo

Diffstat:
Mpkg/web/handlers/poker/poker.go | 35++++++++++++++++++++++++++++-------
Mpkg/web/handlers/poker/poker_test.go | 20++++++++++----------
2 files changed, 38 insertions(+), 17 deletions(-)

diff --git a/pkg/web/handlers/poker/poker.go b/pkg/web/handlers/poker/poker.go @@ -101,6 +101,7 @@ type PokerPlayer struct { RoundTotalBet int Bet int Cash int + AllInMaxGain int SeatIdx int // 0 indexed Cards []PlayerCard CardsMtx sync.RWMutex @@ -160,11 +161,11 @@ func (g *Ongoing) computeWinners() (winner []GameResult) { poker.NewCard(cardToPokerCard(playerCard1)), poker.NewCard(cardToPokerCard(playerCard2)), } - e := poker.Evaluate(hand) - if _, ok := m[e]; !ok { - m[e] = make([]*PokerPlayer, 0) + handEvaluation := poker.Evaluate(hand) + if _, ok := m[handEvaluation]; !ok { + m[handEvaluation] = make([]*PokerPlayer, 0) } - m[e] = append(m[e], p) + m[handEvaluation] = append(m[handEvaluation], p) } arr := make([]GameResult, 0) @@ -371,6 +372,8 @@ func waitPlayersActionFn(g *PokerGame, roomID string, skip, minBet int) bool { // Used to skip small/big blinds on first round skipIsDone := false + newlyAllInPlayers := make([]*PokerPlayer, 0) + OUTER: for { // Loop until the round is settled players := reorderPlayers(g.Ongoing.Players, dealerIdx) @@ -472,6 +475,7 @@ OUTER: logMsg := fmt.Sprintf("%s call (%d)", p.Username, bet) if p.Cash == 0 { logMsg += " (all-in)" + newlyAllInPlayers = append(newlyAllInPlayers, p) } newLogEvent(g, roomLogsTopic, logMsg) @@ -496,6 +500,7 @@ OUTER: logMsg := fmt.Sprintf("%s bet %d", p.Username, bet) if p.Cash == 0 { logMsg += " (all-in)" + newlyAllInPlayers = append(newlyAllInPlayers, p) } newLogEvent(g, roomLogsTopic, logMsg) @@ -524,6 +529,14 @@ OUTER: time.Sleep(time.Second) + for _, p := range newlyAllInPlayers { + maxGain := g.Ongoing.MainPot + for _, op := range g.Ongoing.Players { + maxGain += utils.MinInt(op.Bet, p.Bet) + } + p.AllInMaxGain = maxGain + } + // Transfer players bets into the main pot for _, p := range g.Ongoing.Players { g.Ongoing.MainPotMtx.Lock() @@ -795,6 +808,14 @@ type PlayerGain struct { } func processPot(winners []GameResult, nbPlayers, mainPot int) (res []PlayerGain) { + /* + 100 100 100 100 100 // 500 + 10A 10 10 10 F // 40 -> 540 + A 100 100 F F + A 50 50 F F + + 17A 13A 15A 21A + */ if len(winners) == 0 { logrus.Error("winners has len 0") } else if len(winners) == 1 && len(winners[0].Players) == 1 { @@ -816,8 +837,7 @@ func processPot(winners []GameResult, nbPlayers, mainPot int) (res []PlayerGain) } else if len(group.Players) == 1 && group.Players[0].Cash == 0 { // Only 1 player win but is all-in player := group.Players[0] - maxGain := player.RoundTotalBet * nbPlayers - piece := utils.MinInt(maxGain, mainPot) + piece := player.AllInMaxGain res = append(res, PlayerGain{player, piece, groupIdx, handStr}) mainPot -= piece isDone = false @@ -829,7 +849,7 @@ func processPot(winners []GameResult, nbPlayers, mainPot int) (res []PlayerGain) for _, p := range group.Players { if p.Cash == 0 { // all-in allInCount++ - maxGain := p.RoundTotalBet * nbPlayers + maxGain := p.AllInMaxGain piece := utils.MinInt(maxGain, expectedSplit) res = append(res, PlayerGain{p, piece, groupIdx, handStr}) mainPot -= piece @@ -840,6 +860,7 @@ func processPot(winners []GameResult, nbPlayers, mainPot int) (res []PlayerGain) } } } + // If everyone in the group was all-in, we need to evaluate the next group as well if allInCount == nbPlayersInGroup { isDone = false continue diff --git a/pkg/web/handlers/poker/poker_test.go b/pkg/web/handlers/poker/poker_test.go @@ -50,9 +50,9 @@ func Test_processPot(t *testing.T) { var arr []GameResult var res []PlayerGain - p1 = &PokerPlayer{Cash: 0, RoundTotalBet: 100, Username: "p1"} - p2 = &PokerPlayer{Cash: 0, RoundTotalBet: 200, Username: "p2"} - p3 = &PokerPlayer{Cash: 0, RoundTotalBet: 300, Username: "p3"} + p1 = &PokerPlayer{Cash: 0, RoundTotalBet: 100, AllInMaxGain: 400, Username: "p1"} + p2 = &PokerPlayer{Cash: 0, RoundTotalBet: 200, AllInMaxGain: 700, Username: "p2"} + p3 = &PokerPlayer{Cash: 0, RoundTotalBet: 300, AllInMaxGain: 900, Username: "p3"} p4 = &PokerPlayer{Cash: 1, RoundTotalBet: 400, Username: "p4"} arr = []GameResult{ {1, []*PokerPlayer{p2, p4, p1, p3}}, @@ -64,9 +64,9 @@ func Test_processPot(t *testing.T) { assert.Equal(t, 250, res[2].Gain) assert.Equal(t, 250, res[3].Gain) - p1 = &PokerPlayer{Cash: 0, RoundTotalBet: 10, Username: "p1"} - p2 = &PokerPlayer{Cash: 0, RoundTotalBet: 20, Username: "p2"} - p3 = &PokerPlayer{Cash: 0, RoundTotalBet: 300, Username: "p3"} + p1 = &PokerPlayer{Cash: 0, RoundTotalBet: 10, AllInMaxGain: 40, Username: "p1"} + p2 = &PokerPlayer{Cash: 0, RoundTotalBet: 20, AllInMaxGain: 70, Username: "p2"} + p3 = &PokerPlayer{Cash: 0, RoundTotalBet: 300, AllInMaxGain: 630, Username: "p3"} p4 = &PokerPlayer{Cash: 1, RoundTotalBet: 400, Username: "p4"} arr = []GameResult{ {1, []*PokerPlayer{p2, p4, p1, p3}}, @@ -74,12 +74,12 @@ func Test_processPot(t *testing.T) { sortGameResults(arr) res = processPot(arr, 4, 1000) assert.Equal(t, 40, res[0].Gain) - assert.Equal(t, 80, res[1].Gain) - assert.Equal(t, 440, res[2].Gain) - assert.Equal(t, 440, res[3].Gain) + assert.Equal(t, 70, res[1].Gain) + assert.Equal(t, 445, res[2].Gain) + assert.Equal(t, 445, res[3].Gain) p1 = &PokerPlayer{Cash: 1, RoundTotalBet: 500, Username: "p1"} - p2 = &PokerPlayer{Cash: 0, RoundTotalBet: 500, Username: "p2"} + p2 = &PokerPlayer{Cash: 0, RoundTotalBet: 500, AllInMaxGain: 1000, Username: "p2"} arr = []GameResult{ {1, []*PokerPlayer{p2}}, {2, []*PokerPlayer{p1}},