Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>

This commit is contained in:
Matt Bruce 2025-12-22 12:16:01 -06:00
parent 740ef6a73b
commit 8ee7b4c30c
2 changed files with 66 additions and 61 deletions

View File

@ -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) {

View File

@ -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