import Foundation struct Dealer { private static let normalCardOrder = [ Card(.eichel, .ober), Card(.blatt, .ober), Card(.herz, .ober), Card(.schelln, .ober), Card(.eichel, .unter), Card(.blatt, .unter), Card(.herz, .unter), Card(.schelln, .unter), Card(.herz, .ass), Card(.herz, .zehn), Card(.herz, .könig), Card(.herz, .neun), Card(.herz, .acht), Card(.herz, .sieben), Card(.eichel, .ass), Card(.eichel, .zehn), Card(.eichel, .könig), Card(.eichel, .neun), Card(.eichel, .acht), Card(.eichel, .sieben), Card(.blatt, .ass), Card(.blatt, .zehn), Card(.blatt, .könig), Card(.blatt, .neun), Card(.blatt, .acht), Card(.blatt, .sieben), Card(.schelln, .ass), Card(.schelln, .zehn), Card(.schelln, .könig), Card(.schelln, .neun), Card(.schelln, .acht), Card(.schelln, .sieben), ] private static let wenzCardOder = [ Card(.eichel, .unter), Card(.blatt, .unter), Card(.herz, .unter), Card(.schelln, .unter), Card(.herz, .ass), Card(.herz, .zehn), Card(.herz, .könig), Card(.herz, .ober), Card(.herz, .neun), Card(.herz, .acht), Card(.herz, .sieben), Card(.eichel, .ass), Card(.eichel, .zehn), Card(.eichel, .könig), Card(.eichel, .ober), Card(.eichel, .neun), Card(.eichel, .acht), Card(.eichel, .sieben), Card(.blatt, .ass), Card(.blatt, .zehn), Card(.blatt, .könig), Card(.blatt, .ober), Card(.blatt, .neun), Card(.blatt, .acht), Card(.blatt, .sieben), Card(.schelln, .ass), Card(.schelln, .zehn), Card(.schelln, .könig), Card(.schelln, .ober), Card(.schelln, .neun), Card(.schelln, .acht), Card(.schelln, .sieben), ] private static let geierCardOrder = [ Card(.eichel, .ober), Card(.blatt, .ober), Card(.herz, .ober), Card(.schelln, .ober), Card(.herz, .ass), Card(.herz, .zehn), Card(.herz, .könig), Card(.herz, .unter), Card(.herz, .neun), Card(.herz, .acht), Card(.herz, .sieben), Card(.eichel, .ass), Card(.eichel, .zehn), Card(.eichel, .könig), Card(.eichel, .unter), Card(.eichel, .neun), Card(.eichel, .acht), Card(.eichel, .sieben), Card(.blatt, .ass), Card(.blatt, .zehn), Card(.blatt, .könig), Card(.blatt, .unter), Card(.blatt, .neun), Card(.blatt, .acht), Card(.blatt, .sieben), Card(.schelln, .ass), Card(.schelln, .zehn), Card(.schelln, .könig), Card(.schelln, .unter), Card(.schelln, .neun), Card(.schelln, .acht), Card(.schelln, .sieben), ] private static let eichelCardOrder = [ Card(.eichel, .ober), Card(.blatt, .ober), Card(.herz, .ober), Card(.schelln, .ober), Card(.eichel, .unter), Card(.blatt, .unter), Card(.herz, .unter), Card(.schelln, .unter), Card(.eichel, .ass), Card(.eichel, .zehn), Card(.eichel, .könig), Card(.eichel, .neun), Card(.eichel, .acht), Card(.eichel, .sieben), Card(.blatt, .ass), Card(.blatt, .zehn), Card(.blatt, .könig), Card(.blatt, .neun), Card(.blatt, .acht), Card(.blatt, .sieben), Card(.herz, .ass), Card(.herz, .zehn), Card(.herz, .könig), Card(.herz, .neun), Card(.herz, .acht), Card(.herz, .sieben), Card(.schelln, .ass), Card(.schelln, .zehn), Card(.schelln, .könig), Card(.schelln, .neun), Card(.schelln, .acht), Card(.schelln, .sieben), ] private static let blattCardOrder = [ Card(.eichel, .ober), Card(.blatt, .ober), Card(.herz, .ober), Card(.schelln, .ober), Card(.eichel, .unter), Card(.blatt, .unter), Card(.herz, .unter), Card(.schelln, .unter), Card(.blatt, .ass), Card(.blatt, .zehn), Card(.blatt, .könig), Card(.blatt, .neun), Card(.blatt, .acht), Card(.blatt, .sieben), Card(.eichel, .ass), Card(.eichel, .zehn), Card(.eichel, .könig), Card(.eichel, .neun), Card(.eichel, .acht), Card(.eichel, .sieben), Card(.herz, .ass), Card(.herz, .zehn), Card(.herz, .könig), Card(.herz, .neun), Card(.herz, .acht), Card(.herz, .sieben), Card(.schelln, .ass), Card(.schelln, .zehn), Card(.schelln, .könig), Card(.schelln, .neun), Card(.schelln, .acht), Card(.schelln, .sieben), ] private static let schellnCardOrder = [ Card(.eichel, .ober), Card(.blatt, .ober), Card(.herz, .ober), Card(.schelln, .ober), Card(.eichel, .unter), Card(.blatt, .unter), Card(.herz, .unter), Card(.schelln, .unter), Card(.schelln, .ass), Card(.schelln, .zehn), Card(.schelln, .könig), Card(.schelln, .neun), Card(.schelln, .acht), Card(.schelln, .sieben), Card(.eichel, .ass), Card(.eichel, .zehn), Card(.eichel, .könig), Card(.eichel, .neun), Card(.eichel, .acht), Card(.eichel, .sieben), Card(.blatt, .ass), Card(.blatt, .zehn), Card(.blatt, .könig), Card(.blatt, .neun), Card(.blatt, .acht), Card(.blatt, .sieben), Card(.herz, .ass), Card(.herz, .zehn), Card(.herz, .könig), Card(.herz, .neun), Card(.herz, .acht), Card(.herz, .sieben), ] private static let normalSortIndex: [Card : Int] = { normalCardOrder.enumerated().reduce(into: [:]) { $0[$1.element] = $1.offset } }() private static let wenzSortIndex: [Card : Int] = { wenzCardOder.enumerated().reduce(into: [:]) { $0[$1.element] = $1.offset } }() private static let geierSortIndex: [Card : Int] = { geierCardOrder.enumerated().reduce(into: [:]) { $0[$1.element] = $1.offset } }() private static let eichelSortIndex: [Card : Int] = { eichelCardOrder.enumerated().reduce(into: [:]) { $0[$1.element] = $1.offset } }() private static let blattSortIndex: [Card : Int] = { blattCardOrder.enumerated().reduce(into: [:]) { $0[$1.element] = $1.offset } }() private static let schellnSortIndex: [Card : Int] = { schellnCardOrder.enumerated().reduce(into: [:]) { $0[$1.element] = $1.offset } }() static func sort(cards: T, using strategy: CardSortingStrategy = .normal) -> [Card] where T: Sequence, T.Element == Card { switch strategy { case .normal: return cards.sorted { normalSortIndex[$0]! < normalSortIndex[$1]! } case .wenz: return cards.sorted { wenzSortIndex[$0]! < wenzSortIndex[$1]! } case .geier: return cards.sorted { geierSortIndex[$0]! < geierSortIndex[$1]! } case .soloEichel: return cards.sorted { eichelSortIndex[$0]! < eichelSortIndex[$1]! } case .soloBlatt: return cards.sorted { blattSortIndex[$0]! < blattSortIndex[$1]! } case .soloSchelln: return cards.sorted { schellnSortIndex[$0]! < schellnSortIndex[$1]! } } } /** Creates a random assignment of 8 cards per 4 players. */ static func deal() -> [[Card]] { let deck = Card.Suit.allCases.map { suit in Card.Symbol.allCases.map { symbol in Card(suit: suit, symbol: symbol) } }.joined() let random = Array(deck).shuffled() return (0..<4).map { part -> Array.SubSequence in let start = part * 8 let end = start + 8 return random[start..(in cards: T, for game: GameType) -> Int where T: Sequence, T.Element == Card { var count = 0 let trumpsInOrder: Array.SubSequence switch game.sortingType { case .normal: trumpsInOrder = normalCardOrder[0..<8] case .wenz: trumpsInOrder = wenzCardOder[0..<4] case .geier: trumpsInOrder = geierCardOrder[0..<4] case .soloEichel: trumpsInOrder = eichelCardOrder[0..<8] case .soloBlatt: trumpsInOrder = blattCardOrder[0..<8] case .soloSchelln: trumpsInOrder = schellnCardOrder[0..<8] } while cards.contains(trumpsInOrder[count]) { count += 1 } guard count >= 3 else { return 0 } return count } }