Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
parent
c9b2a9e692
commit
ed1dabfe18
@ -591,6 +591,22 @@ final class GameState: CasinoGameState {
|
||||
return currentAmount + amount <= maxBet
|
||||
}
|
||||
|
||||
/// The minimum bet level across all bet types that can accept more chips.
|
||||
/// Used by chip selector to determine if chips should be enabled.
|
||||
/// Returns the smallest bet so chips stay enabled if ANY bet type can accept more.
|
||||
var minBetForChipSelector: Int {
|
||||
// All bet types are always available in Baccarat
|
||||
let allBetTypes: [BetType] = [
|
||||
.player, .banker, .tie,
|
||||
.playerPair, .bankerPair,
|
||||
.dragonBonusPlayer, .dragonBonusBanker
|
||||
]
|
||||
|
||||
// Return the minimum bet amount across all bet types
|
||||
// so chips stay enabled if any bet type can accept more
|
||||
return allBetTypes.map { betAmount(for: $0) }.min() ?? 0
|
||||
}
|
||||
|
||||
// MARK: - Betting Actions
|
||||
|
||||
/// Places a bet of the specified amount on the given bet type.
|
||||
|
||||
@ -353,7 +353,7 @@ struct GameTableView: View {
|
||||
ChipSelectorView(
|
||||
selectedChip: $selectedChip,
|
||||
balance: state.balance,
|
||||
currentBet: state.totalBetAmount,
|
||||
currentBet: state.minBetForChipSelector,
|
||||
maxBet: state.maxBet
|
||||
)
|
||||
.transition(.opacity.combined(with: .move(edge: .bottom)))
|
||||
@ -464,7 +464,7 @@ struct GameTableView: View {
|
||||
ChipSelectorView(
|
||||
selectedChip: $selectedChip,
|
||||
balance: state.balance,
|
||||
currentBet: state.totalBetAmount,
|
||||
currentBet: state.minBetForChipSelector,
|
||||
maxBet: state.maxBet
|
||||
)
|
||||
.transition(.opacity.combined(with: .move(edge: .bottom)))
|
||||
|
||||
@ -177,7 +177,6 @@ final class GameState: CasinoGameState {
|
||||
/// Whether a specific side bet can accept more chips of the given amount.
|
||||
/// Matches Baccarat's canAddToBet pattern.
|
||||
func canAddToSideBet(type: SideBetType, amount: Int) -> Bool {
|
||||
guard settings.sideBetsEnabled else { return false }
|
||||
let currentAmount: Int
|
||||
switch type {
|
||||
case .perfectPairs:
|
||||
@ -204,16 +203,12 @@ final class GameState: CasinoGameState {
|
||||
return false
|
||||
}
|
||||
|
||||
/// The minimum bet level across all active bet types.
|
||||
/// The minimum bet level across all bet types.
|
||||
/// Used by chip selector to determine if chips should be enabled.
|
||||
/// Returns the smallest bet so chips stay enabled if ANY bet type can accept more.
|
||||
var minBetForChipSelector: Int {
|
||||
if settings.sideBetsEnabled {
|
||||
// Return the minimum of all bet types so chips stay enabled if any can be increased
|
||||
return min(currentBet, perfectPairsBet, twentyOnePlusThreeBet)
|
||||
} else {
|
||||
return currentBet
|
||||
}
|
||||
min(currentBet, perfectPairsBet, twentyOnePlusThreeBet)
|
||||
}
|
||||
|
||||
/// Whether the current hand can hit.
|
||||
@ -983,8 +978,6 @@ final class GameState: CasinoGameState {
|
||||
|
||||
/// Evaluates side bets based on the initial deal.
|
||||
private func evaluateSideBets() {
|
||||
guard settings.sideBetsEnabled else { return }
|
||||
|
||||
let playerCards = playerHands[0].cards
|
||||
guard playerCards.count >= 2 else { return }
|
||||
|
||||
|
||||
@ -136,11 +136,6 @@ final class GameSettings: GameSettingsProtocol {
|
||||
/// Speed of card dealing (uses CasinoDesign.DealingSpeed constants)
|
||||
var dealingSpeed: Double = CasinoDesign.DealingSpeed.normal { didSet { save() } }
|
||||
|
||||
// MARK: - Side Bets
|
||||
|
||||
/// Whether side bets (Perfect Pairs, 21+3) are enabled.
|
||||
var sideBetsEnabled: Bool = false { didSet { save() } }
|
||||
|
||||
// MARK: - Display Settings
|
||||
|
||||
/// Whether to show the cards remaining indicator.
|
||||
@ -242,7 +237,6 @@ final class GameSettings: GameSettingsProtocol {
|
||||
self.blackjackPayout = data.blackjackPayout
|
||||
self.insuranceAllowed = data.insuranceAllowed
|
||||
self.neverAskInsurance = data.neverAskInsurance
|
||||
self.sideBetsEnabled = data.sideBetsEnabled
|
||||
self.showAnimations = data.showAnimations
|
||||
self.dealingSpeed = data.dealingSpeed
|
||||
self.showCardsRemaining = data.showCardsRemaining
|
||||
@ -269,7 +263,6 @@ final class GameSettings: GameSettingsProtocol {
|
||||
blackjackPayout: blackjackPayout,
|
||||
insuranceAllowed: insuranceAllowed,
|
||||
neverAskInsurance: neverAskInsurance,
|
||||
sideBetsEnabled: sideBetsEnabled,
|
||||
showAnimations: showAnimations,
|
||||
dealingSpeed: dealingSpeed,
|
||||
showCardsRemaining: showCardsRemaining,
|
||||
@ -297,7 +290,6 @@ final class GameSettings: GameSettingsProtocol {
|
||||
blackjackPayout = 1.5
|
||||
insuranceAllowed = true
|
||||
neverAskInsurance = false
|
||||
sideBetsEnabled = false
|
||||
showAnimations = true
|
||||
dealingSpeed = CasinoDesign.DealingSpeed.normal
|
||||
showCardsRemaining = true
|
||||
|
||||
@ -3250,6 +3250,7 @@
|
||||
}
|
||||
},
|
||||
"Enable Side Bets" : {
|
||||
"extractionState" : "stale",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
@ -5348,6 +5349,7 @@
|
||||
}
|
||||
},
|
||||
"Perfect Pairs (25:1) and 21+3 (100:1)" : {
|
||||
"extractionState" : "stale",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
@ -6329,6 +6331,7 @@
|
||||
}
|
||||
},
|
||||
"SIDE BETS" : {
|
||||
"extractionState" : "stale",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
|
||||
@ -62,7 +62,6 @@ struct BlackjackSettingsData: PersistableGameData {
|
||||
blackjackPayout: 1.5,
|
||||
insuranceAllowed: true,
|
||||
neverAskInsurance: false,
|
||||
sideBetsEnabled: false,
|
||||
showAnimations: true,
|
||||
dealingSpeed: 1.0,
|
||||
showCardsRemaining: true,
|
||||
@ -87,7 +86,6 @@ struct BlackjackSettingsData: PersistableGameData {
|
||||
var blackjackPayout: Double
|
||||
var insuranceAllowed: Bool
|
||||
var neverAskInsurance: Bool
|
||||
var sideBetsEnabled: Bool
|
||||
var showAnimations: Bool
|
||||
var dealingSpeed: Double
|
||||
var showCardsRemaining: Bool
|
||||
|
||||
@ -111,16 +111,6 @@ struct SettingsView: View {
|
||||
TableLimitsPicker(selection: $settings.tableLimits)
|
||||
}
|
||||
|
||||
// 3.5. Side Bets
|
||||
SheetSection(title: String(localized: "SIDE BETS"), icon: "dollarsign.arrow.trianglehead.counterclockwise.rotate.90") {
|
||||
SettingsToggle(
|
||||
title: String(localized: "Enable Side Bets"),
|
||||
subtitle: String(localized: "Perfect Pairs (25:1) and 21+3 (100:1)"),
|
||||
isOn: $settings.sideBetsEnabled,
|
||||
accentColor: accent
|
||||
)
|
||||
}
|
||||
|
||||
// 4. Deck Settings
|
||||
SheetSection(title: String(localized: "DECK SETTINGS"), icon: "rectangle.portrait.on.rectangle.portrait") {
|
||||
DeckCountPicker(selection: $settings.deckCount)
|
||||
|
||||
@ -55,7 +55,6 @@ struct BettingZoneView: View {
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
if state.settings.sideBetsEnabled {
|
||||
// Horizontal layout: PP | Main Bet | 21+3
|
||||
HStack(spacing: Design.Spacing.small) {
|
||||
// Perfect Pairs
|
||||
@ -82,11 +81,6 @@ struct BettingZoneView: View {
|
||||
.frame(width: Design.Size.sideBetZoneWidth)
|
||||
}
|
||||
.frame(height: zoneHeight)
|
||||
} else {
|
||||
// Simple layout: just main bet
|
||||
mainBetZone
|
||||
.frame(height: zoneHeight)
|
||||
}
|
||||
}
|
||||
|
||||
private var mainBetZone: some View {
|
||||
@ -155,14 +149,12 @@ extension Design.Size {
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("With Side Bets") {
|
||||
#Preview("Main Bet Only") {
|
||||
ZStack {
|
||||
Color.Table.felt.ignoresSafeArea()
|
||||
BettingZoneView(
|
||||
state: {
|
||||
let settings = GameSettings()
|
||||
settings.sideBetsEnabled = true
|
||||
let state = GameState(settings: settings)
|
||||
let state = GameState(settings: GameSettings())
|
||||
state.placeBet(amount: 100)
|
||||
return state
|
||||
}(),
|
||||
@ -177,9 +169,7 @@ extension Design.Size {
|
||||
Color.Table.felt.ignoresSafeArea()
|
||||
BettingZoneView(
|
||||
state: {
|
||||
let settings = GameSettings()
|
||||
settings.sideBetsEnabled = true
|
||||
let state = GameState(settings: settings)
|
||||
let state = GameState(settings: GameSettings())
|
||||
state.placeBet(amount: 250)
|
||||
state.placeSideBet(type: .perfectPairs, amount: 25)
|
||||
state.placeSideBet(type: .twentyOnePlusThree, amount: 50)
|
||||
|
||||
@ -135,7 +135,7 @@ struct BlackjackTableView: View {
|
||||
)
|
||||
|
||||
// Side bet toasts (positioned on left/right sides to not cover cards)
|
||||
if state.settings.sideBetsEnabled && state.showSideBetToasts {
|
||||
if state.showSideBetToasts {
|
||||
HStack {
|
||||
// PP on left
|
||||
if state.perfectPairsBet > 0, let ppResult = state.perfectPairsResult {
|
||||
|
||||
@ -36,6 +36,17 @@ public protocol CasinoGameState: SessionManagedGame {
|
||||
|
||||
/// Aggregated statistics from all sessions.
|
||||
var aggregatedStats: AggregatedSessionStats { get }
|
||||
|
||||
// MARK: - Chip Selection
|
||||
|
||||
/// The minimum bet level across all bet types.
|
||||
/// Used by ChipSelectorView to determine if chips should be enabled.
|
||||
/// Returns the smallest bet so chips stay enabled if ANY bet type can accept more.
|
||||
///
|
||||
/// Games with multiple bet types (main bet, side bets) should return the minimum
|
||||
/// bet amount across all placeable bet types, ensuring the chip selector remains
|
||||
/// responsive as long as at least one bet type has room for more chips.
|
||||
var minBetForChipSelector: Int { get }
|
||||
}
|
||||
|
||||
// MARK: - Default Implementations
|
||||
|
||||
Loading…
Reference in New Issue
Block a user