dkforest

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

commit f263d4f82db1f1a8744db7b4e57670fa12a3d152
parent 692d9327f0f12a32238a2d6abd8e75fafaac8a49
Author: n0tr1v <n0tr1v@protonmail.com>
Date:   Tue,  5 Dec 2023 21:13:53 -0500

cleanup

Diffstat:
Mpkg/web/handlers/poker/poker.go | 510++++++++++++++++++++++++++++++++++++++++---------------------------------------
1 file changed, 257 insertions(+), 253 deletions(-)

diff --git a/pkg/web/handlers/poker/poker.go b/pkg/web/handlers/poker/poker.go @@ -179,317 +179,321 @@ func NewOngoing(g *PokerGame) *Ongoing { return &Ongoing{Deck: deck, Players: players, WaitTurnEvent: PokerWaitTurnEvent{Idx: -1}} } -func (g *PokerGame) Deal(roomID string) { +func dealerThread(g *PokerGame, roomID string) { roomTopic := "room_" + roomID - if g.Ongoing != nil { - if !g.IsGameOver { - fmt.Println("game already ongoing") - return - } else { - g.IsGameOver = false - PokerPubSub.Pub(roomTopic, ResetCardsEvent{}) - time.Sleep(time.Second) - } - } - if g.CountSeated() < 2 { - fmt.Println("need at least 2 players") - return - } + waitPlayersActionFn := func() bool { + lastRisePlayerIdx := -1 + minBet := 0 - g.Ongoing = NewOngoing(g) - - go func() { - waitPlayersActionFn := func() bool { - lastRisePlayerIdx := -1 - minBet := 0 - - playerAlive := 0 - for _, p := range g.Ongoing.Players { - if p != nil && !p.Folded { - playerAlive++ - } + playerAlive := 0 + for _, p := range g.Ongoing.Players { + if p != nil && !p.Folded { + playerAlive++ } + } - // TODO: implement maximum re-rise - OUTER: - for { // Loop until the round is settled - for i, p := range g.Ongoing.Players { - if p == nil { - continue - } - if i == lastRisePlayerIdx { - break OUTER - } - player := g.Ongoing.GetPlayer(p.Username) - if player.Folded { - continue - } - evt := PokerWaitTurnEvent{Idx: i} - PokerPubSub.Pub(roomTopic, evt) - g.Ongoing.WaitTurnEvent = evt - - // Maximum time allowed for the player to send his action - waitCh := time.After(MaxUserCountdown * time.Second) - LOOP: - for { // Repeat until we get an event from the player we're interested in - var evt PlayerEvent - - select { - case evt = <-g.PlayersEventCh: - case <-waitCh: - // Waited too long, either auto-check or auto-fold - if p.Cash == 0 { // all-in - break LOOP - } - if p.Bet < minBet { - player.Folded = true - PokerPubSub.Pub(roomTopic, PlayerFoldEvent{Card1Idx: player.Cards[0].Idx, Card2Idx: player.Cards[1].Idx}) - playerAlive-- - if playerAlive == 1 { - break OUTER - } - } + // TODO: implement maximum re-rise + OUTER: + for { // Loop until the round is settled + for i, p := range g.Ongoing.Players { + if p == nil { + continue + } + if i == lastRisePlayerIdx { + break OUTER + } + player := g.Ongoing.GetPlayer(p.Username) + if player.Folded { + continue + } + evt := PokerWaitTurnEvent{Idx: i} + PokerPubSub.Pub(roomTopic, evt) + g.Ongoing.WaitTurnEvent = evt + + // Maximum time allowed for the player to send his action + waitCh := time.After(MaxUserCountdown * time.Second) + LOOP: + for { // Repeat until we get an event from the player we're interested in + var evt PlayerEvent + + select { + case evt = <-g.PlayersEventCh: + case <-waitCh: + // Waited too long, either auto-check or auto-fold + if p.Cash == 0 { // all-in break LOOP } - - if evt.Player != p.Username { - continue - } - roomUserTopic := "room_" + roomID + "_" + p.Username - if evt.Fold { + if p.Bet < minBet { player.Folded = true PokerPubSub.Pub(roomTopic, PlayerFoldEvent{Card1Idx: player.Cards[0].Idx, Card2Idx: player.Cards[1].Idx}) playerAlive-- if playerAlive == 1 { break OUTER } - } else if evt.Check { - if p.Bet < minBet { - msg := fmt.Sprintf("Need to bet %d", minBet-p.Bet) - PokerPubSub.Pub(roomUserTopic, ErrorMsgEvent{Message: msg}) - continue - } - } else if evt.Call { - bet := minBet - p.Bet - if p.Cash < bet { - bet = p.Cash - p.Bet += bet - p.Cash = 0 - // All in - } else { - p.Bet += bet - p.Cash -= bet - } - PokerPubSub.Pub(roomTopic, PlayerBetEvent{PlayerIdx: i, Player: p.Username, Bet: bet, TotalBet: p.Bet, Cash: p.Cash}) - } else if evt.Bet > 0 { - if (p.Bet + evt.Bet) < minBet { - msg := fmt.Sprintf("Bet (%d) is too low. Must bet at least %d", evt.Bet, minBet-p.Bet) - PokerPubSub.Pub(roomUserTopic, ErrorMsgEvent{Message: msg}) - continue - } - if (p.Bet + evt.Bet) > minBet { - lastRisePlayerIdx = i - } - minBet = p.Bet + evt.Bet - p.Bet += evt.Bet - p.Cash -= evt.Bet - PokerPubSub.Pub(roomTopic, PlayerBetEvent{PlayerIdx: i, Player: p.Username, Bet: evt.Bet, TotalBet: p.Bet, Cash: p.Cash}) } - break + break LOOP } - } - // All settle when all players have the same bet amount - if isRoundSettled(g.Ongoing.Players) { + if evt.Player != p.Username { + continue + } + roomUserTopic := "room_" + roomID + "_" + p.Username + if evt.Fold { + player.Folded = true + PokerPubSub.Pub(roomTopic, PlayerFoldEvent{Card1Idx: player.Cards[0].Idx, Card2Idx: player.Cards[1].Idx}) + playerAlive-- + if playerAlive == 1 { + break OUTER + } + } else if evt.Check { + if p.Bet < minBet { + msg := fmt.Sprintf("Need to bet %d", minBet-p.Bet) + PokerPubSub.Pub(roomUserTopic, ErrorMsgEvent{Message: msg}) + continue + } + } else if evt.Call { + bet := minBet - p.Bet + if p.Cash < bet { + bet = p.Cash + p.Bet += bet + p.Cash = 0 + // All in + } else { + p.Bet += bet + p.Cash -= bet + } + PokerPubSub.Pub(roomTopic, PlayerBetEvent{PlayerIdx: i, Player: p.Username, Bet: bet, TotalBet: p.Bet, Cash: p.Cash}) + } else if evt.Bet > 0 { + if (p.Bet + evt.Bet) < minBet { + msg := fmt.Sprintf("Bet (%d) is too low. Must bet at least %d", evt.Bet, minBet-p.Bet) + PokerPubSub.Pub(roomUserTopic, ErrorMsgEvent{Message: msg}) + continue + } + if (p.Bet + evt.Bet) > minBet { + lastRisePlayerIdx = i + } + minBet = p.Bet + evt.Bet + p.Bet += evt.Bet + p.Cash -= evt.Bet + PokerPubSub.Pub(roomTopic, PlayerBetEvent{PlayerIdx: i, Player: p.Username, Bet: evt.Bet, TotalBet: p.Bet, Cash: p.Cash}) + } break } } - // Transfer players bets into the main pot - for i := range g.Ongoing.Players { - if g.Ongoing.Players[i] != nil { - g.Ongoing.MainPot += g.Ongoing.Players[i].Bet - g.Ongoing.Players[i].Bet = 0 - } + // All settle when all players have the same bet amount + if isRoundSettled(g.Ongoing.Players) { + break } + } - evt := PokerWaitTurnEvent{Idx: -1, MainPot: g.Ongoing.MainPot} - PokerPubSub.Pub(roomTopic, evt) - g.Ongoing.WaitTurnEvent = evt - - return playerAlive == 1 + // Transfer players bets into the main pot + for i := range g.Ongoing.Players { + if g.Ongoing.Players[i] != nil { + g.Ongoing.MainPot += g.Ongoing.Players[i].Bet + g.Ongoing.Players[i].Bet = 0 + } } - type Seat struct { - Top int - Left int - Angle string - Top2 int - Left2 int + evt := PokerWaitTurnEvent{Idx: -1, MainPot: g.Ongoing.MainPot} + PokerPubSub.Pub(roomTopic, evt) + g.Ongoing.WaitTurnEvent = evt + + return playerAlive == 1 + } + + type Seat struct { + Top int + Left int + Angle string + Top2 int + Left2 int + } + seats := []Seat{ + {Top: 50, Left: 600, Top2: 50 + 5, Left2: 600 + 5, Angle: "-90deg"}, + {Top: 150, Left: 574, Top2: 150 + 5, Left2: 574 + 3, Angle: "-80deg"}, + {Top: 250, Left: 530, Top2: 250 + 5, Left2: 530 + 1, Angle: "-70deg"}, + } + + var card string + idx := 0 + + burnCard := func(pos int) { + card = g.Ongoing.Deck[idx] + idx++ + evt := PokerEvent{ + ID: "card" + itoa(idx), + Name: "", + Idx: idx, + Top: BurnStackY + (pos * 2), + Left: BurnStackX + (pos * 4), } - seats := []Seat{ - {Top: 50, Left: 600, Top2: 50 + 5, Left2: 600 + 5, Angle: "-90deg"}, - {Top: 150, Left: 574, Top2: 150 + 5, Left2: 574 + 3, Angle: "-80deg"}, - {Top: 250, Left: 530, Top2: 250 + 5, Left2: 530 + 1, Angle: "-70deg"}, + PokerPubSub.Pub(roomTopic, evt) + g.Ongoing.Events = append(g.Ongoing.Events, evt) + } + + dealCard := func(pos int) { + card = g.Ongoing.Deck[idx] + idx++ + evt := PokerEvent{ + ID: "card" + itoa(idx), + Name: card, + Idx: idx, + Top: 150, + Left: 100 + (pos * 55), + Reveal: true, } + PokerPubSub.Pub(roomTopic, evt) + g.Ongoing.Events = append(g.Ongoing.Events, evt) + } - var card string - idx := 0 + deckHash := utils.MD5([]byte(strings.Join(g.Ongoing.Deck, ""))) + PokerPubSub.Pub(roomTopic, GameStartedEvent{DeckHash: deckHash}) - burnCard := func(pos int) { - card = g.Ongoing.Deck[idx] - idx++ - evt := PokerEvent{ - ID: "card" + itoa(idx), - Name: "", - Idx: idx, - Top: BurnStackY + (pos * 2), - Left: BurnStackX + (pos * 4), + // Deal cards + for j := 1; j <= 2; j++ { + for i, p := range g.Ongoing.Players { + if p == nil { + continue } - PokerPubSub.Pub(roomTopic, evt) - g.Ongoing.Events = append(g.Ongoing.Events, evt) - } - - dealCard := func(pos int) { + if p.Cash == 0 { + continue + } + d := seats[i] + time.Sleep(time.Second) card = g.Ongoing.Deck[idx] idx++ + name := "" + left := d.Left + top := d.Top + if j == 2 { + left = d.Left2 + top = d.Top2 + } evt := PokerEvent{ - ID: "card" + itoa(idx), - Name: card, - Idx: idx, - Top: 150, - Left: 100 + (pos * 55), - Reveal: true, + ID: "card" + itoa(idx), + Name: name, + Idx: idx, + Top: top, + Left: left, + Angle: d.Angle, } + g.Ongoing.Players[i].Cards = append(g.Ongoing.Players[i].Cards, PlayerCard{Idx: idx, Name: card}) PokerPubSub.Pub(roomTopic, evt) + PokerPubSub.Pub(roomTopic+"_"+p.Username, YourCardEvent{Idx: j, Name: card}) g.Ongoing.Events = append(g.Ongoing.Events, evt) } + } - deckHash := utils.MD5([]byte(strings.Join(g.Ongoing.Deck, ""))) - PokerPubSub.Pub(roomTopic, GameStartedEvent{DeckHash: deckHash}) + // Wait for players to bet/call/check/fold... + time.Sleep(time.Second) + if waitPlayersActionFn() { + goto END + } - // Deal cards - for j := 1; j <= 2; j++ { - for i, p := range g.Ongoing.Players { - if p == nil { - continue - } - if p.Cash == 0 { - continue - } - d := seats[i] - time.Sleep(time.Second) - card = g.Ongoing.Deck[idx] - idx++ - name := "" - left := d.Left - top := d.Top - if j == 2 { - left = d.Left2 - top = d.Top2 - } - evt := PokerEvent{ - ID: "card" + itoa(idx), - Name: name, - Idx: idx, - Top: top, - Left: left, - Angle: d.Angle, - } - g.Ongoing.Players[i].Cards = append(g.Ongoing.Players[i].Cards, PlayerCard{Idx: idx, Name: card}) - PokerPubSub.Pub(roomTopic, evt) - PokerPubSub.Pub(roomTopic+"_"+p.Username, YourCardEvent{Idx: j, Name: card}) - g.Ongoing.Events = append(g.Ongoing.Events, evt) - } - } + // Burn + time.Sleep(time.Second) + burnCard(0) - // Wait for players to bet/call/check/fold... + // Flop (3 first cards) + for i := 1; i <= 3; i++ { time.Sleep(time.Second) - if waitPlayersActionFn() { - goto END - } + dealCard(i) + } - // Burn - time.Sleep(time.Second) - burnCard(0) + // Wait for players to bet/call/check/fold... + time.Sleep(time.Second) + if waitPlayersActionFn() { + goto END + } - // Flop (3 first cards) - for i := 1; i <= 3; i++ { - time.Sleep(time.Second) - dealCard(i) - } + // Burn + time.Sleep(time.Second) + burnCard(1) - // Wait for players to bet/call/check/fold... - time.Sleep(time.Second) - if waitPlayersActionFn() { - goto END - } + // Turn (4th card) + time.Sleep(time.Second) + dealCard(4) - // Burn - time.Sleep(time.Second) - burnCard(1) + // Wait for players to bet/call/check/fold... + time.Sleep(time.Second) + if waitPlayersActionFn() { + goto END + } - // Turn (4th card) - time.Sleep(time.Second) - dealCard(4) + // Burn + time.Sleep(time.Second) + burnCard(2) - // Wait for players to bet/call/check/fold... - time.Sleep(time.Second) - if waitPlayersActionFn() { - goto END - } + // River (5th card) + time.Sleep(time.Second) + dealCard(5) - // Burn - time.Sleep(time.Second) - burnCard(2) + // Wait for players to bet/call/check/fold... + time.Sleep(time.Second) + if waitPlayersActionFn() { + goto END + } - // River (5th card) - time.Sleep(time.Second) - dealCard(5) + // Show cards + for _, p := range g.Ongoing.Players { + if p != nil && !p.Folded { + fmt.Println(p.Username, p.Cards) + PokerPubSub.Pub(roomTopic, ShowCardsEvent{Cards: p.Cards}) + } + } - // Wait for players to bet/call/check/fold... - time.Sleep(time.Second) - if waitPlayersActionFn() { - goto END +END: + + // TODO: evaluate hands, and crown winner + var winner *PokerPlayer + for _, p := range g.Ongoing.Players { + if p != nil { + winner = p + break } + } + winner.Cash += g.Ongoing.MainPot + g.Ongoing.MainPot = 0 - // Show cards - for _, p := range g.Ongoing.Players { - if p != nil && !p.Folded { - fmt.Println(p.Username, p.Cards) - PokerPubSub.Pub(roomTopic, ShowCardsEvent{Cards: p.Cards}) - } + // Sync "ongoing players" with "room players" objects + for idx := range g.Players { + if g.Ongoing.Players[idx] != nil && g.Players[idx] != nil { + g.Players[idx].Cash = g.Ongoing.Players[idx].Cash } + } - END: + g.IsGameDone = true + PokerPubSub.Pub(roomTopic, GameIsDoneEvent{DeckStr: strings.Join(g.Ongoing.Deck, "")}) - // TODO: evaluate hands, and crown winner - var winner *PokerPlayer - for _, p := range g.Ongoing.Players { - if p != nil { - winner = p - break - } - } - winner.Cash += g.Ongoing.MainPot - g.Ongoing.MainPot = 0 + // Wait a minimum of X seconds before allowing a new game + time.Sleep(MinTimeAfterGame * time.Second) + g.IsGameOver = true + fmt.Println("GAME IS OVER") +} - // Sync "ongoing players" with "room players" objects - for idx := range g.Players { - if g.Ongoing.Players[idx] != nil && g.Players[idx] != nil { - g.Players[idx].Cash = g.Ongoing.Players[idx].Cash - } +func (g *PokerGame) Deal(roomID string) { + roomTopic := "room_" + roomID + + if g.Ongoing != nil { + if !g.IsGameOver { + fmt.Println("game already ongoing") + return + } else { + g.IsGameOver = false + PokerPubSub.Pub(roomTopic, ResetCardsEvent{}) + time.Sleep(time.Second) } + } + if g.CountSeated() < 2 { + fmt.Println("need at least 2 players") + return + } - g.IsGameDone = true - PokerPubSub.Pub(roomTopic, GameIsDoneEvent{DeckStr: strings.Join(g.Ongoing.Deck, "")}) + g.Ongoing = NewOngoing(g) - // Wait a minimum of X seconds before allowing a new game - time.Sleep(MinTimeAfterGame * time.Second) - g.IsGameOver = true - fmt.Println("GAME IS OVER") - }() + go dealerThread(g, roomID) } func (g *PokerGame) CountSeated() (count int) {