CasinoGames/Blackjack/Views/Game/CardCountView.swift

89 lines
3.0 KiB
Swift

//
// CardCountView.swift
// Blackjack
//
// Displays the Hi-Lo running and true count for card counting practice.
//
import SwiftUI
import CasinoKit
/// Displays the Hi-Lo running count for card counting practice.
struct CardCountView: View {
let runningCount: Int
let trueCount: Double
var body: some View {
HStack(spacing: Design.Spacing.large) {
// Running count
VStack(spacing: Design.Spacing.xxSmall) {
Text("Running")
.font(.system(size: Design.Size.cardCountLabelSize, weight: .medium))
.foregroundStyle(.white.opacity(Design.Opacity.medium))
Text(runningCount >= 0 ? "+\(runningCount)" : "\(runningCount)")
.font(.system(size: Design.Size.cardCountValueSize, weight: .bold, design: .monospaced))
.foregroundStyle(countColor(for: runningCount))
}
Divider()
.frame(height: Design.Spacing.xLarge)
.background(Color.white.opacity(Design.Opacity.hint))
// True count
VStack(spacing: Design.Spacing.xxSmall) {
Text("True")
.font(.system(size: Design.Size.cardCountLabelSize, weight: .medium))
.foregroundStyle(.white.opacity(Design.Opacity.medium))
Text(trueCount >= 0 ? "+\(trueCount, format: .number.precision(.fractionLength(1)))" : "\(trueCount, format: .number.precision(.fractionLength(1)))")
.font(.system(size: Design.Size.cardCountValueSize, weight: .bold, design: .monospaced))
.foregroundStyle(countColor(for: Int(trueCount.rounded())))
}
}
.padding(.horizontal, Design.Spacing.large)
.padding(.vertical, Design.Spacing.small)
.background(
RoundedRectangle(cornerRadius: Design.CornerRadius.medium)
.fill(Color.black.opacity(Design.Opacity.subtle))
)
.accessibilityElement(children: .ignore)
.accessibilityLabel(String(localized: "Card Count"))
.accessibilityValue(String(localized: "Running \(runningCount), True \(trueCount, format: .number.precision(.fractionLength(1)))"))
}
private func countColor(for count: Int) -> Color {
if count > 0 {
return .green // Positive count favors player
} else if count < 0 {
return .red // Negative count favors house
} else {
return .white // Neutral
}
}
}
// MARK: - Previews
#Preview("Neutral Count") {
ZStack {
Color.Table.felt.ignoresSafeArea()
CardCountView(runningCount: 0, trueCount: 0.0)
}
}
#Preview("Positive Count") {
ZStack {
Color.Table.felt.ignoresSafeArea()
CardCountView(runningCount: 7, trueCount: 2.3)
}
}
#Preview("Negative Count") {
ZStack {
Color.Table.felt.ignoresSafeArea()
CardCountView(runningCount: -4, trueCount: -1.5)
}
}