Schafkopf-Server/Sources/App/Model/Tables/FinishedTable.swift
2021-12-22 15:06:24 +01:00

141 lines
4.1 KiB
Swift

import Foundation
final class FinishedTable: AbstractTable<FinishedPlayer> {
let game: GameType
let totalNumberOfDoubles: Int
let leadingTrumps: Int
/// Required for the last cards on the table
let indexOfTrickStarter: Int
var cost: Int {
guard !isBettel else {
return game.basicCost * 2^^totalNumberOfDoubles
}
var cost = game.basicCost
if isSchwarz {
cost += 10
} else if isSchneider {
cost += 5
}
cost += 5 * leadingTrumps
guard game != .hochzeit else {
// Wedding is doubled
return cost * 2^^(totalNumberOfDoubles + 1)
}
return cost * 2^^totalNumberOfDoubles
}
var gameSelector: FinishedPlayer {
players.first { $0.selectedGame }!
}
let selectorDidWin: Bool
var coPlayers: [FinishedPlayer] {
let selector = gameSelector
return players.filter { $0 != selector && $0.leadsGame == selector.leadsGame }
}
var winners: [FinishedPlayer] {
let selectorLeads = gameSelector.leadsGame
return players.filter { $0.leadsGame == (selectorDidWin == selectorLeads) }
}
var selectorTeamPoints: Int {
gameSelector.points + coPlayers.map { $0.points }.reduce(0, +)
}
var isBettel: Bool {
game == .bettel
}
var isHochzeit: Bool {
game == .hochzeit
}
var isSchwarz: Bool {
!isBettel && (selectorTeamPoints == 0 || selectorTeamPoints == 120)
}
var isSchneider: Bool {
guard !isBettel else {
return false
}
let points = selectorTeamPoints
let leads = gameSelector.leadsGame
let limit = leads ? 31 : 30
return points < limit || 120 - points < limit
}
override var playedGame: GameType? {
game
}
init(table: PlayingTable) {
let players = table.players.map(FinishedPlayer.init)
let selector = table.players.first { $0.selectsGame }!
self.game = table.game
self.totalNumberOfDoubles = table.totalNumberOfDoubles
self.indexOfTrickStarter = table.indexOfTrickStarter
defer {
for player in winners {
player.isNextActor = true
}
}
guard table.game != .bettel else {
self.selectorDidWin = selector.wonTricks.isEmpty
self.leadingTrumps = 0
super.init(table: table, players: players)
return
}
let selectorLeads = selector.leadsGame
let teamPoints = players
.filter { $0.leadsGame == selectorLeads }
.map { $0.points }
.reduce(0, +)
self.selectorDidWin = teamPoints > (selectorLeads ? 60 : 59)
self.leadingTrumps = table.leadingTrumps
super.init(table: table, players: players)
}
/**
Perform a deal action on the finished table.
- Parameter action: The action to perform
- Parameter player: The name of the player
*/
override func perform(action: PlayerAction, forPlayer name: PlayerName) -> (result: PlayerActionResult, table: ManageableTable?) {
// Only dealing is allowed...
guard action == .deal else {
return (.tableStateInvalid, nil)
}
guard let player = players.player(named: name) else {
print("Unexpectedly missing player \(name) for deal action at finished table \(self.name)")
return (.tableStateInvalid, nil)
}
guard player.canPerform(.deal) else {
print("Finished table: Player \(name) can't perform deal")
return (.tableStateInvalid, nil)
}
let waiting = WaitingTable(oldTableAdvancedByOne: self)
let table = DealingTable(table: waiting)
return (.success, table)
}
override func tableInfo(forPlayerAt index: Int) -> TableInfo {
var info = super.tableInfo(forPlayerAt: index)
info.summary = GameSummary(table: self, language: language)
return info
}
override func cardStackPosition(ofPlayerAt index: Int) -> Int {
(4 + index - indexOfTrickStarter) % 4
}
}