From 3c4d1f0e291d16c3173ba8116364dc6d4681a467 Mon Sep 17 00:00:00 2001 From: Christoph Hagen Date: Tue, 18 Oct 2022 11:40:08 +0200 Subject: [PATCH] Update player points when game ends --- Sources/App/Management/SQLiteDatabase.swift | 4 ++-- Sources/App/Management/TableManagement.swift | 8 +++++--- Sources/App/Model/Players/Player.swift | 2 +- Sources/App/Model/Tables/FinishedTable.swift | 19 +++++++++++++++++++ Sources/App/routes.swift | 4 ++-- 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/Sources/App/Management/SQLiteDatabase.swift b/Sources/App/Management/SQLiteDatabase.swift index 7ebf005..195b25b 100644 --- a/Sources/App/Management/SQLiteDatabase.swift +++ b/Sources/App/Management/SQLiteDatabase.swift @@ -266,11 +266,11 @@ final class SQLiteDatabase { return tables.select(game: game, player: player) } - func play(card: Card, playerToken: SessionToken) -> PlayerActionResult { + func play(card: Card, playerToken: SessionToken, in database: Database) async throws -> PlayerActionResult { guard let player = playerNameForToken[playerToken] else { return .invalidToken } - return tables.play(card: card, player: player) + return try await tables.play(card: card, player: player, in: database) } func disconnectAllSockets() { diff --git a/Sources/App/Management/TableManagement.swift b/Sources/App/Management/TableManagement.swift index 06063b7..b9c5ecd 100644 --- a/Sources/App/Management/TableManagement.swift +++ b/Sources/App/Management/TableManagement.swift @@ -114,8 +114,8 @@ final class TableManagement { } /// `player.canStartGame` is automatically set to false, because table is not full tables[table.id] = table + #warning("Update points for all players, add penalty if running game") table.sendUpdateToAllPlayers() - // TODO: Update points for all players try await player.update(on: database) } @@ -177,7 +177,7 @@ final class TableManagement { return .success } - func play(card: Card, player: PlayerName) -> PlayerActionResult { + func play(card: Card, player: PlayerName, in database: Database) async throws -> PlayerActionResult { guard let table = currentTable(for: player) else { return .noTableJoined } @@ -190,8 +190,10 @@ final class TableManagement { return .success } tables[newTable.id] = newTable + if let finished = newTable as? FinishedTable { + try await finished.updatePlayerPoints(in: database) + } newTable.sendUpdateToAllPlayers() - // TODO: Save new table return .success } diff --git a/Sources/App/Model/Players/Player.swift b/Sources/App/Model/Players/Player.swift index 1b621c3..cef335e 100644 --- a/Sources/App/Model/Players/Player.swift +++ b/Sources/App/Model/Players/Player.swift @@ -7,7 +7,7 @@ class Player { let name: PlayerName - let totalPoints: Int + var totalPoints: Int var socket: WebSocket? diff --git a/Sources/App/Model/Tables/FinishedTable.swift b/Sources/App/Model/Tables/FinishedTable.swift index 8effeb3..1cddfce 100644 --- a/Sources/App/Model/Tables/FinishedTable.swift +++ b/Sources/App/Model/Tables/FinishedTable.swift @@ -1,4 +1,5 @@ import Foundation +import Fluent final class FinishedTable: AbstractTable { @@ -137,4 +138,22 @@ final class FinishedTable: AbstractTable { override func cardStackPosition(ofPlayerAt index: Int) -> Int { (4 + index - indexOfTrickStarter) % 4 } + + func updatePlayerPoints(in database: Database) async throws { + let points = cost + let winnerNames = winners.map { $0.name } + for player in allPlayers { + guard let user = try await User.query(on: database).filter(\.$name == player.name).first() else { + continue + } + if winnerNames.contains(player.name) { + user.points += points + player.totalPoints += points + } else { + user.points -= points + player.totalPoints -= points + } + try await user.save(on: database) + } + } } diff --git a/Sources/App/routes.swift b/Sources/App/routes.swift index a316c32..f8bbbcb 100644 --- a/Sources/App/routes.swift +++ b/Sources/App/routes.swift @@ -412,14 +412,14 @@ func performActionForPlayer(_ app: Application) { - `412`: The action is not allowed */ func playCard(_ app: Application) { - app.post("player", "card") { request -> HTTPResponseStatus in + app.post("player", "card") { request async throws -> HTTPResponseStatus in let token = try request.header(.token) let cardId = try request.header(.action) guard let card = Card(id: cardId) else { throw Abort(.badRequest) } - switch server.play(card: card, playerToken: token) { + switch try await server.play(card: card, playerToken: token, in: request.db) { case .success: return .ok case .invalidToken: