CasinoGames/Baccarat/Models/GameSettings.swift

247 lines
7.0 KiB
Swift

//
// GameSettings.swift
// Baccarat
//
// User-configurable game settings.
//
import Foundation
import SwiftUI
/// The number of decks available for the shoe.
enum DeckCount: Int, CaseIterable, Identifiable {
case one = 1
case six = 6
case eight = 8
var id: Int { rawValue }
var displayName: String {
switch self {
case .one: return "1 Deck"
case .six: return "6 Decks"
case .eight: return "8 Decks (Standard)"
}
}
var description: String {
switch self {
case .one: return "Rare, for private games"
case .six: return "Common in mini baccarat"
case .eight: return "Casino standard"
}
}
}
/// Preset table limits for betting.
enum TableLimits: String, CaseIterable, Identifiable {
case casual = "casual"
case low = "low"
case medium = "medium"
case high = "high"
case vip = "vip"
var id: String { rawValue }
var displayName: String {
switch self {
case .casual: return "Casual"
case .low: return "Low Stakes"
case .medium: return "Medium Stakes"
case .high: return "High Stakes"
case .vip: return "VIP"
}
}
var minBet: Int {
switch self {
case .casual: return 5
case .low: return 10
case .medium: return 25
case .high: return 100
case .vip: return 500
}
}
var maxBet: Int {
switch self {
case .casual: return 500
case .low: return 1_000
case .medium: return 5_000
case .high: return 10_000
case .vip: return 50_000
}
}
var description: String {
"$\(minBet) - $\(maxBet.formatted())"
}
var detailedDescription: String {
switch self {
case .casual: return "Perfect for learning"
case .low: return "Standard mini baccarat"
case .medium: return "Regular casino table"
case .high: return "High roller table"
case .vip: return "Exclusive VIP room"
}
}
}
/// Observable settings class for game configuration.
@Observable
@MainActor
final class GameSettings {
// MARK: - Deck Settings
/// Number of decks in the shoe.
var deckCount: DeckCount = .eight
// MARK: - Betting Limits
/// The table limits preset.
var tableLimits: TableLimits = .low
/// Minimum bet amount.
var minBet: Int {
tableLimits.minBet
}
/// Maximum bet amount per betting spot.
var maxBet: Int {
tableLimits.maxBet
}
// MARK: - Starting Balance
/// The starting balance for new games.
var startingBalance: Int = 10_000
// MARK: - Animation Settings
/// Whether to show dealing animations.
var showAnimations: Bool = true
/// Speed of card dealing (1.0 = normal, 0.5 = fast, 2.0 = slow)
var dealingSpeed: Double = 1.0
// MARK: - Display Settings
/// Whether to show the cards remaining indicator.
var showCardsRemaining: Bool = true
/// Whether to show the history road map.
var showHistory: Bool = true
// MARK: - Sound Settings
/// Whether sound effects are enabled.
var soundEnabled: Bool = true
/// Whether haptic feedback is enabled.
var hapticsEnabled: Bool = true
/// Volume level for sound effects (0.0 to 1.0).
var soundVolume: Float = 1.0
// MARK: - Persistence Keys
private enum Keys {
static let deckCount = "settings.deckCount"
static let tableLimits = "settings.tableLimits"
static let startingBalance = "settings.startingBalance"
static let showAnimations = "settings.showAnimations"
static let dealingSpeed = "settings.dealingSpeed"
static let showCardsRemaining = "settings.showCardsRemaining"
static let showHistory = "settings.showHistory"
static let soundEnabled = "settings.soundEnabled"
static let hapticsEnabled = "settings.hapticsEnabled"
static let soundVolume = "settings.soundVolume"
}
// MARK: - Initialization
init() {
load()
}
// MARK: - Persistence
/// Loads settings from UserDefaults.
func load() {
let defaults = UserDefaults.standard
if let rawDeckCount = defaults.object(forKey: Keys.deckCount) as? Int,
let deckCount = DeckCount(rawValue: rawDeckCount) {
self.deckCount = deckCount
}
if let rawTableLimits = defaults.string(forKey: Keys.tableLimits),
let tableLimits = TableLimits(rawValue: rawTableLimits) {
self.tableLimits = tableLimits
}
if let balance = defaults.object(forKey: Keys.startingBalance) as? Int {
self.startingBalance = balance
}
if defaults.object(forKey: Keys.showAnimations) != nil {
self.showAnimations = defaults.bool(forKey: Keys.showAnimations)
}
if let speed = defaults.object(forKey: Keys.dealingSpeed) as? Double {
self.dealingSpeed = speed
}
if defaults.object(forKey: Keys.showCardsRemaining) != nil {
self.showCardsRemaining = defaults.bool(forKey: Keys.showCardsRemaining)
}
if defaults.object(forKey: Keys.showHistory) != nil {
self.showHistory = defaults.bool(forKey: Keys.showHistory)
}
if defaults.object(forKey: Keys.soundEnabled) != nil {
self.soundEnabled = defaults.bool(forKey: Keys.soundEnabled)
}
if defaults.object(forKey: Keys.hapticsEnabled) != nil {
self.hapticsEnabled = defaults.bool(forKey: Keys.hapticsEnabled)
}
if let volume = defaults.object(forKey: Keys.soundVolume) as? Float {
self.soundVolume = volume
}
}
/// Saves settings to UserDefaults.
func save() {
let defaults = UserDefaults.standard
defaults.set(deckCount.rawValue, forKey: Keys.deckCount)
defaults.set(tableLimits.rawValue, forKey: Keys.tableLimits)
defaults.set(startingBalance, forKey: Keys.startingBalance)
defaults.set(showAnimations, forKey: Keys.showAnimations)
defaults.set(dealingSpeed, forKey: Keys.dealingSpeed)
defaults.set(showCardsRemaining, forKey: Keys.showCardsRemaining)
defaults.set(showHistory, forKey: Keys.showHistory)
defaults.set(soundEnabled, forKey: Keys.soundEnabled)
defaults.set(hapticsEnabled, forKey: Keys.hapticsEnabled)
defaults.set(soundVolume, forKey: Keys.soundVolume)
}
/// Resets all settings to defaults.
func resetToDefaults() {
deckCount = .eight
tableLimits = .low
startingBalance = 10_000
showAnimations = true
dealingSpeed = 1.0
showCardsRemaining = true
showHistory = true
soundEnabled = true
hapticsEnabled = true
soundVolume = 1.0
save()
}
}