Schafkopf-Server/Sources/App/Model/Dealer.swift
Christoph Hagen 3db9652cad Sync push
2021-12-03 18:03:29 +01:00

313 lines
8.2 KiB
Swift

import Foundation
private 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 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 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 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 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 let wenzSortIndex: [Card : Int] = {
wenzCardOder.enumerated().reduce(into: [:]) { $0[$1.element] = $1.offset }
}()
private let geierSortIndex: [Card : Int] = {
geierCardOrder.enumerated().reduce(into: [:]) { $0[$1.element] = $1.offset }
}()
private let eichelSortIndex: [Card : Int] = {
eichelCardOrder.enumerated().reduce(into: [:]) { $0[$1.element] = $1.offset }
}()
private let blattSortIndex: [Card : Int] = {
blattCardOrder.enumerated().reduce(into: [:]) { $0[$1.element] = $1.offset }
}()
private let schellnSortIndex: [Card : Int] = {
schellnCardOrder.enumerated().reduce(into: [:]) { $0[$1.element] = $1.offset }
}()
private let wenzTrumps: [Card] = wenzCardOder[0..<4]
private let geierTrumps: [Card] = geierCardOrder[0..<4]
private let eichelTrumps: [Card] = eichelCardOrder[0..<8]
private let blattTrumps: [Card] = blattCardOrder[0..<8]
private let schellnTrumps: [Card] = schellnCardOrder[0..<8]
extension Card {
func isTrump(in game: GameType) -> Bool {
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]
}
}
}
extension Array where Element == Card {
func sorted(cardOrder order: CardOrder) -> [Card] {
switch order {
case .normal:
return sorted { normalSortIndex[$0]! < normalSortIndex[$1]! }
case .wenz:
return sorted { wenzSortIndex[$0]! < wenzSortIndex[$1]! }
case .geier:
return sorted { geierSortIndex[$0]! < geierSortIndex[$1]! }
case .soloEichel:
return sorted { eichelSortIndex[$0]! < eichelSortIndex[$1]! }
case .soloBlatt:
return sorted { blattSortIndex[$0]! < blattSortIndex[$1]! }
case .soloSchelln:
return sorted { schellnSortIndex[$0]! < schellnSortIndex[$1]! }
}
}
func consecutiveTrumps(for game: GameType) -> Int {
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 contains(trumpsInOrder[count]) {
count += 1
}
guard count >= 3 else {
return 0
}
return count
}
func trumpCount(for game: GameType) -> Int {
}
/**
Split cards into chunks to assign them to players.
- Note: The array must contain a multiple of the `size` parameter
*/
func split(intoChunksOf size: Int) -> [Hand] {
stride(from: 0, to: count, by: size).map { i in
Array(self[i..<i+4])
}
}
var canOfferWedding: Bool {
NormalCardOrder.trumpCount(self) == 1
}
}
struct Dealer {
/**
Creates a random assignment of 4 cards per 4 players for the initial round of doubling.
*/
static func dealFirstCards() -> [Hand] {
// Select 16 random cards for the first hands
Array(Card.allCards.shuffled()[0..<16])
.split(intoChunksOf: 4)
.map { $0.sorted(cardOrder: .normal) }
}
static func dealRemainingCards(of initial: [Hand]) -> [Hand] {
Card.allCards
.subtracting(initial.reduce([], +))
.shuffled()
.split(intoChunksOf: 4)
}
}