// // RulesHelpView.swift // Blackjack // // Game rules and how to play guide. // import SwiftUI import CasinoKit struct RulesHelpView: View { @Environment(\.dismiss) private var dismiss @State private var currentPage = 0 private let pages: [RulePage] = [ RulePage( title: String(localized: "Objective"), icon: "target", content: [ String(localized: "Beat the dealer by getting a hand value closer to 21 without going over."), String(localized: "If you go over 21, you 'bust' and lose immediately."), String(localized: "If the dealer busts and you haven't, you win.") ] ), RulePage( title: String(localized: "Card Values"), icon: "suit.spade.fill", content: [ String(localized: "2-10: Face value"), String(localized: "Jack, Queen, King: 10"), String(localized: "Ace: 1 or 11 (whichever helps your hand)"), String(localized: "A 'soft' hand has an Ace counting as 11.") ] ), RulePage( title: String(localized: "Blackjack"), icon: "star.fill", content: [ String(localized: "An Ace + 10-value card dealt initially is 'Blackjack'."), String(localized: "Blackjack pays 3:2 (1.5x your bet)."), String(localized: "If both you and dealer have Blackjack, it's a push (tie).") ] ), RulePage( title: String(localized: "Actions"), icon: "hand.tap.fill", content: [ String(localized: "Hit: Take another card"), String(localized: "Stand: Keep your current hand"), String(localized: "Double Down: Double your bet, take one card, then stand"), String(localized: "Split: If you have two cards of the same value, split into two hands"), String(localized: "Surrender: Give up half your bet and end the hand") ] ), RulePage( title: String(localized: "Insurance"), icon: "shield.fill", content: [ String(localized: "Offered when dealer shows an Ace."), String(localized: "Costs half your original bet."), String(localized: "Pays 2:1 if dealer has Blackjack."), String(localized: "Generally not recommended by basic strategy.") ] ), RulePage( title: String(localized: "Dealer Rules"), icon: "person.fill", content: [ String(localized: "Dealer must hit on 16 or less."), String(localized: "Dealer must stand on 17 or more (varies by rules)."), String(localized: "Some games: Dealer hits on 'soft 17' (Ace + 6).") ] ), RulePage( title: String(localized: "Payouts"), icon: "dollarsign.circle.fill", content: [ String(localized: "Win: 1:1 (even money)"), String(localized: "Blackjack: 3:2"), String(localized: "Insurance: 2:1"), String(localized: "Push: Bet returned"), String(localized: "Surrender: Half bet returned") ] ) ] var body: some View { NavigationStack { ZStack { Color.Settings.background .ignoresSafeArea() VStack(spacing: 0) { // Page content TabView(selection: $currentPage) { ForEach(pages.indices, id: \.self) { index in RulePageView(page: pages[index]) .tag(index) } } .tabViewStyle(.page(indexDisplayMode: .never)) // Page indicator HStack(spacing: Design.Spacing.small) { ForEach(pages.indices, id: \.self) { index in Circle() .fill(index == currentPage ? Color.Settings.accent : Color.white.opacity(Design.Opacity.light)) .frame(width: 8, height: 8) } } .padding(.vertical, Design.Spacing.medium) } } .navigationTitle(String(localized: "How to Play")) .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .topBarTrailing) { Button(String(localized: "Done")) { dismiss() } .foregroundStyle(Color.Settings.accent) } } .toolbarBackground(Color.Settings.background, for: .navigationBar) .toolbarColorScheme(.dark, for: .navigationBar) } } } // MARK: - Rule Page Model struct RulePage: Identifiable { let id = UUID() let title: String let icon: String let content: [String] } // MARK: - Rule Page View struct RulePageView: View { let page: RulePage @ScaledMetric(relativeTo: .title) private var iconSize: CGFloat = Design.BaseFontSize.display @ScaledMetric(relativeTo: .title) private var titleSize: CGFloat = Design.BaseFontSize.title @ScaledMetric(relativeTo: .body) private var bodySize: CGFloat = Design.BaseFontSize.body var body: some View { ScrollView { VStack(spacing: Design.Spacing.xLarge) { // Icon Image(systemName: page.icon) .font(.system(size: iconSize)) .foregroundStyle(Color.Settings.accent) .padding(.top, Design.Spacing.xxLarge) // Title Text(page.title) .font(.system(size: titleSize, weight: .bold)) .foregroundStyle(.white) // Content VStack(alignment: .leading, spacing: Design.Spacing.medium) { ForEach(page.content.indices, id: \.self) { index in HStack(alignment: .top, spacing: Design.Spacing.medium) { Text("•") .foregroundStyle(Color.Settings.accent) Text(page.content[index]) .font(.system(size: bodySize)) .foregroundStyle(.white.opacity(Design.Opacity.heavy)) } } } .padding(.horizontal, Design.Spacing.xxLarge) Spacer() } } } } #Preview { RulesHelpView() }