SoliCards-iOS-iPadOS-MacOS/SoliCards/GameEngine/MoveValidator.swift
idev2025 de0da01f25 feat: SoliCards v1.2.0 — native SwiftUI solitaire for iOS, iPadOS, macOS
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.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 08:26:14 -04:00

42 lines
1.4 KiB
Swift

import Foundation
enum MoveValidator {
/// True if the two cards have alternating colors (one red, one black).
static func isAlternatingColor(_ card: Card, with other: Card) -> Bool {
card.color != other.color
}
/// True if both cards share the same suit.
static func isSameSuit(_ card: Card, as other: Card) -> Bool {
card.suit == other.suit
}
/// True if card's rank is exactly one higher than target (for foundation building AK).
static func isAscending(_ card: Card, onto target: Card) -> Bool {
card.rank.rawValue == target.rank.rawValue + 1
}
/// True if card's rank is exactly one lower than target (for tableau stacking KA).
static func isDescending(_ card: Card, onto target: Card) -> Bool {
card.rank.rawValue == target.rank.rawValue - 1
}
/// True if the card is an Ace.
static func isAce(_ card: Card) -> Bool {
card.rank == .ace
}
/// True if the card is a King.
static func isKing(_ card: Card) -> Bool {
card.rank == .king
}
/// True if the card can be placed on a foundation pile (same suit, ascending).
static func canPlaceOnFoundation(_ card: Card, topCard: Card?) -> Bool {
guard let topCard else {
return isAce(card)
}
return isSameSuit(card, as: topCard) && isAscending(card, onto: topCard)
}
}