# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## What This Project Is SoliCards is a native SwiftUI solitaire card game for iOS 17+, iPadOS 17+, and macOS 14+. It was ported from a web-based JavaScript game (`game-SoliCards/SoliCards.html`) following the 7-phase workflow defined in [PROMPT.md](PROMPT.md). ## Build Commands ```bash # Generate Xcode project (required after cloning or editing project.yml) xcodegen generate # Build for iOS Simulator xcodebuild build -project SoliCards.xcodeproj -scheme SoliCards -destination 'platform=iOS Simulator,name=iPhone 16' # Build for macOS xcodebuild build -project SoliCards.xcodeproj -scheme SoliCards -destination 'platform=macOS' CODE_SIGN_IDENTITY=- CODE_SIGNING_REQUIRED=NO # Run tests xcodebuild test -project SoliCards.xcodeproj -scheme SoliCardsTests -destination 'platform=iOS Simulator,name=iPhone 16' # Static analysis xcodebuild analyze -project SoliCards.xcodeproj -scheme SoliCards -destination 'platform=iOS Simulator,name=iPhone 16' ``` ## Architecture **MVVM + Protocol-Oriented Strategy** — see [ARCHITECTURE.md](ARCHITECTURE.md) for full details. - `GameRules` protocol with 3 conforming structs: `KlondikeRules`, `SpiderRules`, `FreeCellRules` - `@Observable` macro (not `ObservableObject`) for property-level SwiftUI observation - `@MainActor` on ViewModels and TimerService for Swift 6 concurrency safety - `DragGesture` + `PreferenceKey` frame hit-testing for card drag & drop (not `onDrag`/`onDrop`) - SwiftData for persistence (`GameRecord`, `StatsRecord`, `PrefsRecord`) - Zero external dependencies ## Key Conventions - `.xcodeproj` is generated by xcodegen from `project.yml` — do not edit it by hand - `Array.trailingSuffix(while:)` extension replaces missing stdlib `suffix(while:)` — used in rules engines for face-up card runs - Card images are loaded from the asset catalog via platform-conditional helpers (`UIImage`/`NSImage`) in `CardView` - Sound playback is dispatched via `nonisolated func playSound()` to avoid `@MainActor` isolation on the audio path ## Test Suite 57 tests across 12 suites. All tests are in `SoliCardsTests/` using Swift Testing (`@Test`, `#expect`). Key test coverage areas: - `GameEngine/` — KlondikeRules, SpiderRules, FreeCellRules, MoveValidator, AutoCompleter, GameState - `Models/` — Card, Deck, Difficulty, GameVariant, Rank, Suit