// // BetType.swift // Baccarat // // Bet types and payout rates for baccarat. // import Foundation import SwiftUI /// The types of bets available in baccarat. enum BetType: String, CaseIterable, Identifiable { // MARK: - Main Bets case player = "Player" case banker = "Banker" case tie = "Tie" // MARK: - Side Bets case playerPair = "Player Pair" case bankerPair = "Banker Pair" case dragonBonusPlayer = "Dragon Bonus Player" case dragonBonusBanker = "Dragon Bonus Banker" var id: String { rawValue } /// Whether this is a main bet (Player/Banker) that is required to play. var isMainBet: Bool { self == .player || self == .banker } /// Whether this is a side bet. var isSideBet: Bool { !isMainBet && self != .tie } /// The base payout multiplier for winning this bet type. /// Note: Dragon Bonus has variable payouts based on margin - this is the natural win payout. var payoutMultiplier: Double { switch self { case .player: return 1.0 case .banker: return 0.95 // 5% commission case .tie: return 8.0 case .playerPair, .bankerPair: return 11.0 // 11:1 case .dragonBonusPlayer, .dragonBonusBanker: return 1.0 // Base for natural } } /// Display name with payout info. var displayWithPayout: String { switch self { case .player: return "Player (1:1)" case .banker: return "Banker (0.95:1)" case .tie: return "Tie (8:1)" case .playerPair: return "P Pair (11:1)" case .bankerPair: return "B Pair (11:1)" case .dragonBonusPlayer: return "Dragon P" case .dragonBonusBanker: return "Dragon B" } } /// Short display name for betting zones. var shortName: String { switch self { case .player: return "PLAYER" case .banker: return "BANKER" case .tie: return "TIE" case .playerPair: return "P PAIR" case .bankerPair: return "B PAIR" case .dragonBonusPlayer: return "P BONUS" case .dragonBonusBanker: return "B BONUS" } } /// The payout description shown in betting zones. var payoutDescription: String { switch self { case .player: return "PAYS 1 TO 1" case .banker: return "PAYS 0.95 TO 1" case .tie: return "PAYS 8 TO 1" case .playerPair, .bankerPair: return "PAYS 11 TO 1" case .dragonBonusPlayer, .dragonBonusBanker: return "UP TO 30 TO 1" } } /// The color associated with this bet type. var color: Color { switch self { case .player: return .blue case .banker: return .red case .tie: return .green case .playerPair: return .blue.opacity(0.7) case .bankerPair: return .red.opacity(0.7) case .dragonBonusPlayer: return .purple case .dragonBonusBanker: return .orange } } /// All main betting options (required to play). static var mainBets: [BetType] { [.player, .banker] } /// All side bets. static var sideBets: [BetType] { [.tie, .playerPair, .bankerPair, .dragonBonusPlayer, .dragonBonusBanker] } /// Pair bets. static var pairBets: [BetType] { [.playerPair, .bankerPair] } /// Dragon bonus bets. static var dragonBets: [BetType] { [.dragonBonusPlayer, .dragonBonusBanker] } } /// Represents a bet placed by the user. struct Bet: Identifiable, Equatable { let id = UUID() let type: BetType let amount: Int static func == (lhs: Bet, rhs: Bet) -> Bool { lhs.id == rhs.id } } /// Dragon Bonus payout table based on margin of victory. enum DragonBonusPayout { /// Returns the payout multiplier for Dragon Bonus based on the margin of victory. /// Returns nil if the bet loses. static func multiplier(for margin: Int, isNatural: Bool) -> Int? { // Natural win (8 or 9) if isNatural && margin > 0 { return 1 } // Non-natural wins by margin switch margin { case 9: return 30 case 8: return 10 case 7: return 6 case 6: return 4 case 5: return 2 case 4: return 1 default: return nil // Loses on margin < 4, tie, or loss } } /// All possible payouts for display in rules. static var payoutTable: [(margin: String, payout: String)] { [ ("Natural Win (8 or 9)", "1 to 1"), ("Win by 9", "30 to 1"), ("Win by 8", "10 to 1"), ("Win by 7", "6 to 1"), ("Win by 6", "4 to 1"), ("Win by 5", "2 to 1"), ("Win by 4", "1 to 1"), ("Win by 0-3 or Lose", "Lose") ] } }