Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
parent
a9b4f95bb4
commit
982d54ed1d
@ -349,7 +349,7 @@ final class GameState {
|
|||||||
syncSoundSettings()
|
syncSoundSettings()
|
||||||
loadSavedGame()
|
loadSavedGame()
|
||||||
|
|
||||||
// Start timing for the first round's betting phase
|
// Start timing for the first round (includes betting phase)
|
||||||
roundStartTime = Date()
|
roundStartTime = Date()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -503,9 +503,9 @@ final class GameState {
|
|||||||
func deal() async {
|
func deal() async {
|
||||||
guard canDeal else { return }
|
guard canDeal else { return }
|
||||||
|
|
||||||
// Track bet amount for statistics (roundStartTime is set in newRound)
|
// Track bet amount for statistics (roundStartTime was set when betting phase started)
|
||||||
roundBetAmount = currentBet + perfectPairsBet + twentyOnePlusThreeBet
|
roundBetAmount = currentBet + perfectPairsBet + twentyOnePlusThreeBet
|
||||||
Design.debugLog("🎴 Deal started - roundStartTime: \(String(describing: roundStartTime)), roundBetAmount: \(roundBetAmount)")
|
Design.debugLog("🎴 Deal started - roundBetAmount: \(roundBetAmount), time since round start: \(Date().timeIntervalSince(roundStartTime ?? Date()))s")
|
||||||
|
|
||||||
// Ensure enough cards for a full hand - reshuffle if needed
|
// Ensure enough cards for a full hand - reshuffle if needed
|
||||||
if !engine.canDealNewHand {
|
if !engine.canDealNewHand {
|
||||||
@ -1224,15 +1224,15 @@ final class GameState {
|
|||||||
twentyOnePlusThreeResult = nil
|
twentyOnePlusThreeResult = nil
|
||||||
showSideBetToasts = false
|
showSideBetToasts = false
|
||||||
|
|
||||||
// Start timing for the new round (includes betting phase)
|
|
||||||
roundStartTime = Date()
|
|
||||||
Design.debugLog("🎰 New round started - roundStartTime: \(roundStartTime!)")
|
|
||||||
|
|
||||||
// Reset UI state
|
// Reset UI state
|
||||||
showResultBanner = false
|
showResultBanner = false
|
||||||
lastRoundResult = nil
|
lastRoundResult = nil
|
||||||
currentPhase = .betting
|
currentPhase = .betting
|
||||||
|
|
||||||
|
// Start timing for the new round (includes betting phase)
|
||||||
|
roundStartTime = Date()
|
||||||
|
Design.debugLog("🎰 New round started - roundStartTime: \(roundStartTime!)")
|
||||||
|
|
||||||
sound.play(.newRound)
|
sound.play(.newRound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5068,6 +5068,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"PLAYER" : {
|
||||||
|
"comment" : "Title to display for a player hand when the hand number is not available.",
|
||||||
|
"isCommentAutoGenerated" : true
|
||||||
|
},
|
||||||
"Player hand: %@. Value: %@" : {
|
"Player hand: %@. Value: %@" : {
|
||||||
"comment" : "A user-readable string describing a player's blackjack hand, including the card values and any relevant game results. The argument is a comma-separated list of the card descriptions in the player's hand.",
|
"comment" : "A user-readable string describing a player's blackjack hand, including the card values and any relevant game results. The argument is a comma-separated list of the card descriptions in the player's hand.",
|
||||||
"isCommentAutoGenerated" : true,
|
"isCommentAutoGenerated" : true,
|
||||||
|
|||||||
@ -156,7 +156,8 @@ extension Color {
|
|||||||
enum Hand {
|
enum Hand {
|
||||||
static let player = Color(red: 0.2, green: 0.5, blue: 0.8)
|
static let player = Color(red: 0.2, green: 0.5, blue: 0.8)
|
||||||
static let dealer = Color(red: 0.8, green: 0.3, blue: 0.3)
|
static let dealer = Color(red: 0.8, green: 0.3, blue: 0.3)
|
||||||
static let active = Color.yellow
|
/// Bright emerald green - readable with white text, indicates "your turn"
|
||||||
|
static let active = Color(red: 0.0, green: 0.7, blue: 0.45)
|
||||||
static let inactive = Color.white.opacity(CasinoDesign.Opacity.medium)
|
static let inactive = Color.white.opacity(CasinoDesign.Opacity.medium)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// DealerHandView.swift
|
// DealerHandView.swift
|
||||||
// Blackjack
|
// Blackjack
|
||||||
//
|
//
|
||||||
// Displays the dealer's hand with cards and value.
|
// Displays the dealer's hand with label, value badge, and cards.
|
||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
@ -21,37 +21,33 @@ struct DealerHandView: View {
|
|||||||
let visibleCardCount: Int
|
let visibleCardCount: Int
|
||||||
|
|
||||||
@ScaledMetric(relativeTo: .headline) private var labelFontSize: CGFloat = Design.Size.handLabelFontSize
|
@ScaledMetric(relativeTo: .headline) private var labelFontSize: CGFloat = Design.Size.handLabelFontSize
|
||||||
@ScaledMetric(relativeTo: .headline) private var badgeHeight: CGFloat = CasinoDesign.Size.valueBadge
|
|
||||||
|
/// The value to display in the badge (based on visible cards and hole card state).
|
||||||
|
private var displayValue: Int? {
|
||||||
|
guard !hand.cards.isEmpty && visibleCardCount > 0 else { return nil }
|
||||||
|
|
||||||
|
if showHoleCard {
|
||||||
|
// Hole card revealed - calculate value from visible cards
|
||||||
|
let visibleCards = Array(hand.cards.prefix(visibleCardCount))
|
||||||
|
return BlackjackHand.bestValue(for: visibleCards)
|
||||||
|
} else {
|
||||||
|
// Hole card hidden - show only the first (face-up) card's value
|
||||||
|
return hand.cards[0].blackjackValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
|
||||||
VStack(spacing: Design.Spacing.small) {
|
VStack(spacing: Design.Spacing.small) {
|
||||||
// Label and value - fixed height prevents vertical layout shift
|
// Label and value badge
|
||||||
HStack(spacing: Design.Spacing.small) {
|
HandLabelView(
|
||||||
Text(String(localized: "DEALER"))
|
title: String(localized: "DEALER"),
|
||||||
.font(.system(size: labelFontSize, weight: .bold, design: .rounded))
|
value: displayValue,
|
||||||
.foregroundStyle(.white)
|
badgeColor: Color.Hand.dealer
|
||||||
|
)
|
||||||
// Calculate value from visible cards only
|
|
||||||
if !hand.cards.isEmpty && visibleCardCount > 0 {
|
|
||||||
if showHoleCard {
|
|
||||||
// Hole card revealed - calculate value from visible cards
|
|
||||||
let visibleCards = Array(hand.cards.prefix(visibleCardCount))
|
|
||||||
let displayValue = BlackjackHand.bestValue(for: visibleCards)
|
|
||||||
ValueBadge(value: displayValue, color: Color.Hand.dealer)
|
|
||||||
.animation(nil, value: displayValue) // No animation when value changes
|
|
||||||
} else {
|
|
||||||
// Hole card hidden - show only the first (face-up) card's value
|
|
||||||
ValueBadge(value: hand.cards[0].blackjackValue, color: Color.Hand.dealer)
|
|
||||||
.animation(nil, value: hand.cards[0].blackjackValue) // No animation when value changes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.frame(minHeight: badgeHeight) // Reserve consistent height
|
|
||||||
// Remove animations on badge appearance/value changes
|
|
||||||
.animation(nil, value: visibleCardCount)
|
.animation(nil, value: visibleCardCount)
|
||||||
.animation(nil, value: showHoleCard)
|
.animation(nil, value: showHoleCard)
|
||||||
// Cards with result badge overlay (overlay prevents height change)
|
|
||||||
|
// Cards with result badge overlay
|
||||||
HStack(spacing: hand.cards.isEmpty ? Design.Spacing.small : cardSpacing) {
|
HStack(spacing: hand.cards.isEmpty ? Design.Spacing.small : cardSpacing) {
|
||||||
CardStackView.dealer(
|
CardStackView.dealer(
|
||||||
cards: hand.cards,
|
cards: hand.cards,
|
||||||
@ -118,6 +114,8 @@ struct DealerHandView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Previews
|
||||||
|
|
||||||
#Preview("Empty Hand") {
|
#Preview("Empty Hand") {
|
||||||
ZStack {
|
ZStack {
|
||||||
Color.Table.felt.ignoresSafeArea()
|
Color.Table.felt.ignoresSafeArea()
|
||||||
@ -171,4 +169,3 @@ struct DealerHandView: View {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
107
Blackjack/Blackjack/Views/Table/HandLabelView.swift
Normal file
107
Blackjack/Blackjack/Views/Table/HandLabelView.swift
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
//
|
||||||
|
// HandLabelView.swift
|
||||||
|
// Blackjack
|
||||||
|
//
|
||||||
|
// Shared label component for hand displays (dealer and player).
|
||||||
|
// Shows title text with an optional value badge.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import CasinoKit
|
||||||
|
|
||||||
|
/// Displays a hand label with title and value badge.
|
||||||
|
/// Used by both DealerHandView and PlayerHandView for consistent appearance.
|
||||||
|
struct HandLabelView: View {
|
||||||
|
let title: String
|
||||||
|
let value: Int?
|
||||||
|
let valueText: String?
|
||||||
|
let badgeColor: Color
|
||||||
|
|
||||||
|
@ScaledMetric(relativeTo: .headline) private var labelFontSize: CGFloat = Design.Size.handLabelFontSize
|
||||||
|
@ScaledMetric(relativeTo: .headline) private var badgeHeight: CGFloat = CasinoDesign.Size.valueBadge
|
||||||
|
|
||||||
|
/// Creates a hand label with a numeric value badge.
|
||||||
|
init(title: String, value: Int?, badgeColor: Color) {
|
||||||
|
self.title = title
|
||||||
|
self.value = value
|
||||||
|
self.valueText = nil
|
||||||
|
self.badgeColor = badgeColor
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a hand label with a text value badge (for soft hands like "8/18").
|
||||||
|
init(title: String, valueText: String?, badgeColor: Color) {
|
||||||
|
self.title = title
|
||||||
|
self.value = nil
|
||||||
|
self.valueText = valueText
|
||||||
|
self.badgeColor = badgeColor
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
HStack(spacing: Design.Spacing.small) {
|
||||||
|
Text(title)
|
||||||
|
.font(.system(size: labelFontSize, weight: .bold, design: .rounded))
|
||||||
|
.foregroundStyle(.white)
|
||||||
|
|
||||||
|
if let value = value {
|
||||||
|
ValueBadge(value: value, color: badgeColor)
|
||||||
|
} else if let text = valueText, !text.isEmpty {
|
||||||
|
TextValueBadge(text: text, color: badgeColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fixedSize() // Prevent the label from being constrained/truncated
|
||||||
|
.frame(minHeight: badgeHeight)
|
||||||
|
.animation(nil, value: value)
|
||||||
|
.animation(nil, value: valueText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A badge that displays text (for soft hand values like "8/18").
|
||||||
|
struct TextValueBadge: View {
|
||||||
|
let text: String
|
||||||
|
let color: Color
|
||||||
|
|
||||||
|
// Match ValueBadge styling from CasinoKit
|
||||||
|
@ScaledMetric(relativeTo: .headline) private var fontSize: CGFloat = 15
|
||||||
|
@ScaledMetric(relativeTo: .headline) private var badgeHeight: CGFloat = CasinoDesign.Size.valueBadge
|
||||||
|
@ScaledMetric(relativeTo: .headline) private var badgePadding: CGFloat = 8
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
Text(text)
|
||||||
|
.font(.system(size: fontSize, weight: .bold, design: .rounded))
|
||||||
|
.foregroundStyle(.white)
|
||||||
|
.lineLimit(1)
|
||||||
|
.fixedSize(horizontal: true, vertical: false) // Prevent truncation
|
||||||
|
.padding(.horizontal, badgePadding)
|
||||||
|
.frame(minHeight: badgeHeight)
|
||||||
|
.background(
|
||||||
|
Capsule()
|
||||||
|
.fill(color)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Previews
|
||||||
|
|
||||||
|
#Preview("Dealer Label") {
|
||||||
|
ZStack {
|
||||||
|
Color.Table.felt.ignoresSafeArea()
|
||||||
|
VStack(spacing: Design.Spacing.large) {
|
||||||
|
HandLabelView(title: "DEALER", value: 21, badgeColor: Color.Hand.dealer)
|
||||||
|
HandLabelView(title: "DEALER", value: 17, badgeColor: Color.Hand.dealer)
|
||||||
|
HandLabelView(title: "DEALER", value: nil, badgeColor: Color.Hand.dealer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Preview("Player Label") {
|
||||||
|
ZStack {
|
||||||
|
Color.Table.felt.ignoresSafeArea()
|
||||||
|
VStack(spacing: Design.Spacing.large) {
|
||||||
|
HandLabelView(title: "PLAYER", value: 21, badgeColor: Color.Hand.player)
|
||||||
|
HandLabelView(title: "PLAYER", valueText: "8/18", badgeColor: Color.Hand.player)
|
||||||
|
HandLabelView(title: "Hand 1", value: 17, badgeColor: Color.Hand.player)
|
||||||
|
HandLabelView(title: "Hand 2", valueText: "5/15", badgeColor: Color.Hand.active)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -2,7 +2,7 @@
|
|||||||
// PlayerHandView.swift
|
// PlayerHandView.swift
|
||||||
// Blackjack
|
// Blackjack
|
||||||
//
|
//
|
||||||
// Displays a single player hand with cards, value, bet, and result.
|
// Displays a single player hand with label, value badge, cards, and bet.
|
||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
@ -34,8 +34,21 @@ struct PlayerHandView: View {
|
|||||||
@ScaledMetric(relativeTo: .body) private var hintPaddingH: CGFloat = Design.Size.hintPaddingH
|
@ScaledMetric(relativeTo: .body) private var hintPaddingH: CGFloat = Design.Size.hintPaddingH
|
||||||
@ScaledMetric(relativeTo: .body) private var hintPaddingV: CGFloat = Design.Size.hintPaddingV
|
@ScaledMetric(relativeTo: .body) private var hintPaddingV: CGFloat = Design.Size.hintPaddingV
|
||||||
|
|
||||||
|
/// The title to display (PLAYER or Hand #).
|
||||||
|
private var displayTitle: String {
|
||||||
|
if let number = handNumber {
|
||||||
|
return String(localized: "Hand \(number)")
|
||||||
|
}
|
||||||
|
return String(localized: "PLAYER")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The badge color (active hands get highlight color).
|
||||||
|
private var badgeColor: Color {
|
||||||
|
isActive ? Color.Hand.active : Color.Hand.player
|
||||||
|
}
|
||||||
|
|
||||||
/// Calculates display info for visible cards using shared BlackjackHand logic.
|
/// Calculates display info for visible cards using shared BlackjackHand logic.
|
||||||
private var visibleCardsDisplayInfo: (text: String, color: Color)? {
|
private var visibleCardsDisplayInfo: (text: String, value: Int, isBusted: Bool)? {
|
||||||
guard !hand.cards.isEmpty else { return nil }
|
guard !hand.cards.isEmpty else { return nil }
|
||||||
|
|
||||||
let visibleCards = Array(hand.cards.prefix(visibleCardCount))
|
let visibleCards = Array(hand.cards.prefix(visibleCardCount))
|
||||||
@ -45,27 +58,24 @@ struct PlayerHandView: View {
|
|||||||
let (hardValue, softValue) = BlackjackHand.calculateValues(for: visibleCards)
|
let (hardValue, softValue) = BlackjackHand.calculateValues(for: visibleCards)
|
||||||
let displayValue = BlackjackHand.bestValue(for: visibleCards)
|
let displayValue = BlackjackHand.bestValue(for: visibleCards)
|
||||||
let hasSoftAce = BlackjackHand.hasSoftAce(for: visibleCards)
|
let hasSoftAce = BlackjackHand.hasSoftAce(for: visibleCards)
|
||||||
|
let isBusted = hardValue > 21
|
||||||
// Determine color based on visible cards
|
|
||||||
let isVisibleBlackjack = visibleCards.count == 2 && displayValue == 21 && !hand.isSplit
|
|
||||||
let isVisibleBusted = hardValue > 21
|
|
||||||
let isVisible21 = displayValue == 21 && !isVisibleBlackjack
|
|
||||||
|
|
||||||
let displayColor: Color = {
|
|
||||||
if isVisibleBlackjack { return .yellow }
|
|
||||||
if isVisibleBusted { return .red }
|
|
||||||
if isVisible21 { return .green }
|
|
||||||
return .white
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Show value like hand.valueDisplay does (e.g., "8/18" for soft hands)
|
// Show value like hand.valueDisplay does (e.g., "8/18" for soft hands)
|
||||||
let valueText = hasSoftAce ? "\(hardValue)/\(softValue)" : "\(displayValue)"
|
let valueText = hasSoftAce ? "\(hardValue)/\(softValue)" : "\(displayValue)"
|
||||||
|
|
||||||
return (valueText, displayColor)
|
return (valueText, displayValue, isBusted)
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(spacing: Design.Spacing.small) {
|
VStack(spacing: Design.Spacing.small) {
|
||||||
|
// Label and value badge at TOP (consistent with dealer)
|
||||||
|
HandLabelView(
|
||||||
|
title: displayTitle,
|
||||||
|
valueText: visibleCardsDisplayInfo?.text,
|
||||||
|
badgeColor: badgeColor
|
||||||
|
)
|
||||||
|
.animation(nil, value: visibleCardCount)
|
||||||
|
|
||||||
// Cards with container
|
// Cards with container
|
||||||
CardStackView.player(
|
CardStackView.player(
|
||||||
cards: hand.cards,
|
cards: hand.cards,
|
||||||
@ -112,39 +122,25 @@ struct PlayerHandView: View {
|
|||||||
.animation(.easeInOut(duration: Design.Animation.quick), value: isActive)
|
.animation(.easeInOut(duration: Design.Animation.quick), value: isActive)
|
||||||
.animation(.spring(duration: Design.Animation.springDuration), value: hand.result != nil)
|
.animation(.spring(duration: Design.Animation.springDuration), value: hand.result != nil)
|
||||||
|
|
||||||
// Hand info
|
// Bet amount and doubled down indicator
|
||||||
HStack(spacing: Design.Spacing.small) {
|
if hand.bet > 0 || hand.isDoubledDown {
|
||||||
if let number = handNumber {
|
HStack(spacing: Design.Spacing.small) {
|
||||||
Text(String(localized: "Hand \(number)"))
|
if hand.bet > 0 {
|
||||||
.font(.system(size: handNumberSize, weight: .medium))
|
HStack(spacing: Design.Spacing.xSmall) {
|
||||||
.foregroundStyle(.white.opacity(Design.Opacity.medium))
|
Image(systemName: "dollarsign.circle.fill")
|
||||||
}
|
.font(.system(size: iconSize))
|
||||||
|
.foregroundStyle(.yellow)
|
||||||
|
Text("\(hand.bet * (hand.isDoubledDown ? 2 : 1))")
|
||||||
|
.font(.system(size: handNumberSize, weight: .bold, design: .rounded))
|
||||||
|
.foregroundStyle(.yellow)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate value from visible (animation-completed) cards only
|
if hand.isDoubledDown {
|
||||||
if let displayInfo = visibleCardsDisplayInfo {
|
Image(systemName: "xmark.circle.fill")
|
||||||
Text(displayInfo.text)
|
.font(.system(size: iconSize))
|
||||||
.font(.system(size: labelFontSize, weight: .bold, design: .rounded))
|
.foregroundStyle(.purple)
|
||||||
.foregroundStyle(displayInfo.color)
|
}
|
||||||
.animation(nil, value: displayInfo.text)
|
|
||||||
.animation(nil, value: displayInfo.color)
|
|
||||||
}
|
|
||||||
|
|
||||||
if hand.isDoubledDown {
|
|
||||||
Image(systemName: "xmark.circle.fill")
|
|
||||||
.font(.system(size: iconSize))
|
|
||||||
.foregroundStyle(.purple)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bet amount
|
|
||||||
if hand.bet > 0 {
|
|
||||||
HStack(spacing: Design.Spacing.xSmall) {
|
|
||||||
Image(systemName: "dollarsign.circle.fill")
|
|
||||||
.font(.system(size: iconSize))
|
|
||||||
.foregroundStyle(.yellow)
|
|
||||||
Text("\(hand.bet * (hand.isDoubledDown ? 2 : 1))")
|
|
||||||
.font(.system(size: handNumberSize, weight: .bold, design: .rounded))
|
|
||||||
.foregroundStyle(.yellow)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,13 +150,6 @@ struct PlayerHandView: View {
|
|||||||
|
|
||||||
// MARK: - Computed Properties
|
// MARK: - Computed Properties
|
||||||
|
|
||||||
private var valueColor: Color {
|
|
||||||
if hand.isBlackjack { return .yellow }
|
|
||||||
if hand.isBusted { return .red }
|
|
||||||
if hand.value == 21 { return .green }
|
|
||||||
return .white
|
|
||||||
}
|
|
||||||
|
|
||||||
private var playerAccessibilityLabel: String {
|
private var playerAccessibilityLabel: String {
|
||||||
let cardsDescription = hand.cards.map { $0.accessibilityDescription }.joined(separator: ", ")
|
let cardsDescription = hand.cards.map { $0.accessibilityDescription }.joined(separator: ", ")
|
||||||
var label = String(localized: "Player hand: \(cardsDescription). Value: \(hand.valueDisplay)")
|
var label = String(localized: "Player hand: \(cardsDescription). Value: \(hand.valueDisplay)")
|
||||||
@ -192,7 +181,7 @@ struct PlayerHandView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#Preview("With Cards") {
|
#Preview("With Cards - Active") {
|
||||||
ZStack {
|
ZStack {
|
||||||
Color.Table.felt.ignoresSafeArea()
|
Color.Table.felt.ignoresSafeArea()
|
||||||
PlayerHandView(
|
PlayerHandView(
|
||||||
@ -214,15 +203,15 @@ struct PlayerHandView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#Preview("Blackjack") {
|
#Preview("Soft Hand") {
|
||||||
ZStack {
|
ZStack {
|
||||||
Color.Table.felt.ignoresSafeArea()
|
Color.Table.felt.ignoresSafeArea()
|
||||||
PlayerHandView(
|
PlayerHandView(
|
||||||
hand: BlackjackHand(cards: [
|
hand: BlackjackHand(cards: [
|
||||||
Card(suit: .hearts, rank: .ace),
|
Card(suit: .hearts, rank: .ace),
|
||||||
Card(suit: .spades, rank: .king)
|
Card(suit: .spades, rank: .seven)
|
||||||
], bet: 100),
|
], bet: 100),
|
||||||
isActive: false,
|
isActive: true,
|
||||||
showCardCount: true,
|
showCardCount: true,
|
||||||
showAnimations: true,
|
showAnimations: true,
|
||||||
dealingSpeed: 1.0,
|
dealingSpeed: 1.0,
|
||||||
@ -236,7 +225,7 @@ struct PlayerHandView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#Preview("Split Hand") {
|
#Preview("Split Hand - Inactive") {
|
||||||
ZStack {
|
ZStack {
|
||||||
Color.Table.felt.ignoresSafeArea()
|
Color.Table.felt.ignoresSafeArea()
|
||||||
PlayerHandView(
|
PlayerHandView(
|
||||||
@ -244,7 +233,7 @@ struct PlayerHandView: View {
|
|||||||
Card(suit: .clubs, rank: .eight),
|
Card(suit: .clubs, rank: .eight),
|
||||||
Card(suit: .spades, rank: .jack)
|
Card(suit: .spades, rank: .jack)
|
||||||
], bet: 100),
|
], bet: 100),
|
||||||
isActive: true,
|
isActive: false,
|
||||||
showCardCount: false,
|
showCardCount: false,
|
||||||
showAnimations: true,
|
showAnimations: true,
|
||||||
dealingSpeed: 1.0,
|
dealingSpeed: 1.0,
|
||||||
@ -252,8 +241,8 @@ struct PlayerHandView: View {
|
|||||||
cardWidth: 60,
|
cardWidth: 60,
|
||||||
cardSpacing: -20,
|
cardSpacing: -20,
|
||||||
visibleCardCount: 2,
|
visibleCardCount: 2,
|
||||||
currentHint: "Stand",
|
currentHint: nil,
|
||||||
showHintToast: true
|
showHintToast: false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user