aboutsummaryrefslogtreecommitdiff
path: root/internal/casino/cards.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/casino/cards.go')
-rw-r--r--internal/casino/cards.go80
1 files changed, 80 insertions, 0 deletions
diff --git a/internal/casino/cards.go b/internal/casino/cards.go
new file mode 100644
index 0000000..0c32e06
--- /dev/null
+++ b/internal/casino/cards.go
@@ -0,0 +1,80 @@
+package casino
+
+import (
+ "fmt"
+ "math/rand"
+)
+
+// 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:
+ var value int
+ fmt.Sscanf(c.rank, "%d", &value)
+ 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:
+ var value int
+ fmt.Sscanf(c.rank, "%d", &value)
+ 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
+}