72 lines
1.9 KiB
Swift
72 lines
1.9 KiB
Swift
//
|
|
// Shoe.swift
|
|
// Baccarat
|
|
//
|
|
// A shoe containing multiple decks of cards, used in baccarat.
|
|
//
|
|
|
|
import Foundation
|
|
import CasinoKit
|
|
|
|
/// Represents a shoe containing multiple decks of cards.
|
|
/// Standard baccarat uses 6-8 decks shuffled together.
|
|
struct Shoe {
|
|
private var cards: [Card] = []
|
|
|
|
/// The number of decks in this shoe.
|
|
let deckCount: Int
|
|
|
|
/// Number of cards remaining in the shoe.
|
|
var cardsRemaining: Int {
|
|
cards.count
|
|
}
|
|
|
|
/// Whether the shoe needs to be reshuffled (less than 20% remaining).
|
|
var needsReshuffle: Bool {
|
|
let totalCards = deckCount * 52
|
|
return cards.count < totalCards / 5
|
|
}
|
|
|
|
/// Creates a new shoe with the specified number of decks.
|
|
/// - Parameter deckCount: Number of decks to include (default: 8).
|
|
init(deckCount: Int = 8) {
|
|
self.deckCount = deckCount
|
|
shuffle()
|
|
}
|
|
|
|
/// Shuffles all decks together to create a fresh shoe.
|
|
mutating func shuffle() {
|
|
cards = []
|
|
|
|
for _ in 0..<deckCount {
|
|
for suit in Suit.allCases {
|
|
for rank in Rank.allCases {
|
|
cards.append(Card(suit: suit, rank: rank))
|
|
}
|
|
}
|
|
}
|
|
|
|
// Fisher-Yates shuffle for true randomness
|
|
for i in stride(from: cards.count - 1, through: 1, by: -1) {
|
|
let j = Int.random(in: 0...i)
|
|
cards.swapAt(i, j)
|
|
}
|
|
}
|
|
|
|
/// Deals a single card from the top of the shoe.
|
|
/// - Returns: The dealt card, or nil if shoe is empty.
|
|
mutating func deal() -> Card? {
|
|
guard !cards.isEmpty else { return nil }
|
|
return cards.removeFirst()
|
|
}
|
|
|
|
/// Burns (discards) a specified number of cards from the shoe.
|
|
/// - Parameter count: Number of cards to burn.
|
|
mutating func burn(_ count: Int) {
|
|
for _ in 0..<min(count, cards.count) {
|
|
_ = cards.removeFirst()
|
|
}
|
|
}
|
|
}
|
|
|