124 lines
4.6 KiB
Swift
124 lines
4.6 KiB
Swift
import Foundation
|
|
|
|
final class WeddingTable: AbstractTable<WeddingPlayer> {
|
|
|
|
var indexOfWeddingOffer: Int
|
|
|
|
init(table: BiddingTable, offerer: BiddingPlayer) {
|
|
let players = table.players.map { WeddingPlayer(player: $0, offersWedding: $0 == offerer) }
|
|
indexOfWeddingOffer = table.players.index(of: offerer)
|
|
super.init(table: table, players: players)
|
|
}
|
|
|
|
var hasRemainingActors: Bool {
|
|
players.contains { $0.requiresAction }
|
|
}
|
|
|
|
var requiresCardSelection: Bool {
|
|
players.contains { $0.selectsGame }
|
|
}
|
|
|
|
override var playedGame: GameType? {
|
|
.hochzeit
|
|
}
|
|
|
|
override func perform(action: PlayerAction, forPlayer name: PlayerName) -> (result: PlayerActionResult, table: ManageableTable?) {
|
|
guard let player = players.player(named: name) else {
|
|
log("Player \(name) unexpectedly missing from wedding table \(self.name)")
|
|
return (.tableStateInvalid, nil)
|
|
}
|
|
guard player.canPerform(action) else {
|
|
return (.tableStateInvalid, nil)
|
|
}
|
|
|
|
switch action {
|
|
case .acceptWedding:
|
|
return performWeddingAccept(forPlayer: player)
|
|
case .withdrawFromAuction:
|
|
return performWithdrawl(forPlayer: player)
|
|
case .increaseOrMatchGame:
|
|
log("Unexpected action \(action) should not be possible")
|
|
fatalError()
|
|
default:
|
|
return (.tableStateInvalid, nil)
|
|
}
|
|
}
|
|
|
|
private func performWeddingAccept(forPlayer player: WeddingPlayer) -> (result: PlayerActionResult, table: ManageableTable?) {
|
|
guard player.requiresAction else {
|
|
return (.tableStateInvalid, nil)
|
|
}
|
|
player.state = .wouldAcceptWedding
|
|
guard !hasRemainingActors else {
|
|
return (.success, nil)
|
|
}
|
|
// Nobody wants to play a higher game, so let the first player accept the wedding
|
|
players.first { $0.wouldAcceptWedding }!.selectsGame = true
|
|
return (.success, nil)
|
|
}
|
|
|
|
private func performWithdrawl(forPlayer player: WeddingPlayer) -> (result: PlayerActionResult, table: ManageableTable?) {
|
|
guard player.requiresAction else {
|
|
return (.tableStateInvalid, nil)
|
|
}
|
|
player.state = .withdrawnFromAuction
|
|
guard !hasRemainingActors else {
|
|
return (.success, nil)
|
|
}
|
|
// Nobody wants to play a higher game, so let the first player accept the wedding
|
|
guard let player = players.first(where: { $0.wouldAcceptWedding }) else {
|
|
// Nobody wants to accept the wedding or play something higher, so abort the game
|
|
let table = WaitingTable(oldTableAdvancedByOne: self)
|
|
return (.success, table)
|
|
}
|
|
player.selectsGame = true
|
|
return (.success, nil)
|
|
}
|
|
|
|
private func performOutbid(forPlayer player: WeddingPlayer) -> (result: PlayerActionResult, table: ManageableTable?) {
|
|
guard player.requiresAction else {
|
|
return (.tableStateInvalid, nil)
|
|
}
|
|
let table = BiddingTable(wedding: self, outbidBy: player)
|
|
return (.success, table)
|
|
}
|
|
|
|
override func cards(forPlayerAt index: Int) -> [PlayableCard] {
|
|
let player = players[index]
|
|
guard requiresCardSelection, player.selectsGame else {
|
|
return player.cards.unplayable
|
|
}
|
|
return player.exchangeableCards
|
|
}
|
|
|
|
override func gameIsSelected(byPlayerAt index: Int) -> Bool {
|
|
players[index].selectsGame
|
|
}
|
|
|
|
override func play(card: Card, player name: PlayerName) -> (result: PlayerActionResult, table: ManageableTable?) {
|
|
guard requiresCardSelection else {
|
|
log("Wedding is not in stage where card should be selected")
|
|
return (.tableStateInvalid, nil)
|
|
}
|
|
guard let player = players.player(named: name) else {
|
|
log("Player \(name) unexpectedly missing from wedding table \(self.name)")
|
|
return (.tableStateInvalid, nil)
|
|
}
|
|
guard player.selectsGame else {
|
|
log("Player \(name) is not the one selecting a wedding card")
|
|
return (.tableStateInvalid, nil)
|
|
}
|
|
guard player.canExchange(card: card) else {
|
|
log("Invalid card \(card) to exchange in wedding")
|
|
return (.tableStateInvalid, nil)
|
|
}
|
|
|
|
let offerer = players[indexOfWeddingOffer]
|
|
let trumpCard = offerer.replaceWeddingCard(with: card)
|
|
player.replace(card, with: trumpCard)
|
|
let table = PlayingTable(wedding: self, offeredBy: offerer, acceptedBy: player)
|
|
return (.success, table)
|
|
}
|
|
|
|
}
|