184 lines
4.8 KiB
Go
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
|
|
}
|