Schafkopf-Server/Sources/App/Sorting/Dealer.swift
2021-12-01 22:49:54 +01:00

299 lines
9.0 KiB
Swift

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<T>(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<Card>.SubSequence in
let start = part * 8
let end = start + 8
return random[start..<end]
}.map { sort(cards: $0) }
}
static func consecutiveTrumps<T>(in cards: T, for game: GameType) -> Int where T: Sequence, T.Element == Card {
var count = 0
let trumpsInOrder: Array<Card>.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
}
}