Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
parent
740ef6a73b
commit
8ee7b4c30c
@ -153,6 +153,67 @@ final class GameState {
|
|||||||
roundHistory.count
|
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
|
// MARK: - Initialization
|
||||||
|
|
||||||
init(settings: GameSettings) {
|
init(settings: GameSettings) {
|
||||||
|
|||||||
@ -37,7 +37,7 @@ struct BlackjackTableView: View {
|
|||||||
// Dealer area
|
// Dealer area
|
||||||
DealerHandView(
|
DealerHandView(
|
||||||
hand: state.dealerHand,
|
hand: state.dealerHand,
|
||||||
showHoleCard: shouldShowDealerHoleCard,
|
showHoleCard: state.shouldShowDealerHoleCard,
|
||||||
showCardCount: showCardCount,
|
showCardCount: showCardCount,
|
||||||
cardWidth: cardWidth,
|
cardWidth: cardWidth,
|
||||||
cardSpacing: cardSpacing
|
cardSpacing: cardSpacing
|
||||||
@ -53,7 +53,7 @@ struct BlackjackTableView: View {
|
|||||||
PlayerHandsView(
|
PlayerHandsView(
|
||||||
hands: state.playerHands,
|
hands: state.playerHands,
|
||||||
activeHandIndex: state.activeHandIndex,
|
activeHandIndex: state.activeHandIndex,
|
||||||
isPlayerTurn: isPlayerTurn,
|
isPlayerTurn: state.isPlayerTurn,
|
||||||
showCardCount: showCardCount,
|
showCardCount: showCardCount,
|
||||||
cardWidth: cardWidth,
|
cardWidth: cardWidth,
|
||||||
cardSpacing: cardSpacing
|
cardSpacing: cardSpacing
|
||||||
@ -77,15 +77,15 @@ struct BlackjackTableView: View {
|
|||||||
.debugBorder(showDebugBorders, color: .blue, label: "BetZone")
|
.debugBorder(showDebugBorders, color: .blue, label: "BetZone")
|
||||||
|
|
||||||
// Betting hint based on count (only when card counting enabled)
|
// Betting hint based on count (only when card counting enabled)
|
||||||
if showCardCount, let bettingHint = bettingHint {
|
if let hint = state.bettingHint {
|
||||||
BettingHintView(hint: bettingHint, trueCount: state.engine.trueCount)
|
BettingHintView(hint: hint, trueCount: state.engine.trueCount)
|
||||||
.transition(.opacity)
|
.transition(.opacity)
|
||||||
.debugBorder(showDebugBorders, color: .purple, label: "BetHint")
|
.debugBorder(showDebugBorders, color: .purple, label: "BetHint")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Fixed-height hint area to prevent layout shifts during player turn
|
// Fixed-height hint area to prevent layout shifts during player turn
|
||||||
ZStack {
|
ZStack {
|
||||||
if state.settings.showHints && isPlayerTurn, let hint = currentHint {
|
if let hint = state.currentHint {
|
||||||
HintView(hint: hint)
|
HintView(hint: hint)
|
||||||
.transition(.opacity)
|
.transition(.opacity)
|
||||||
}
|
}
|
||||||
@ -99,62 +99,6 @@ struct BlackjackTableView: View {
|
|||||||
.debugBorder(showDebugBorders, color: .white, label: "TableView")
|
.debugBorder(showDebugBorders, color: .white, label: "TableView")
|
||||||
.animation(.spring(duration: Design.Animation.springDuration), value: state.currentPhase)
|
.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
|
// MARK: - Previews
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user