import Foundation import Vapor typealias CardId = String struct Card: Codable { enum Symbol: Character, CaseIterable, Codable { case ass = "A" case zehn = "Z" case könig = "K" case ober = "O" case unter = "U" case neun = "9" case acht = "8" case sieben = "7" var points: Int { switch self { case .ass: return 11 case .zehn: return 10 case .könig: return 4 case .ober: return 3 case .unter: return 2 default: return 0 } } } enum Suit: Character, CaseIterable, Codable { case eichel = "E" case blatt = "B" case herz = "H" case schelln = "S" } let symbol: Symbol let suit: Suit init(suit: Suit, symbol: Symbol) { self.suit = suit self.symbol = symbol } init(_ suit: Suit, _ symbol: Symbol) { self.suit = suit self.symbol = symbol } init?(rawValue: String) { guard rawValue.count == 2 else { return nil } guard let suit = Suit(rawValue: rawValue.first!), let symbol = Symbol(rawValue: rawValue.last!) else { return nil } self.suit = suit self.symbol = symbol } var id: CardId { "\(suit.rawValue)\(symbol.rawValue)" } var points: Int { symbol.points } static let allCards: Set = { let all = Card.Suit.allCases.map { suit in Card.Symbol.allCases.map { symbol in Card(suit: suit, symbol: symbol) } }.joined() return Set(all) }() } extension Card: CustomStringConvertible { var description: String { "\(suit) \(symbol)" } } extension Card: Hashable { } struct PlayableCard { let card: Card let isPlayable: Bool var cardInfo: CardInfo { .init(card: card.id, playable: isPlayable) } } struct CardInfo: Codable, Equatable { let card: CardId let playable: Bool }