diff --git a/Blackjack/Engine/GameState.swift b/Blackjack/Engine/GameState.swift index 470d56f..c6341cb 100644 --- a/Blackjack/Engine/GameState.swift +++ b/Blackjack/Engine/GameState.swift @@ -153,6 +153,67 @@ final class GameState { roundHistory.count } + /// Whether it's currently the player's turn. + var isPlayerTurn: Bool { + if case .playerTurn = currentPhase { return true } + return false + } + + /// Whether the dealer's hole card should be revealed. + var shouldShowDealerHoleCard: Bool { + switch currentPhase { + case .dealerTurn, .roundComplete: + return true + default: + return false + } + } + + // MARK: - Hints + + /// Current gameplay hint based on basic strategy. + var currentHint: String? { + guard settings.showHints else { return nil } + guard isPlayerTurn else { return nil } + guard let hand = activeHand, + let upCard = dealerUpCard else { return nil } + + // Use count-adjusted hints when card counting is enabled + if settings.showCardCount { + return engine.getCountAdjustedHint(playerHand: hand, dealerUpCard: upCard) + } + return engine.getHint(playerHand: hand, dealerUpCard: upCard) + } + + /// Betting recommendation based on the true count. + var bettingHint: String? { + guard settings.showCardCount else { return nil } + guard currentPhase == .betting else { return nil } + + let tc = Int(engine.trueCount.rounded()) + + switch tc { + case ...(-2): + return String(localized: "Bet minimum or sit out") + case -1: + return String(localized: "Bet minimum") + case 0: + return String(localized: "Bet minimum (neutral)") + case 1: + return String(localized: "Bet 2x minimum") + case 2: + return String(localized: "Bet 4x minimum") + case 3: + return String(localized: "Bet 6x minimum") + case 4: + return String(localized: "Bet 8x minimum") + case 5...: + return String(localized: "Bet maximum!") + default: + return nil + } + } + // MARK: - Initialization init(settings: GameSettings) { diff --git a/Blackjack/Views/Table/BlackjackTableView.swift b/Blackjack/Views/Table/BlackjackTableView.swift index f4276e4..3c51410 100644 --- a/Blackjack/Views/Table/BlackjackTableView.swift +++ b/Blackjack/Views/Table/BlackjackTableView.swift @@ -37,7 +37,7 @@ struct BlackjackTableView: View { // Dealer area DealerHandView( hand: state.dealerHand, - showHoleCard: shouldShowDealerHoleCard, + showHoleCard: state.shouldShowDealerHoleCard, showCardCount: showCardCount, cardWidth: cardWidth, cardSpacing: cardSpacing @@ -53,7 +53,7 @@ struct BlackjackTableView: View { PlayerHandsView( hands: state.playerHands, activeHandIndex: state.activeHandIndex, - isPlayerTurn: isPlayerTurn, + isPlayerTurn: state.isPlayerTurn, showCardCount: showCardCount, cardWidth: cardWidth, cardSpacing: cardSpacing @@ -77,15 +77,15 @@ struct BlackjackTableView: View { .debugBorder(showDebugBorders, color: .blue, label: "BetZone") // Betting hint based on count (only when card counting enabled) - if showCardCount, let bettingHint = bettingHint { - BettingHintView(hint: bettingHint, trueCount: state.engine.trueCount) + if let hint = state.bettingHint { + BettingHintView(hint: hint, trueCount: state.engine.trueCount) .transition(.opacity) .debugBorder(showDebugBorders, color: .purple, label: "BetHint") } } else { // Fixed-height hint area to prevent layout shifts during player turn ZStack { - if state.settings.showHints && isPlayerTurn, let hint = currentHint { + if let hint = state.currentHint { HintView(hint: hint) .transition(.opacity) } @@ -99,62 +99,6 @@ struct BlackjackTableView: View { .debugBorder(showDebugBorders, color: .white, label: "TableView") .animation(.spring(duration: Design.Animation.springDuration), value: state.currentPhase) } - - // MARK: - Computed Properties - - private var shouldShowDealerHoleCard: Bool { - switch state.currentPhase { - case .dealerTurn, .roundComplete: - return true - default: - return false - } - } - - private var isPlayerTurn: Bool { - if case .playerTurn = state.currentPhase { - return true - } - return false - } - - private var currentHint: String? { - guard let hand = state.activeHand, - let upCard = state.dealerUpCard else { return nil } - - // Use count-adjusted hints when card counting is enabled - if showCardCount { - return state.engine.getCountAdjustedHint(playerHand: hand, dealerUpCard: upCard) - } - return state.engine.getHint(playerHand: hand, dealerUpCard: upCard) - } - - /// Betting recommendation based on the true count. - private var bettingHint: String? { - let tc = Int(state.engine.trueCount.rounded()) - - // Betting spread recommendations based on true count - switch tc { - case ...(-2): - return String(localized: "Bet minimum or sit out") - case -1: - return String(localized: "Bet minimum") - case 0: - return String(localized: "Bet minimum (neutral)") - case 1: - return String(localized: "Bet 2x minimum") - case 2: - return String(localized: "Bet 4x minimum") - case 3: - return String(localized: "Bet 6x minimum") - case 4: - return String(localized: "Bet 8x minimum") - case 5...: - return String(localized: "Bet maximum!") - default: - return nil - } - } } // MARK: - Previews