import Foundation protocol CardOrder { static var trumpCount: Int { get } static var cardOrder: [Card] { get } } extension CardOrder { private static var sortIndex: [Card : Int] { cardOrder.enumerated().reduce(into: [:]) { $0[$1.element] = $1.offset } } private static var trumpOrder: [Card] { Array(cardOrder[0.. { Set(trumpOrder) } static func isTrump(_ card: Card) -> Bool { trumps.contains(card) } static func highCardIndex(cards: [Card]) -> Int { let high: Card if isTrump(cards[0]) { high = sort(cards).first! } else { let suit = cards.first!.suit high = cards.filter { $0.suit == suit } .sorted { $0.symbol }.first! } return cards.firstIndex(of: high)! } static func consecutiveTrumps(_ cards: [Card]) -> Int { var count = 0 while cards.contains(trumpOrder[count]) { count += 1 } guard count >= 3 else { return 0 } return count } static func sort(_ cards: [Card]) -> [Card] { cards.sorted { sortIndex[$0]! < sortIndex[$1]! } } static func trumpCount(_ cards: [Card]) -> Int { cards.filter { trumps.contains($0) }.count } static func hasTrump(in cards: [Card]) -> Bool { cards.contains { trumps.contains($0) } } static func has(suit: Card.Suit, in cards: [Card]) -> Bool { cards.contains { !isTrump($0) && $0.suit == suit } } static func cards(with suit: Card.Suit, in cards: [Card]) -> [Card] { cards.filter { !isTrump($0) && $0.suit == suit } } }