155 lines
4.0 KiB
Swift
155 lines
4.0 KiB
Swift
//
|
|
// BaccaratGameData.swift
|
|
// Baccarat
|
|
//
|
|
// Baccarat-specific game data that persists to iCloud.
|
|
//
|
|
|
|
import Foundation
|
|
import CasinoKit
|
|
|
|
/// Persisted data for Baccarat game.
|
|
public struct BaccaratGameData: PersistableGameData {
|
|
|
|
// MARK: - PersistableGameData
|
|
|
|
public static let gameIdentifier = "baccarat"
|
|
|
|
public var roundsPlayed: Int {
|
|
roundHistory.count
|
|
}
|
|
|
|
public static var empty: BaccaratGameData {
|
|
BaccaratGameData(
|
|
balance: 10_000,
|
|
roundHistory: [],
|
|
totalWinnings: 0,
|
|
biggestWin: 0,
|
|
biggestLoss: 0,
|
|
lastModified: Date()
|
|
)
|
|
}
|
|
|
|
// MARK: - Game Data
|
|
|
|
/// Current chip balance.
|
|
public var balance: Int
|
|
|
|
/// History of all rounds played.
|
|
public var roundHistory: [SavedRoundResult]
|
|
|
|
// MARK: - Lifetime Statistics
|
|
|
|
/// Total net winnings (can be negative).
|
|
public var totalWinnings: Int
|
|
|
|
/// Biggest single-round win.
|
|
public var biggestWin: Int
|
|
|
|
/// Biggest single-round loss (stored as positive number).
|
|
public var biggestLoss: Int
|
|
|
|
/// Last time data was modified (required by PersistableGameData).
|
|
public var lastModified: Date
|
|
|
|
// MARK: - Computed Stats
|
|
|
|
/// Number of Player wins.
|
|
public var playerWins: Int {
|
|
roundHistory.filter { $0.result == "player" }.count
|
|
}
|
|
|
|
/// Number of Banker wins.
|
|
public var bankerWins: Int {
|
|
roundHistory.filter { $0.result == "banker" }.count
|
|
}
|
|
|
|
/// Number of Tie games.
|
|
public var tieGames: Int {
|
|
roundHistory.filter { $0.result == "tie" }.count
|
|
}
|
|
|
|
/// Win rate percentage.
|
|
public var winRate: Double {
|
|
guard roundsPlayed > 0 else { return 0 }
|
|
let wins = roundHistory.filter { $0.netWinnings > 0 }.count
|
|
return Double(wins) / Double(roundsPlayed) * 100
|
|
}
|
|
}
|
|
|
|
/// Codable round result for persistence.
|
|
public struct SavedRoundResult: Codable, Identifiable, Sendable {
|
|
public let id: UUID
|
|
public let result: String // "player", "banker", "tie"
|
|
public let playerValue: Int
|
|
public let bankerValue: Int
|
|
public let playerPair: Bool
|
|
public let bankerPair: Bool
|
|
public let isNatural: Bool
|
|
public let timestamp: Date
|
|
public let netWinnings: Int
|
|
|
|
public init(
|
|
id: UUID = UUID(),
|
|
result: String,
|
|
playerValue: Int,
|
|
bankerValue: Int,
|
|
playerPair: Bool,
|
|
bankerPair: Bool,
|
|
isNatural: Bool,
|
|
timestamp: Date = Date(),
|
|
netWinnings: Int
|
|
) {
|
|
self.id = id
|
|
self.result = result
|
|
self.playerValue = playerValue
|
|
self.bankerValue = bankerValue
|
|
self.playerPair = playerPair
|
|
self.bankerPair = bankerPair
|
|
self.isNatural = isNatural
|
|
self.timestamp = timestamp
|
|
self.netWinnings = netWinnings
|
|
}
|
|
}
|
|
|
|
// MARK: - Conversion from RoundResult
|
|
|
|
extension SavedRoundResult {
|
|
/// Creates a SavedRoundResult from a RoundResult and net winnings.
|
|
init(from roundResult: RoundResult, netWinnings: Int) {
|
|
self.id = roundResult.id
|
|
self.result = roundResult.result.persistenceKey
|
|
self.playerValue = roundResult.playerValue
|
|
self.bankerValue = roundResult.bankerValue
|
|
self.playerPair = roundResult.playerPair
|
|
self.bankerPair = roundResult.bankerPair
|
|
self.isNatural = roundResult.isNatural
|
|
self.timestamp = roundResult.timestamp
|
|
self.netWinnings = netWinnings
|
|
}
|
|
}
|
|
|
|
// MARK: - GameResult Extension
|
|
|
|
extension GameResult {
|
|
/// String key for persistence.
|
|
var persistenceKey: String {
|
|
switch self {
|
|
case .playerWins: return "player"
|
|
case .bankerWins: return "banker"
|
|
case .tie: return "tie"
|
|
}
|
|
}
|
|
|
|
/// Creates GameResult from persistence key.
|
|
init?(persistenceKey: String) {
|
|
switch persistenceKey {
|
|
case "player": self = .playerWins
|
|
case "banker": self = .bankerWins
|
|
case "tie": self = .tie
|
|
default: return nil
|
|
}
|
|
}
|
|
}
|
|
|