2024-11-01 00:46:26 +08:00

184 lines
4.8 KiB
Go

package controller
import (
"strconv"
"git.lxtend.com/qqbot/handler/blackjack/model"
"git.lxtend.com/qqbot/handler/blackjack/util"
)
type BackJackSimulator struct {
deck *model.Deck
dealerCards *model.Deck
playerCards *model.Deck
dealerScore int
playerScore int
status util.Status
}
func NewBlackJackSimulator() *BackJackSimulator {
simulator := &BackJackSimulator{
deck: model.NewDeck(),
dealerCards: model.NewDeck(),
playerCards: model.NewDeck(),
}
simulator.Init()
return simulator
}
func initDeck(deck *model.Deck) *model.Deck {
colors := []string{"Spade", "Heart", "Diamond", "Club"}
for _, color := range colors {
for i := 2; i <= 10; i++ {
deck.Add(model.NewCard(color, strconv.Itoa(i), []int{i}, true))
}
for _, name := range []string{"J", "Q", "K"} {
deck.Add(model.NewCard(color, name, []int{10}, true))
}
deck.Add(model.NewCard(color, "A", []int{1, 11}, true))
}
return deck.Shuffle()
}
func initDealerCards(dealerCards *model.Deck, deck *model.Deck) *model.Deck {
if firstCard := deck.Draw(); deck != nil {
dealerCards.Add(firstCard.Flip())
}
if secondCard := deck.Draw(); deck != nil {
dealerCards.Add(secondCard)
}
return dealerCards
}
func initPlayerCards(playerCards *model.Deck, deck *model.Deck) *model.Deck {
if firstCard := deck.Draw(); deck != nil {
playerCards.Add(firstCard)
}
if secondCard := deck.Draw(); deck != nil {
playerCards.Add(secondCard)
}
return playerCards
}
func (simulator *BackJackSimulator) Init() *BackJackSimulator {
simulator.deck = model.NewDeck()
simulator.dealerCards = model.NewDeck()
simulator.playerCards = model.NewDeck()
simulator.deck = initDeck(simulator.deck)
simulator.dealerCards = initDealerCards(simulator.dealerCards, simulator.deck)
simulator.playerCards = initPlayerCards(simulator.playerCards, simulator.deck)
simulator.dealerScore, simulator.playerScore = 0, 0
simulator.status = util.INITIALIZED
return simulator
}
func (simulator *BackJackSimulator) Hit() *BackJackResponse {
if simulator.status == util.FAILED || simulator.status == util.WINNED || simulator.status == util.DRAW {
return NewBlackJackResponse(400, "[🐧] You have failed in this Blackjack game !\n")
}
if card := simulator.deck.Draw(); card != nil {
simulator.playerCards.Add(card)
simulator.playerScore = 0
for _, card := range simulator.playerCards.Cards() {
simulator.playerScore += card.Value[0]
}
if simulator.playerScore > 21 {
simulator.status = util.FAILED
return NewBlackJackResponse(400, "[🐧] Your total score exceeds 21 ! You lose !\n")
}
}
return NewBlackJackResponse(200, "[🐧] You have drawn a card !\n")
}
func (simulator *BackJackSimulator) Stand() *BackJackResponse {
if simulator.status == util.FAILED || simulator.status == util.WINNED || simulator.status == util.DRAW {
return NewBlackJackResponse(400, "[🐧] You have failed in this Blackjack game !\n")
}
simulator.dealerScore, simulator.playerScore = 0, 0
maxDealerScore, maxPlayerScore, minDealerScore, minPlayerScore := 0, 0, 0, 0
for _, card := range simulator.dealerCards.Cards() {
if !card.Visible {
card.Flip()
}
if card.Name == "A" {
maxDealerScore += card.Value[1]
minDealerScore += card.Value[0]
} else {
maxDealerScore += card.Value[0]
minDealerScore += card.Value[0]
}
}
for _, card := range simulator.playerCards.Cards() {
if card.Name == "A" {
maxPlayerScore += card.Value[1]
minPlayerScore += card.Value[0]
} else {
maxPlayerScore += card.Value[0]
minPlayerScore += card.Value[0]
}
}
if maxDealerScore < 17 {
for maxDealerScore < 17 {
if card := simulator.deck.Draw(); card != nil {
simulator.dealerCards.Add(card)
if card.Name == "A" {
maxDealerScore += card.Value[1]
minDealerScore += card.Value[0]
} else {
maxDealerScore += card.Value[0]
minDealerScore += card.Value[0]
}
}
if minDealerScore > 21 {
simulator.status = util.WINNED
return NewBlackJackResponse(400, "[🐧] The dealer burst and you have won the game !\n")
}
}
}
if maxDealerScore > maxPlayerScore {
simulator.status = util.FAILED
return NewBlackJackResponse(400, "[🐧] The dealer wins the game !\n")
} else if maxDealerScore < maxPlayerScore {
simulator.status = util.WINNED
return NewBlackJackResponse(400, "[🐧] You have won the game !\n")
} else if maxDealerScore == maxPlayerScore {
simulator.status = util.DRAW
return NewBlackJackResponse(200, "[🐧] It is a draw !\n")
}
return NewBlackJackResponse(400, "[🐧] Unrecognized Error !\n")
}
func (simulator *BackJackSimulator) GetDealerCards() *model.Deck {
return simulator.dealerCards
}
func (simulator *BackJackSimulator) GetPlayerCards() *model.Deck {
return simulator.playerCards
}
func (simulator *BackJackSimulator) GetStatus() util.Status {
return simulator.status
}