Structure sorting

This commit is contained in:
Christoph Hagen 2021-12-06 11:42:15 +01:00
parent 158a2ea03f
commit 50a35ece03
9 changed files with 317 additions and 55 deletions

View File

@ -0,0 +1,53 @@
import Foundation
typealias Trick = [Card]
typealias Hand = [Card]
extension Array where Element == Card {
var points: Int {
map { $0.points }
.reduce(0, +)
}
func highCardIndex(forGame game: GameType) -> Int {
game.sortingType.highCardIndex(cards: self)
}
func sortedCards(forGame game: GameType) -> [Card] {
sortedCards(order: game.sortingType)
}
func sortedCards(order: CardOrder.Type) -> [Card] {
order.sort(self)
}
func consecutiveTrumps(for game: GameType) -> Int {
game.sortingType.consecutiveTrumps(self)
}
func trumpCount(for game: GameType) -> Int {
game.sortingType.trumpCount(self)
}
func suitCount(_ suit: Card.Suit, in game: GameType) -> Int {
filter { card in
card.suit == suit && !game.sortingType.isTrump(card)
}.count
}
/**
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
}
}

View File

@ -1,37 +1,41 @@
//
// File.swift
//
//
// Created by iMac on 03.12.21.
//
import Foundation import Foundation
enum CardOrderType {
/// The sorting for most games, where heart is trump
case normal
case wenz
case geier
case soloEichel
case soloBlatt
case soloSchelln
}
protocol CardOrder { protocol CardOrder {
static var trumpOrder: [Card] { get } static var trumpCount: Int { get }
static var sortIndex: [Card : Int] { get } static var cardOrder: [Card] { get }
} }
extension CardOrder { 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..<trumpCount])
}
private static var trumps: Set<Card> { 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 { static func consecutiveTrumps(_ cards: [Card]) -> Int {
var count = 0 var count = 0
while cards.contains(trumpOrder[count]) { while cards.contains(trumpOrder[count]) {
@ -46,4 +50,20 @@ extension CardOrder {
static func sort(_ cards: [Card]) -> [Card] { static func sort(_ cards: [Card]) -> [Card] {
cards.sorted { sortIndex[$0]! < sortIndex[$1]! } 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 }
}
} }

View File

@ -0,0 +1,41 @@
import Foundation
struct GeierCardOrder: CardOrder {
static let trumpCount = 4
static let cardOrder = [
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)
]
}

View File

@ -1,15 +1,10 @@
//
// File.swift
//
//
// Created by iMac on 03.12.21.
//
import Foundation import Foundation
struct NormalCardOrder: CardOrder { struct NormalCardOrder: CardOrder {
private static let cardOrder = [ static let trumpCount = 14
static let cardOrder = [
Card(.eichel, .ober), Card(.eichel, .ober),
Card(.blatt, .ober), Card(.blatt, .ober),
Card(.herz, .ober), Card(.herz, .ober),
@ -41,18 +36,6 @@ struct NormalCardOrder: CardOrder {
Card(.schelln, .könig), Card(.schelln, .könig),
Card(.schelln, .neun), Card(.schelln, .neun),
Card(.schelln, .acht), Card(.schelln, .acht),
Card(.schelln, .sieben), Card(.schelln, .sieben)
] ]
private static let sortIndex: [Card : Int] = {
cardOrder.enumerated().reduce(into: [:]) { $0[$1.element] = $1.offset }
}()
static let trumpOrder: [Card] = Array(cardOrder[0..<8])
private static let trumps: Set<Card> = Set(trumpOrder)
static func trumpCount(_ cards: [Card]) -> Int {
cards.filter { trumps.contains(card) }.count
}
} }

View File

@ -0,0 +1,41 @@
import Foundation
struct SoloBlattCardOrder: CardOrder {
static let trumpCount = 14
static let cardOrder = [
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)
]
}

View File

@ -0,0 +1,41 @@
import Foundation
struct SoloEichelCardOrder: CardOrder {
static let trumpCount = 14
static let cardOrder = [
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)
]
}

View File

@ -0,0 +1,42 @@
import Foundation
struct SoloSchellnCardOrder: CardOrder {
static let trumpCount = 14
static let cardOrder = [
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)
]
}

View File

@ -0,0 +1,41 @@
import Foundation
struct WenzCardOrder: CardOrder {
static let trumpCount = 4
static let cardOrder = [
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)
]
}

View File

@ -59,20 +59,20 @@ enum GameType: Codable {
gameClass.cost gameClass.cost
} }
var sortingType: CardOrderType { var sortingType: CardOrder.Type {
switch self { switch self {
case .wenz: case .wenz:
return .wenz return WenzCardOrder.self
case .geier: case .geier:
return .geier return GeierCardOrder.self
case .soloEichel: case .soloEichel:
return .soloEichel return SoloEichelCardOrder.self
case .soloBlatt: case .soloBlatt:
return .soloBlatt return SoloBlattCardOrder.self
case .soloSchelln: case .soloSchelln:
return .soloSchelln return SoloSchellnCardOrder.self
default: default:
return .normal return NormalCardOrder.self
} }
} }
} }