Refactor tables and players for clarity
This commit is contained in:
26
Sources/App/Model/Players/AbstractPlayer.swift
Normal file
26
Sources/App/Model/Players/AbstractPlayer.swift
Normal file
@ -0,0 +1,26 @@
|
||||
import Foundation
|
||||
import WebSocketKit
|
||||
|
||||
class AbstractPlayer {
|
||||
|
||||
let name: PlayerName
|
||||
|
||||
var socket: WebSocket?
|
||||
|
||||
init(name: PlayerName, socket: WebSocket? = nil) {
|
||||
self.name = name
|
||||
self.socket = socket
|
||||
}
|
||||
|
||||
init(player: Player) {
|
||||
self.name = player.name
|
||||
self.socket = player.socket
|
||||
}
|
||||
}
|
||||
|
||||
extension AbstractPlayer: Equatable {
|
||||
|
||||
static func == (lhs: AbstractPlayer, rhs: AbstractPlayer) -> Bool {
|
||||
lhs.name == rhs.name
|
||||
}
|
||||
}
|
51
Sources/App/Model/Players/BiddingPlayer.swift
Normal file
51
Sources/App/Model/Players/BiddingPlayer.swift
Normal file
@ -0,0 +1,51 @@
|
||||
import Foundation
|
||||
import WebSocketKit
|
||||
|
||||
final class BiddingPlayer {
|
||||
|
||||
let name: String
|
||||
|
||||
var socket: WebSocket?
|
||||
|
||||
let cards: [PlayableCard]
|
||||
|
||||
var isStillBidding = true
|
||||
|
||||
var isAllowedToOfferWedding = true
|
||||
|
||||
var offersWedding = false
|
||||
|
||||
var wouldAcceptWedding = false
|
||||
|
||||
init(player: DealingPlayer, cards: [PlayableCard]) {
|
||||
self.name = player.name
|
||||
self.socket = player.socket
|
||||
self.cards = cards
|
||||
}
|
||||
}
|
||||
|
||||
extension BiddingPlayer: Player {
|
||||
|
||||
var canOfferWedding: Bool {
|
||||
rawCards.canOfferWedding
|
||||
}
|
||||
|
||||
var rawCards: [Card] {
|
||||
cards.map { $0.card }
|
||||
}
|
||||
|
||||
|
||||
var actions: [PlayerAction] {
|
||||
guard isStillBidding else {
|
||||
return []
|
||||
}
|
||||
guard canOfferWedding, isAllowedToOfferWedding, !offersWedding else {
|
||||
return [.increaseOrMatchGame, .withdrawFromAuction]
|
||||
}
|
||||
return [.increaseOrMatchGame, .withdrawFromAuction, .offerWedding]
|
||||
}
|
||||
|
||||
var playedCard: Card? {
|
||||
nil
|
||||
}
|
||||
}
|
24
Sources/App/Model/Players/DealingPlayer.swift
Normal file
24
Sources/App/Model/Players/DealingPlayer.swift
Normal file
@ -0,0 +1,24 @@
|
||||
import Foundation
|
||||
import WebSocketKit
|
||||
|
||||
final class DealingPlayer: AbstractPlayer {
|
||||
|
||||
var cards: [PlayableCard] = []
|
||||
|
||||
var didDouble: Bool? = nil
|
||||
|
||||
init(player: WaitingPlayer) {
|
||||
super.init(player: player)
|
||||
}
|
||||
}
|
||||
|
||||
extension DealingPlayer: Player {
|
||||
|
||||
var actions: [PlayerAction] {
|
||||
didDouble == nil ? [.initialDoubleCost, .noDoubleCost] : []
|
||||
}
|
||||
|
||||
var playedCard: Card? {
|
||||
nil
|
||||
}
|
||||
}
|
63
Sources/App/Model/Players/Player.swift
Normal file
63
Sources/App/Model/Players/Player.swift
Normal file
@ -0,0 +1,63 @@
|
||||
import Foundation
|
||||
import WebSocketKit
|
||||
|
||||
protocol Player: AnyObject {
|
||||
|
||||
var name: String { get }
|
||||
|
||||
var socket: WebSocket? { get set }
|
||||
|
||||
var playedCard: Card? { get }
|
||||
|
||||
var actions: [PlayerAction] { get }
|
||||
|
||||
var cards: [PlayableCard] { get }
|
||||
|
||||
}
|
||||
|
||||
extension Player {
|
||||
|
||||
// MARK: Connection
|
||||
|
||||
/// Indicate that the player is connected when at a table
|
||||
var isConnected: Bool {
|
||||
guard let socket = socket else {
|
||||
return false
|
||||
}
|
||||
guard !socket.isClosed else {
|
||||
self.socket = nil
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func connect(using socket: WebSocket) {
|
||||
_ = self.socket?.close()
|
||||
self.socket = socket
|
||||
}
|
||||
|
||||
func disconnect() -> Bool {
|
||||
guard let socket = socket else {
|
||||
return false
|
||||
}
|
||||
do {
|
||||
try socket.close().wait()
|
||||
} catch {
|
||||
print("Failed to close socket for player: \(name): \(error)")
|
||||
}
|
||||
self.socket = nil
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
func send(_ info: TableInfo) {
|
||||
try? socket?.send(encodeJSON(info))
|
||||
}
|
||||
|
||||
// MARK: Actions
|
||||
|
||||
func canPerform(_ action: PlayerAction) -> Bool {
|
||||
actions.contains(action)
|
||||
}
|
||||
|
||||
}
|
30
Sources/App/Model/Players/PlayingPlayer.swift
Normal file
30
Sources/App/Model/Players/PlayingPlayer.swift
Normal file
@ -0,0 +1,30 @@
|
||||
import Foundation
|
||||
import WebSocketKit
|
||||
|
||||
final class PlayingPlayer: AbstractPlayer {
|
||||
|
||||
var playedCard: Card? = nil
|
||||
|
||||
var cards: [PlayableCard]
|
||||
|
||||
var leadsGame = false
|
||||
|
||||
var canStillRaise = true
|
||||
|
||||
init(player: BiddingPlayer) {
|
||||
self.cards = player.cards
|
||||
super.init(player: player)
|
||||
}
|
||||
}
|
||||
|
||||
extension PlayingPlayer: Player {
|
||||
|
||||
|
||||
var actions: [PlayerAction] {
|
||||
guard canStillRaise, !leadsGame else {
|
||||
return []
|
||||
}
|
||||
return [.doubleDuringGame]
|
||||
}
|
||||
|
||||
}
|
22
Sources/App/Model/Players/WaitingPlayer.swift
Normal file
22
Sources/App/Model/Players/WaitingPlayer.swift
Normal file
@ -0,0 +1,22 @@
|
||||
import Foundation
|
||||
import WebSocketKit
|
||||
|
||||
final class WaitingPlayer: AbstractPlayer {
|
||||
|
||||
var canStartGame: Bool = false
|
||||
}
|
||||
|
||||
extension WaitingPlayer: Player {
|
||||
|
||||
var actions: [PlayerAction] {
|
||||
canStartGame ? [.deal] : []
|
||||
}
|
||||
|
||||
var cards: [PlayableCard] {
|
||||
[]
|
||||
}
|
||||
|
||||
var playedCard: Card? {
|
||||
nil
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user