package casino import ( "math/rand" "strconv" ) // card is a single playing card shared by every card-based table game. type card struct { rank string suit string } func (c card) String() string { return c.rank + " of " + c.suit } // blackjackValue scores aces as 11 and faces as 10. func (c card) blackjackValue() int { switch c.rank { case "A": return 11 case "K", "Q", "J": return 10 default: value, _ := strconv.Atoi(c.rank) return value } } // baccaratValue scores aces as 1 and faces/tens as 0. func (c card) baccaratValue() int { switch c.rank { case "K", "Q", "J", "10": return 0 case "A": return 1 default: value, _ := strconv.Atoi(c.rank) return value } } // shoe is a shuffled multi-deck card shoe shared by card table games. It // reshuffles once the remaining cards fall to the shuffleAt fraction. type shoe struct { cards []card rng *rand.Rand decks int shuffleAt float64 } func newShoe(decks int, shuffleAt float64, rng *rand.Rand) *shoe { s := &shoe{rng: rng, decks: decks, shuffleAt: shuffleAt} s.shuffle() return s } func (s *shoe) shuffle() { ranks := []string{"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"} suits := []string{"clubs", "diamonds", "hearts", "spades"} s.cards = make([]card, 0, s.decks*52) for deck := 0; deck < s.decks; deck++ { for _, suit := range suits { for _, rank := range ranks { s.cards = append(s.cards, card{rank: rank, suit: suit}) } } } s.rng.Shuffle(len(s.cards), func(i, j int) { s.cards[i], s.cards[j] = s.cards[j], s.cards[i] }) } func (s *shoe) draw() card { if s.shuffleAt > 0 && len(s.cards) <= int(float64(s.decks*52)*s.shuffleAt) { s.shuffle() } card := s.cards[len(s.cards)-1] s.cards = s.cards[:len(s.cards)-1] return card }