import Foundation protocol GameRules: Sendable { var variant: GameVariant { get } /// Deal cards from a shuffled deck into the initial board layout. func deal(deck: [Card]) -> GameSnapshot /// Check if moving the given cards from source to destination is valid. func canMove(cards: [Card], from: CardLocation, to: CardLocation, state: GameSnapshot) -> Bool /// Return all valid destinations for the given cards from a source location. func validDestinations(for cards: [Card], from: CardLocation, state: GameSnapshot) -> [CardLocation] /// Draw card(s) from the stock pile. func drawFromStock(state: inout GameSnapshot, drawCount: Int) -> MoveAction? /// Calculate the score change for a given move. func scoreForMove(from: CardLocation, to: CardLocation) -> Int /// Check if the game is won. func isWon(state: GameSnapshot) -> Bool /// Check if auto-complete is possible (all remaining cards are face-up and ordered). func canAutoComplete(state: GameSnapshot) -> Bool /// Find available hints, ordered by priority (1 = highest). func findHints(state: GameSnapshot, settings: DifficultySettings) -> [HintResult] /// Check if a card can be stacked onto another card on a tableau. func canStackOnTableau(card: Card, onto target: Card) -> Bool /// Check if a group of cards can be picked up from a location. func canPickUp(cards: [Card], from: CardLocation, state: GameSnapshot) -> Bool } extension GameRules { func validDestinations(for cards: [Card], from: CardLocation, state: GameSnapshot) -> [CardLocation] { var destinations: [CardLocation] = [] for i in 0..