Added !poker and auth entry point
This commit is contained in:
154
internal/chat/poker.go
Normal file
154
internal/chat/poker.go
Normal file
@@ -0,0 +1,154 @@
|
||||
package chat
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
twitch "github.com/gempir/go-twitch-irc/v4"
|
||||
"streambot_twitch/internal/points"
|
||||
)
|
||||
|
||||
// card
|
||||
type Card struct {
|
||||
Rank, Suit string
|
||||
}
|
||||
|
||||
var (
|
||||
suits = []string{" of Hearts", " of Diamnods", " of Clubs", " of Spades"}
|
||||
ranks = []string{"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"}
|
||||
baseDeck []Card
|
||||
)
|
||||
|
||||
func init() {
|
||||
// build 2 decks (no Jokers) 104 cards
|
||||
for d := 0; d < 2; d++ {
|
||||
for _, s := range suits {
|
||||
for _, r := range ranks {
|
||||
baseDeck = append(baseDeck, Card{Rank: r, Suit: s})
|
||||
}
|
||||
}
|
||||
}
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
}
|
||||
|
||||
// impliment !poker or !table <bet>
|
||||
func HandlePokerCommand(
|
||||
client *twitch.Client,
|
||||
message twitch.PrivateMessage,
|
||||
user twitch.User,
|
||||
channel, msg string,
|
||||
) {
|
||||
parts := strings.Fields(msg)
|
||||
if len(parts) < 2 {
|
||||
client.Say(channel, fmt.Sprintf("@%s Usage: !poker <bet>", user.DisplayName))
|
||||
return
|
||||
}
|
||||
bet, err := strconv.Atoi(parts[1])
|
||||
if err != nil || bet <= 0 {
|
||||
client.Say(channel, fmt.Sprintf("@%s Invalid bet amount", user.DisplayName))
|
||||
return
|
||||
}
|
||||
|
||||
login := strings.ToLower(user.Name)
|
||||
// load or init user points
|
||||
balance := points.GetPoints(login)
|
||||
if bet > ballance {
|
||||
client.Say(channel, fmt.Sprintf("@%s You have %d points, bet lower", user.DisplayName, balance))
|
||||
return
|
||||
}
|
||||
// Deduct the bet
|
||||
balance, err = points.AddPoints(login, -bet)
|
||||
if err != nil {
|
||||
client.Say(channel, fmt.Sprintf("@%s Error updating points: %v", user.DisplayName, err))
|
||||
return
|
||||
}
|
||||
|
||||
// shuffle deck
|
||||
deck := make([]Card, len(baseDeck))
|
||||
copy(deck, baseDeck)
|
||||
rand.Shuffle(len(deck), func(i, j int) {deck[i], deck[j] = deck[j], deck[i]})
|
||||
|
||||
// deal 2 cards each
|
||||
player := []Card{deck[0], deck[1]}
|
||||
dealer := []Card{deck[2], deck[3]}
|
||||
|
||||
// compute hand values
|
||||
pv := handValue(player)
|
||||
dv := handValue(dealer)
|
||||
|
||||
// Determine outcome and payout multiplier
|
||||
var net int
|
||||
var outcome string
|
||||
switch {
|
||||
case pv > 21:
|
||||
outcome = "FBPenalty Bust! You lose"
|
||||
net = 0
|
||||
case pv == 21:
|
||||
outcome = "BLACKJACK! GoatEmotey"
|
||||
net = bet * 2
|
||||
case dv > 21:
|
||||
outcome = "GoldPLZ Dealer bust! You win"
|
||||
net = int(float64(bet) * 1.5)
|
||||
case pv > dv:
|
||||
outcome = "OhMyDog You Win"
|
||||
net int(float64(bet) * 1.3)
|
||||
case pv < dv:
|
||||
outcome = "cmonBruh You lose"
|
||||
net = 0
|
||||
default:
|
||||
outcome = "PunchTrees Push"
|
||||
net = bet
|
||||
}
|
||||
|
||||
// Add winnings
|
||||
balance, err = points.AddPoints(login, net)
|
||||
if err != nil {
|
||||
client.Say(channel, fmt.Sprintf("@%s Error updating Points: %v", user.DisplayName, err))
|
||||
return
|
||||
}
|
||||
|
||||
// format a hand for display
|
||||
fmtHand := func(h []Card) string {
|
||||
var parts []string
|
||||
for _, c := range h {
|
||||
parts = append(parts, c.Rank+c.Suit)
|
||||
}
|
||||
return strings.Join(parts, ",")
|
||||
}
|
||||
|
||||
// post result
|
||||
client.Say(channel, fmt.Sprintf("@%s You: [%s]=%d Dealer: [%s]=%d => %s | Bet: %d Net: %d Ballance: %d", user.DisplayName,
|
||||
fmtHand(player), pv,
|
||||
fmtHand(dealer), dv,
|
||||
outcome,
|
||||
bet, net, balance,
|
||||
))
|
||||
}
|
||||
|
||||
// compute BlackJack style value (A = 11 or 1)
|
||||
func handValue(hand []Card) int {
|
||||
total := 0
|
||||
aces := 0
|
||||
for _, c := range hand {
|
||||
switch c.Rank {
|
||||
case "J", "Q", "K":
|
||||
total += 10
|
||||
case "A":
|
||||
total += 11
|
||||
aces++
|
||||
default:
|
||||
v, _ := strconv.Atoi(c.Rank)
|
||||
total += v
|
||||
}
|
||||
}
|
||||
|
||||
// convert A from 11 to 1 while busting
|
||||
for total > 21 && aces > 0 {
|
||||
total -= 10
|
||||
aces--
|
||||
}
|
||||
return total
|
||||
}
|
Reference in New Issue
Block a user