Refactor table + player data, add state

This commit is contained in:
Christoph Hagen
2021-12-20 20:18:19 +01:00
parent 49787db1aa
commit 3a95e1c990
18 changed files with 261 additions and 169 deletions

View File

@@ -1,14 +1,12 @@
import Foundation
import WebSocketKit
final class BiddingPlayer: Player {
final class BiddingPlayer: CardHoldingPlayer {
var isStillBidding = true
var isAllowedToOfferWedding: Bool
var selectsGame = false
init(player: DealingPlayer) {
isAllowedToOfferWedding = true
super.init(player: player)
@@ -47,9 +45,18 @@ final class BiddingPlayer: Player {
return actions
}
override var points: Int? {
get { nil }
set { }
private var biddingState: [PlayerState] {
isStillBidding ? [] : [.didFold]
}
override var states: [PlayerState] {
var states = super.states
if !isStillBidding {
states.append(.didFold)
} else if isNextActor {
states.append(.mustBid)
}
return states
}
}

View File

@@ -0,0 +1,40 @@
import Foundation
class CardHoldingPlayer: Player {
var didDouble: Bool
var cards: [Card]
var selectsGame = false
override init(player: Player) {
self.cards = []
self.didDouble = false
super.init(player: player)
}
init(player: CardHoldingPlayer) {
self.cards = player.cards
self.didDouble = player.didDouble
self.selectsGame = player.selectsGame
super.init(player: player)
}
override var states: [PlayerState] {
var states = super.states
if didDouble {
states.append(.didDouble)
}
if selectsGame {
states.append(.isGameSelector)
}
return states
}
override var info: PlayerInfo {
var info = super.info
info.numberOfDoubles = didDouble ? 1 : 0
return info
}
}

View File

@@ -1,35 +1,28 @@
import Foundation
import WebSocketKit
final class DealingPlayer: Player {
final class DealingPlayer: CardHoldingPlayer {
var didDouble: Bool? = nil
override var isNextActor: Bool {
get { didDouble == nil }
set { }
}
var didDecide = false
override var actions: [PlayerAction] {
didDouble == nil ? [.initialDoubleCost, .noDoubleCost] : []
didDecide ? [] : [.initialDoubleCost, .noDoubleCost]
}
init(player: WaitingPlayer) {
super.init(player: player)
}
override var numberOfDoubles: Int {
get { didDouble == true ? 1 : 0 }
set { }
override var states: [PlayerState] {
var states = super.states
if !didDecide {
states.append(.canDouble)
}
return states
}
override var leadsGame: Bool {
get { false }
set { }
}
override var points: Int? {
get { nil }
override var isNextActor: Bool {
get { !didDecide }
set { }
}

View File

@@ -2,20 +2,32 @@ import Foundation
final class FinishedPlayer: Player {
let tricks: [Trick]
let points: Int
let leadsGame: Bool
let playedCard: Card
init(player: PlayingPlayer) {
self.tricks = player.wonTricks
self.points = player.wonTricks.map { $0.points }.reduce(0, +)
self.leadsGame = player.leadsGame
self.playedCard = player.playedCard!
super.init(player: player)
}
override var points: Int? {
get { tricks.map { $0.points }.reduce(0, +) }
set { }
}
override var actions: [PlayerAction] {
[.deal]
}
override var states: [PlayerState] {
super.states + [] // TODO: Finish
}
override var info: PlayerInfo {
var result = super.info
result.points = points
result.playedCard = playedCard.id
return result
}
}

View File

@@ -7,44 +7,35 @@ class Player {
var socket: WebSocket?
var playedCard: Card?
var isNextActor: Bool
var cards: [Card]
var numberOfDoubles: Int
var leadsGame: Bool
var points: Int?
init(name: PlayerName, socket: WebSocket? = nil) {
self.name = name
self.socket = socket
self.cards = []
self.isNextActor = false
self.playedCard = nil
self.numberOfDoubles = 0
self.leadsGame = false
self.points = nil
}
init(player: Player) {
self.name = player.name
self.socket = player.socket
self.cards = player.cards
self.isNextActor = false
self.playedCard = player.playedCard
self.numberOfDoubles = player.numberOfDoubles
self.leadsGame = player.leadsGame
self.points = player.points
}
var actions: [PlayerAction] {
[]
}
var states: [PlayerState] {
isConnected ? [] : [.isDisconnected]
}
var info: PlayerInfo {
var result = PlayerInfo(name: name)
result.isConnected = isConnected
result.isNextActor = isNextActor
result.state = states.map { $0.rawValue }
return result
}
}
extension Player: Equatable {

View File

@@ -7,18 +7,26 @@ import WebSocketKit
*/
private let numberOfCardsToProtectAce = 4
final class PlayingPlayer: Player {
final class PlayingPlayer: CardHoldingPlayer {
var canStillRaise = true
var isCalledWithAce: Card?
var didPlayCalledAce = false
var playedCard: Card?
var leadsGame: Bool
var numberOfDoubles = 0
/// All tricks won by the player in this game
var wonTricks: [Trick] = []
init(player: Player, leads: Bool, calledAce ace: Card?) {
super.init(player: player)
init(player: CardHoldingPlayer, leads: Bool, calledAce ace: Card?) {
leadsGame = leads
super.init(player: player)
if let ace = ace, cards.contains(ace) {
isCalledWithAce = ace
} else {
@@ -26,8 +34,19 @@ final class PlayingPlayer: Player {
}
}
private var isUnknownCallee: Bool {
isCalledWithAce != nil && !didPlayCalledAce
}
override var actions: [PlayerAction] {
guard canStillRaise, leadsGame == (isCalledWithAce != nil) else {
guard canStillRaise else {
return []
}
if isUnknownCallee && leadsGame {
// Player belongs to caller, but other side has raised
return [.doubleDuringGame]
}
guard !leadsGame else {
return []
}
return [.doubleDuringGame]
@@ -38,7 +57,7 @@ final class PlayingPlayer: Player {
cards = cards.filter { $0 != card }
if card == isCalledWithAce {
leadsGame.toggle()
isCalledWithAce = nil
didPlayCalledAce = true
}
}
@@ -136,4 +155,24 @@ final class PlayingPlayer: Player {
var currentPoints: Int {
wonTricks.map { $0.points }.reduce(0, +)
}
override var states: [PlayerState] {
var states = super.states
if didPlayCalledAce {
states.append(.isCalled)
}
if leadsGame {
states.append(.leadsGame)
}
if numberOfDoubles > 0 {
states.append(.didRaise)
}
return states
}
override var info: PlayerInfo {
var info = super.info
info.playedCard = playedCard?.id
return info
}
}

View File

@@ -8,15 +8,4 @@ final class WaitingPlayer: Player {
override var actions: [PlayerAction] {
canStartGame ? [.deal] : []
}
override var leadsGame: Bool {
get { false }
set { }
}
override var points: Int? {
get { nil }
set { }
}
}

View File

@@ -1,6 +1,6 @@
import Foundation
final class WeddingPlayer: Player {
final class WeddingPlayer: CardHoldingPlayer {
enum State {
case requiresAction
@@ -16,7 +16,7 @@ final class WeddingPlayer: Player {
state == .requiresAction
}
var selectsGame: Bool {
override var selectsGame: Bool {
get {
state == .selectsGame
}
@@ -38,6 +38,14 @@ final class WeddingPlayer: Player {
super.init(player: player)
}
override var states: [PlayerState] {
var states = super.states
if offersWedding {
states.append(.isWeddingOfferer)
}
return states
}
override var actions: [PlayerAction] {
guard state == .requiresAction else {
return []
@@ -57,16 +65,6 @@ final class WeddingPlayer: Player {
set { }
}
override var points: Int? {
get { nil }
set { }
}
override var leadsGame: Bool {
get { offersWedding || selectsGame }
set { }
}
func canExchange(card: Card) -> Bool {
cards.filter { !$0.isTrump(in: .hochzeit) }.contains(card)
}
@@ -86,4 +84,10 @@ final class WeddingPlayer: Player {
func replace(_ card: Card, with trumpCard: Card) {
cards = (cards.filter { $0 != card } + [trumpCard]).sortedCards(forGame: .hochzeit)
}
override var info: PlayerInfo {
var info = super.info
info.leadsGame = offersWedding || selectsGame
return info
}
}