Structure sorting
This commit is contained in:
parent
158a2ea03f
commit
50a35ece03
53
Sources/App/Model/Card/Card+Array.swift
Normal file
53
Sources/App/Model/Card/Card+Array.swift
Normal 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
|
||||||
|
}
|
||||||
|
}
|
@ -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 }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
41
Sources/App/Model/CardOrders/GeierCardOrder.swift
Normal file
41
Sources/App/Model/CardOrders/GeierCardOrder.swift
Normal 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)
|
||||||
|
]
|
||||||
|
}
|
@ -1,15 +1,10 @@
|
|||||||
//
|
|
||||||
// File.swift
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Created by iMac on 03.12.21.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
struct NormalCardOrder: CardOrder {
|
struct NormalCardOrder: CardOrder {
|
||||||
|
|
||||||
|
static let trumpCount = 14
|
||||||
|
|
||||||
private static let cardOrder = [
|
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
41
Sources/App/Model/CardOrders/SoloBlattCardOrder.swift
Normal file
41
Sources/App/Model/CardOrders/SoloBlattCardOrder.swift
Normal 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)
|
||||||
|
]
|
||||||
|
}
|
41
Sources/App/Model/CardOrders/SoloEichelCardOrder.swift
Normal file
41
Sources/App/Model/CardOrders/SoloEichelCardOrder.swift
Normal 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)
|
||||||
|
]
|
||||||
|
}
|
42
Sources/App/Model/CardOrders/SoloSchellnCardOrder.swift
Normal file
42
Sources/App/Model/CardOrders/SoloSchellnCardOrder.swift
Normal 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)
|
||||||
|
]
|
||||||
|
|
||||||
|
}
|
41
Sources/App/Model/CardOrders/WenzCardOrder.swift
Normal file
41
Sources/App/Model/CardOrders/WenzCardOrder.swift
Normal 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)
|
||||||
|
]
|
||||||
|
}
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user