commit b9a598cf0a8b995cfdf2f394a8474b34c6964965
parent 78e8a718c1c0e6a5c30770f85f4a4de90ef390f3
Author: n0tr1v <n0tr1v@protonmail.com>
Date: Fri, 8 Dec 2023 03:53:46 -0500
better split pot algo
Diffstat:
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}},