Complete native rewrite of the web-based SoliCards game as a SwiftUI multiplatform app targeting iOS 17+, iPadOS 17+, and macOS 14+. Three solitaire variants (Klondike, Spider, FreeCell) with full game rules, drag & drop, smart zoom layout, 6 themes, 4 difficulty levels, SwiftData persistence, VoiceOver accessibility, and 57 unit tests. Key features: - MVVM + Protocol-Oriented Strategy architecture - DragGesture with coordinate-space hit-testing (long press + drag) - Smart zoom: cards auto-size to fit screen based on deepest column - Landscape: 30% bigger cards with scrollable overflow (iOS) - macOS: 120pt card cap, 92% height buffer for window resizing - Auto-save, game resume, statistics tracking via SwiftData - Privacy manifest, app icon, String Catalog, zero dependencies Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
60 lines
1.5 KiB
Swift
60 lines
1.5 KiB
Swift
import Foundation
|
|
|
|
enum Difficulty: String, CaseIterable, Codable, Identifiable, Sendable {
|
|
case easy, medium, hard, expert
|
|
|
|
var id: String { rawValue }
|
|
|
|
var displayName: String { rawValue.capitalized }
|
|
|
|
var settings: DifficultySettings {
|
|
switch self {
|
|
case .easy:
|
|
DifficultySettings(
|
|
drawCount: 1,
|
|
maxUndos: .max,
|
|
hintsEnabled: true,
|
|
scoreMultiplier: 0.5,
|
|
timePenalty: 0,
|
|
autoFlipDelay: 0.5
|
|
)
|
|
case .medium:
|
|
DifficultySettings(
|
|
drawCount: 3,
|
|
maxUndos: 20,
|
|
hintsEnabled: true,
|
|
scoreMultiplier: 1.0,
|
|
timePenalty: 2,
|
|
autoFlipDelay: 0.3
|
|
)
|
|
case .hard:
|
|
DifficultySettings(
|
|
drawCount: 3,
|
|
maxUndos: 10,
|
|
hintsEnabled: false,
|
|
scoreMultiplier: 1.5,
|
|
timePenalty: 5,
|
|
autoFlipDelay: 0.2
|
|
)
|
|
case .expert:
|
|
DifficultySettings(
|
|
drawCount: 3,
|
|
maxUndos: 5,
|
|
hintsEnabled: false,
|
|
scoreMultiplier: 2.0,
|
|
timePenalty: 10,
|
|
autoFlipDelay: 0.1
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
struct DifficultySettings: Sendable {
|
|
let drawCount: Int
|
|
let maxUndos: Int
|
|
let hintsEnabled: Bool
|
|
let scoreMultiplier: Double
|
|
let timePenalty: Int
|
|
let autoFlipDelay: TimeInterval
|
|
}
|