Refactor player action
This commit is contained in:
parent
a2c2893499
commit
33f72c43cf
@ -13,7 +13,7 @@ private let numberOfCardsToProtectAce = 4
|
|||||||
let numberOfCardsPerPlayer = 8
|
let numberOfCardsPerPlayer = 8
|
||||||
|
|
||||||
|
|
||||||
final class Player {
|
final class OldPlayer {
|
||||||
|
|
||||||
let name: PlayerName
|
let name: PlayerName
|
||||||
|
|
||||||
@ -28,9 +28,12 @@ final class Player {
|
|||||||
|
|
||||||
/// The players plays/played the first card for the current trick
|
/// The players plays/played the first card for the current trick
|
||||||
var startedCurrentTrick = false
|
var startedCurrentTrick = false
|
||||||
|
|
||||||
|
/// Indicate the currently highest bidder during bidding
|
||||||
|
var isHighestBidder = false
|
||||||
|
|
||||||
/// The action available to the player
|
/// The action available to the player
|
||||||
var actions: [Action] = []
|
var actions: [PlayerAction] = []
|
||||||
|
|
||||||
/// Indicates if the player doubled ("legen")
|
/// Indicates if the player doubled ("legen")
|
||||||
var didDoubleAfterFourCards: Bool? = nil
|
var didDoubleAfterFourCards: Bool? = nil
|
||||||
@ -111,7 +114,7 @@ final class Player {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func canPerform(_ action: Action) -> Bool {
|
func canPerform(_ action: PlayerAction) -> Bool {
|
||||||
actions.contains(action)
|
actions.contains(action)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,6 +127,7 @@ final class Player {
|
|||||||
didDoubleAfterFourCards = nil
|
didDoubleAfterFourCards = nil
|
||||||
isStillBidding = true
|
isStillBidding = true
|
||||||
isGameLeader = false
|
isGameLeader = false
|
||||||
|
isHighestBidder = false
|
||||||
handCards = []
|
handCards = []
|
||||||
playedCard = nil
|
playedCard = nil
|
||||||
wonTricks = []
|
wonTricks = []
|
||||||
@ -184,6 +188,7 @@ final class Player {
|
|||||||
|
|
||||||
func didPerformBid() {
|
func didPerformBid() {
|
||||||
isNextActor = false
|
isNextActor = false
|
||||||
|
isHighestBidder = true
|
||||||
actions = []
|
actions = []
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,6 +216,7 @@ final class Player {
|
|||||||
func auctionEnded() {
|
func auctionEnded() {
|
||||||
actions = []
|
actions = []
|
||||||
isStillBidding = false
|
isStillBidding = false
|
||||||
|
isHighestBidder = false
|
||||||
isNextActor = false
|
isNextActor = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,13 +453,9 @@ final class Player {
|
|||||||
handCards[i].isPlayable = playable
|
handCards[i].isPlayable = playable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func info(masked: Bool, positionInTrick: Int) -> PlayerInfo {
|
|
||||||
.init(player: self, isMasked: masked, trickPosition: positionInTrick)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Player {
|
extension OldPlayer {
|
||||||
|
|
||||||
/// Indicate that the player is connected when at a table
|
/// Indicate that the player is connected when at a table
|
||||||
var isConnected: Bool {
|
var isConnected: Bool {
|
||||||
@ -468,9 +470,9 @@ extension Player {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Player: Equatable {
|
extension OldPlayer: Equatable {
|
||||||
|
|
||||||
static func == (lhs: Player, rhs: Player) -> Bool {
|
static func == (lhs: OldPlayer, rhs: OldPlayer) -> Bool {
|
||||||
lhs.name == rhs.name
|
lhs.name == rhs.name
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,7 +8,7 @@ private extension Int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class Table {
|
final class OldTable {
|
||||||
|
|
||||||
let id: TableId
|
let id: TableId
|
||||||
|
|
||||||
@ -16,13 +16,13 @@ final class Table {
|
|||||||
|
|
||||||
let isPublic: Bool
|
let isPublic: Bool
|
||||||
|
|
||||||
var players: [Player] = []
|
var players: [OldPlayer] = []
|
||||||
|
|
||||||
var phase: GamePhase = .waitingForPlayers
|
var phase: GamePhase = .waitingForPlayers
|
||||||
|
|
||||||
var gameType: GameType? = nil
|
var gameType: GameType? = nil
|
||||||
|
|
||||||
var minimumPlayableGame: GameType.GameClass?
|
var minimumPlayableGame: GameType.GameClass = .none
|
||||||
|
|
||||||
/// Indicates if any player doubled during the current round, extending it to the next round
|
/// Indicates if any player doubled during the current round, extending it to the next round
|
||||||
var didDoubleInCurrentRound = false
|
var didDoubleInCurrentRound = false
|
||||||
@ -53,7 +53,7 @@ final class Table {
|
|||||||
players.filter { $0.isStillBidding }.count
|
players.filter { $0.isStillBidding }.count
|
||||||
}
|
}
|
||||||
|
|
||||||
var auctionWinner: Player {
|
var auctionWinner: OldPlayer {
|
||||||
players.first { $0.isStillBidding }!
|
players.first { $0.isStillBidding }!
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ final class Table {
|
|||||||
guard !isFull else {
|
guard !isFull else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
let player = Player(name: player)
|
let player = OldPlayer(name: player)
|
||||||
players.append(player)
|
players.append(player)
|
||||||
if isFull {
|
if isFull {
|
||||||
prepareTableForFirstGame()
|
prepareTableForFirstGame()
|
||||||
@ -107,54 +107,36 @@ final class Table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The player to play the first card of the current game
|
/// The player to play the first card of the current game
|
||||||
var firstPlayer: Player {
|
var firstPlayer: OldPlayer {
|
||||||
players.first { $0.playsFirstCard }!
|
players.first { $0.playsFirstCard }!
|
||||||
}
|
}
|
||||||
|
|
||||||
func select(player: PlayerName) -> Player? {
|
func select(player: PlayerName) -> OldPlayer? {
|
||||||
players.first { $0.name == player }
|
players.first { $0.name == player }
|
||||||
}
|
}
|
||||||
|
|
||||||
var indexOfTrickStarter: Int {
|
var indexOfTrickStarter: Int {
|
||||||
players.firstIndex { $0.startedCurrentTrick }!
|
players.firstIndex { $0.startedCurrentTrick }!
|
||||||
}
|
}
|
||||||
|
|
||||||
func playerInfo(at index: Int, masked: Bool) -> PlayerInfo? {
|
|
||||||
let starter = indexOfTrickStarter
|
|
||||||
let layer = (4 - starter + index) % 4
|
|
||||||
return player(at: index)?.info(masked: masked, positionInTrick: layer)
|
|
||||||
}
|
|
||||||
|
|
||||||
func playerInfo(leftOf index: Int, masked: Bool) -> PlayerInfo? {
|
func player(at index: Int) -> OldPlayer? {
|
||||||
playerInfo(at: (index + 1) % 4, masked: masked)
|
|
||||||
}
|
|
||||||
|
|
||||||
func playerInfo(acrossOf index: Int, masked: Bool) -> PlayerInfo? {
|
|
||||||
playerInfo(at: (index + 2) % 4, masked: masked)
|
|
||||||
}
|
|
||||||
|
|
||||||
func playerInfo(rightOf index: Int, masked: Bool) -> PlayerInfo? {
|
|
||||||
playerInfo(at: (index + 3) % 4, masked: masked)
|
|
||||||
}
|
|
||||||
|
|
||||||
func player(at index: Int) -> Player? {
|
|
||||||
guard index < players.count else {
|
guard index < players.count else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return players[index]
|
return players[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
func index(of player: Player) -> Int {
|
func index(of player: OldPlayer) -> Int {
|
||||||
players.firstIndex(of: player)!
|
players.firstIndex(of: player)!
|
||||||
}
|
}
|
||||||
|
|
||||||
func nextPlayer(after player: Player) -> Player {
|
func nextPlayer(after player: OldPlayer) -> OldPlayer {
|
||||||
let i = index(of: player)
|
let i = index(of: player)
|
||||||
let newIndex = (i + 1) % maximumPlayersPerTable
|
let newIndex = (i + 1) % maximumPlayersPerTable
|
||||||
return players[newIndex]
|
return players[newIndex]
|
||||||
}
|
}
|
||||||
|
|
||||||
func nextBidder(after player: Player) -> Player {
|
func nextBidder(after player: OldPlayer) -> OldPlayer {
|
||||||
// Find next player to place bid
|
// Find next player to place bid
|
||||||
let index = index(of: player)
|
let index = index(of: player)
|
||||||
for i in 1..<4 {
|
for i in 1..<4 {
|
||||||
@ -166,6 +148,11 @@ final class Table {
|
|||||||
}
|
}
|
||||||
return player
|
return player
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func availableGames(forPlayerAt index: Int) -> [GameType] {
|
||||||
|
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
func remove(player: PlayerName) {
|
func remove(player: PlayerName) {
|
||||||
guard let index = players.firstIndex(where: { $0.name == player }) else {
|
guard let index = players.firstIndex(where: { $0.name == player }) else {
|
||||||
@ -202,7 +189,7 @@ final class Table {
|
|||||||
private func prepareTableForFirstGame() {
|
private func prepareTableForFirstGame() {
|
||||||
phase = .waitingForPlayers
|
phase = .waitingForPlayers
|
||||||
gameType = nil
|
gameType = nil
|
||||||
minimumPlayableGame = nil // Not relevant in this phase
|
minimumPlayableGame = .none // Not relevant in this phase
|
||||||
didDoubleInCurrentRound = false // Not relevant in this phase
|
didDoubleInCurrentRound = false // Not relevant in this phase
|
||||||
let index = players.firstIndex { $0.playsFirstCard } ?? 0
|
let index = players.firstIndex { $0.playsFirstCard } ?? 0
|
||||||
for i in 0..<maximumPlayersPerTable {
|
for i in 0..<maximumPlayersPerTable {
|
||||||
@ -211,13 +198,7 @@ final class Table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func sendUpdateToAllPlayers() {
|
private func sendUpdateToAllPlayers() {
|
||||||
players.enumerated().forEach { playerIndex, player in
|
|
||||||
guard player.isConnected else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let info = TableInfo(self, forPlayerAt: playerIndex)
|
|
||||||
player.send(info)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Player actions
|
// MARK: Player actions
|
||||||
@ -285,7 +266,7 @@ final class Table {
|
|||||||
didDoubleInCurrentRound = false
|
didDoubleInCurrentRound = false
|
||||||
}
|
}
|
||||||
|
|
||||||
func perform(action: Player.Action, forPlayer player: PlayerName) -> PlayerActionResult {
|
func perform(action: PlayerAction, forPlayer player: PlayerName) -> PlayerActionResult {
|
||||||
let player = select(player: player)!
|
let player = select(player: player)!
|
||||||
guard player.canPerform(action) else {
|
guard player.canPerform(action) else {
|
||||||
print("Player \(player) wants to \(action.path), but only allowed: \(player.actions)")
|
print("Player \(player) wants to \(action.path), but only allowed: \(player.actions)")
|
||||||
@ -332,7 +313,7 @@ final class Table {
|
|||||||
return .success
|
return .success
|
||||||
}
|
}
|
||||||
|
|
||||||
func perform(double: Bool, forPlayer player: Player) -> PlayerActionResult {
|
func perform(double: Bool, forPlayer player: OldPlayer) -> PlayerActionResult {
|
||||||
player.didDouble(double)
|
player.didDouble(double)
|
||||||
guard allPlayersFinishedDoubling else {
|
guard allPlayersFinishedDoubling else {
|
||||||
return .success
|
return .success
|
||||||
@ -351,17 +332,17 @@ final class Table {
|
|||||||
player.assignRemainingCards(cards[index])
|
player.assignRemainingCards(cards[index])
|
||||||
}
|
}
|
||||||
players.forEach { $0.startAuction() }
|
players.forEach { $0.startAuction() }
|
||||||
minimumPlayableGame = nil
|
minimumPlayableGame = .none
|
||||||
phase = .bidding
|
phase = .bidding
|
||||||
}
|
}
|
||||||
|
|
||||||
private func performWeddingCall(forPlayer player: Player) -> PlayerActionResult {
|
private func performWeddingCall(forPlayer player: OldPlayer) -> PlayerActionResult {
|
||||||
guard phase == .bidding else {
|
guard phase == .bidding else {
|
||||||
print("Invalid phase \(phase) for wedding call")
|
print("Invalid phase \(phase) for wedding call")
|
||||||
return .tableStateInvalid
|
return .tableStateInvalid
|
||||||
}
|
}
|
||||||
guard minimumPlayableGame == nil || minimumPlayableGame == .ruf else {
|
guard minimumPlayableGame.allowsWedding else {
|
||||||
print("Invalid minimum game \(minimumPlayableGame!) for wedding call")
|
print("Invalid minimum game \(minimumPlayableGame) for wedding call")
|
||||||
return .tableStateInvalid
|
return .tableStateInvalid
|
||||||
}
|
}
|
||||||
guard player.canOfferWedding else {
|
guard player.canOfferWedding else {
|
||||||
@ -381,7 +362,7 @@ final class Table {
|
|||||||
return .success
|
return .success
|
||||||
}
|
}
|
||||||
|
|
||||||
private func performBidIncrease(forPlayer player: Player) -> PlayerActionResult {
|
private func performBidIncrease(forPlayer player: OldPlayer) -> PlayerActionResult {
|
||||||
guard phase == .bidding else {
|
guard phase == .bidding else {
|
||||||
return .tableStateInvalid
|
return .tableStateInvalid
|
||||||
}
|
}
|
||||||
@ -392,37 +373,41 @@ final class Table {
|
|||||||
guard player.isNextActor else {
|
guard player.isNextActor else {
|
||||||
return .tableStateInvalid
|
return .tableStateInvalid
|
||||||
}
|
}
|
||||||
if minimumPlayableGame == nil {
|
// TODO: Check if new player sits before old player
|
||||||
minimumPlayableGame = .ruf
|
// then don't increase game
|
||||||
} else {
|
minimumPlayableGame.increase()
|
||||||
minimumPlayableGame!.increase()
|
if !minimumPlayableGame.allowsWedding {
|
||||||
// Remove wedding offers
|
// Remove wedding offers
|
||||||
players.forEach { $0.weddingOutbid() }
|
players.forEach { $0.weddingOutbid() }
|
||||||
}
|
}
|
||||||
|
#warning("Fix bidding")
|
||||||
|
// TODO: Remove highest bidder from old player
|
||||||
player.didPerformBid()
|
player.didPerformBid()
|
||||||
|
|
||||||
if numberOfRemainingBidders == 1 {
|
if numberOfRemainingBidders == 1 {
|
||||||
selectGame(player: player)
|
selectGame(player: player)
|
||||||
|
return .success
|
||||||
}
|
}
|
||||||
// Find next player to place bid
|
// Find next player to place bid
|
||||||
nextBidder(after: player).requiresBid(hasWedding: false)
|
nextBidder(after: player).requiresBid(hasWedding: false)
|
||||||
return .success
|
return .success
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleWeddingOutbid(forPlayer player: Player) -> PlayerActionResult {
|
private func handleWeddingOutbid(forPlayer player: OldPlayer) -> PlayerActionResult {
|
||||||
if player.offersWedding {
|
if player.offersWedding {
|
||||||
// A player offering a wedding can't outbid itself
|
// A player offering a wedding can't outbid itself
|
||||||
return .tableStateInvalid
|
return .tableStateInvalid
|
||||||
}
|
}
|
||||||
players.forEach { $0.weddingOutbid() }
|
players.forEach { $0.weddingOutbid() }
|
||||||
nextBidder(after: player).requiresBid(hasWedding: true)
|
nextBidder(after: player).requiresBid(hasWedding: false)
|
||||||
return .success
|
return .success
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleWeddingAccept(forPlayer player: Player) -> PlayerActionResult {
|
private func handleWeddingAccept(forPlayer player: OldPlayer) -> PlayerActionResult {
|
||||||
guard phase == .bidding else {
|
guard phase == .bidding else {
|
||||||
return .tableStateInvalid
|
return .tableStateInvalid
|
||||||
}
|
}
|
||||||
guard minimumPlayableGame == nil || minimumPlayableGame == .ruf else {
|
guard minimumPlayableGame.allowsWedding else {
|
||||||
return .tableStateInvalid
|
return .tableStateInvalid
|
||||||
}
|
}
|
||||||
guard weddingOfferExists else {
|
guard weddingOfferExists else {
|
||||||
@ -450,19 +435,19 @@ final class Table {
|
|||||||
return .success
|
return .success
|
||||||
}
|
}
|
||||||
|
|
||||||
private func selectedWedding(player: Player) {
|
private func selectedWedding(player: OldPlayer) {
|
||||||
minimumPlayableGame = nil
|
minimumPlayableGame = .none
|
||||||
gameType = .hochzeit
|
gameType = .hochzeit
|
||||||
phase = .selectWeddingCard
|
phase = .selectWeddingCard
|
||||||
players.forEach { $0.auctionEnded() }
|
players.forEach { $0.auctionEnded() }
|
||||||
player.mustSelectWeddingCard()
|
player.mustSelectWeddingCard()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func selectedCardForWedding(card: Card, player: Player) -> PlayCardResult {
|
private func selectedCardForWedding(card: Card, player: OldPlayer) -> PlayCardResult {
|
||||||
guard player.isNextActor,
|
guard player.isNextActor,
|
||||||
player.wouldAcceptWedding,
|
player.wouldAcceptWedding,
|
||||||
weddingOfferExists else {
|
weddingOfferExists else {
|
||||||
return .invalidTableState
|
return .tableStateInvalid
|
||||||
}
|
}
|
||||||
guard !card.isTrump(in: .hochzeit),
|
guard !card.isTrump(in: .hochzeit),
|
||||||
player.has(card: card) else {
|
player.has(card: card) else {
|
||||||
@ -481,7 +466,7 @@ final class Table {
|
|||||||
return .success
|
return .success
|
||||||
}
|
}
|
||||||
|
|
||||||
private func performWithdrawl(forPlayer player: Player) -> PlayerActionResult {
|
private func performWithdrawl(forPlayer player: OldPlayer) -> PlayerActionResult {
|
||||||
guard phase == .bidding,
|
guard phase == .bidding,
|
||||||
player.isNextActor,
|
player.isNextActor,
|
||||||
player.isStillBidding else {
|
player.isStillBidding else {
|
||||||
@ -490,7 +475,7 @@ final class Table {
|
|||||||
player.withdrawFromBidding()
|
player.withdrawFromBidding()
|
||||||
switch numberOfRemainingBidders {
|
switch numberOfRemainingBidders {
|
||||||
case 1:
|
case 1:
|
||||||
if minimumPlayableGame != nil {
|
if minimumPlayableGame != .none {
|
||||||
// Will only be called when at least one player placed a bid
|
// Will only be called when at least one player placed a bid
|
||||||
selectGame(player: auctionWinner)
|
selectGame(player: auctionWinner)
|
||||||
return .success
|
return .success
|
||||||
@ -515,7 +500,7 @@ final class Table {
|
|||||||
prepareTableForFirstGame()
|
prepareTableForFirstGame()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func selectGame(player: Player) {
|
private func selectGame(player: OldPlayer) {
|
||||||
gameType = nil
|
gameType = nil
|
||||||
phase = .selectGame
|
phase = .selectGame
|
||||||
players.forEach { $0.auctionEnded() }
|
players.forEach { $0.auctionEnded() }
|
||||||
@ -527,14 +512,14 @@ final class Table {
|
|||||||
guard phase == .selectGame, player.selectsGame, game != .hochzeit else {
|
guard phase == .selectGame, player.selectsGame, game != .hochzeit else {
|
||||||
return .tableStateInvalid
|
return .tableStateInvalid
|
||||||
}
|
}
|
||||||
guard minimumPlayableGame == nil || game.gameClass >= minimumPlayableGame! else {
|
guard game.gameClass >= minimumPlayableGame else {
|
||||||
return .tableStateInvalid
|
return .tableStateInvalid
|
||||||
}
|
}
|
||||||
defer { sendUpdateToAllPlayers() }
|
defer { sendUpdateToAllPlayers() }
|
||||||
guard let suit = game.calledSuit else {
|
guard let suit = game.calledSuit else {
|
||||||
phase = .playing
|
phase = .playing
|
||||||
gameType = game
|
gameType = game
|
||||||
minimumPlayableGame = nil
|
minimumPlayableGame = .none
|
||||||
players.forEach { $0.start(game: game) }
|
players.forEach { $0.start(game: game) }
|
||||||
player.switchLeadership()
|
player.switchLeadership()
|
||||||
|
|
||||||
@ -546,7 +531,7 @@ final class Table {
|
|||||||
}
|
}
|
||||||
phase = .playing
|
phase = .playing
|
||||||
gameType = game
|
gameType = game
|
||||||
minimumPlayableGame = nil
|
minimumPlayableGame = .none
|
||||||
players.forEach { $0.start(game: game) }
|
players.forEach { $0.start(game: game) }
|
||||||
player.switchLeadership()
|
player.switchLeadership()
|
||||||
// Find called player
|
// Find called player
|
||||||
@ -555,7 +540,7 @@ final class Table {
|
|||||||
return .success
|
return .success
|
||||||
}
|
}
|
||||||
|
|
||||||
private func performDoubleDuringGame(forPlayer player: Player) -> PlayerActionResult {
|
private func performDoubleDuringGame(forPlayer player: OldPlayer) -> PlayerActionResult {
|
||||||
guard phase == .playing, !player.isGameLeader else {
|
guard phase == .playing, !player.isGameLeader else {
|
||||||
return .tableStateInvalid
|
return .tableStateInvalid
|
||||||
}
|
}
|
||||||
@ -568,14 +553,14 @@ final class Table {
|
|||||||
private func reset() {
|
private func reset() {
|
||||||
phase = .waitingForPlayers
|
phase = .waitingForPlayers
|
||||||
gameType = nil
|
gameType = nil
|
||||||
minimumPlayableGame = nil
|
minimumPlayableGame = .none
|
||||||
for player in players {
|
for player in players {
|
||||||
player.prepareForNewGame(isFirstPlayer: player.playsFirstCard)
|
player.prepareForNewGame(isFirstPlayer: player.playsFirstCard)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Table {
|
extension OldTable {
|
||||||
|
|
||||||
var isFull: Bool {
|
var isFull: Bool {
|
||||||
players.count == maximumPlayersPerTable
|
players.count == maximumPlayersPerTable
|
||||||
@ -588,12 +573,5 @@ extension Table {
|
|||||||
var playerNames: [PlayerName] {
|
var playerNames: [PlayerName] {
|
||||||
players.map { $0.name }
|
players.map { $0.name }
|
||||||
}
|
}
|
||||||
|
|
||||||
func compileInfo(for player: PlayerName) -> TableInfo? {
|
|
||||||
guard let index = players.firstIndex(where: { $0.name == player }) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return TableInfo(self, forPlayerAt: index)
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,35 +1,32 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension Player {
|
enum PlayerAction: String, Codable {
|
||||||
|
/// The player can request cards to be dealt
|
||||||
|
case deal = "deal"
|
||||||
|
|
||||||
enum Action: String, Codable {
|
/// The player doubles on the initial four cards
|
||||||
/// The player can request cards to be dealt
|
case initialDoubleCost = "double"
|
||||||
case deal = "deal"
|
|
||||||
|
|
||||||
/// The player doubles on the initial four cards
|
/// The player does not double on the initial four cards
|
||||||
case initialDoubleCost = "double"
|
case noDoubleCost = "skip"
|
||||||
|
|
||||||
/// The player does not double on the initial four cards
|
/// The player offers a wedding (one trump card)
|
||||||
case noDoubleCost = "skip"
|
case offerWedding = "wedding"
|
||||||
|
|
||||||
/// The player offers a wedding (one trump card)
|
/// The player can choose to accept the wedding
|
||||||
case offerWedding = "wedding"
|
case acceptWedding = "accept"
|
||||||
|
|
||||||
/// The player can choose to accept the wedding
|
/// The player matches or increases the game during auction
|
||||||
case acceptWedding = "accept"
|
case increaseOrMatchGame = "bid"
|
||||||
|
|
||||||
/// The player matches or increases the game during auction
|
/// The player does not want to play
|
||||||
case increaseOrMatchGame = "bid"
|
case withdrawFromAuction = "out"
|
||||||
|
|
||||||
/// The player does not want to play
|
/// The player claims to win and doubles the game cost ("schießen")
|
||||||
case withdrawFromAuction = "out"
|
case doubleDuringGame = "raise"
|
||||||
|
|
||||||
/// The player claims to win and doubles the game cost ("schießen")
|
/// The url path for the client to call (e.g. /player/deal)
|
||||||
case doubleDuringGame = "raise"
|
var path: String {
|
||||||
|
rawValue
|
||||||
/// The url path for the client to call (e.g. /player/deal)
|
|
||||||
var path: String {
|
|
||||||
rawValue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ enum PlayCardResult {
|
|||||||
|
|
||||||
case noTableJoined
|
case noTableJoined
|
||||||
|
|
||||||
case invalidTableState
|
case tableStateInvalid
|
||||||
|
|
||||||
case invalidCard
|
case invalidCard
|
||||||
}
|
}
|
||||||
|
@ -12,4 +12,6 @@ enum PlayerActionResult {
|
|||||||
case tableNotFull
|
case tableNotFull
|
||||||
|
|
||||||
case tableStateInvalid
|
case tableStateInvalid
|
||||||
|
|
||||||
|
case invalidCard
|
||||||
}
|
}
|
@ -284,7 +284,7 @@ func routes(_ app: Application) throws {
|
|||||||
throw Abort(.badRequest)
|
throw Abort(.badRequest)
|
||||||
}
|
}
|
||||||
let result: PlayerActionResult
|
let result: PlayerActionResult
|
||||||
if let action = Player.Action(rawValue: actionString) {
|
if let action = PlayerAction(rawValue: actionString) {
|
||||||
result = database.performAction(playerToken: token, action: action)
|
result = database.performAction(playerToken: token, action: action)
|
||||||
} else if let game = GameType(rawValue: actionString) {
|
} else if let game = GameType(rawValue: actionString) {
|
||||||
result = database.select(game: game, playerToken: token)
|
result = database.select(game: game, playerToken: token)
|
||||||
@ -302,6 +302,8 @@ func routes(_ app: Application) throws {
|
|||||||
throw Abort(.preconditionFailed) // 412
|
throw Abort(.preconditionFailed) // 412
|
||||||
case .tableStateInvalid:
|
case .tableStateInvalid:
|
||||||
throw Abort(.preconditionFailed) // 412
|
throw Abort(.preconditionFailed) // 412
|
||||||
|
case .invalidCard:
|
||||||
|
throw Abort(.preconditionFailed) // 412
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,11 +320,12 @@ func routes(_ app: Application) throws {
|
|||||||
throw Abort(.unauthorized) // 401
|
throw Abort(.unauthorized) // 401
|
||||||
case .noTableJoined:
|
case .noTableJoined:
|
||||||
throw Abort(.preconditionFailed) // 412
|
throw Abort(.preconditionFailed) // 412
|
||||||
case .invalidTableState:
|
case .tableStateInvalid:
|
||||||
throw Abort(.preconditionFailed) // 412
|
throw Abort(.preconditionFailed) // 412
|
||||||
case .invalidCard:
|
case .invalidCard:
|
||||||
throw Abort(.preconditionFailed) // 412
|
throw Abort(.preconditionFailed) // 412
|
||||||
|
case .tableNotFull:
|
||||||
|
throw Abort(.preconditionFailed) // 412
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user