Switch to SQLite database over text files

This commit is contained in:
Christoph Hagen
2021-12-22 22:13:09 +01:00
parent 86456b2441
commit 5eafcfdf4d
10 changed files with 148 additions and 564 deletions

View File

@ -1,24 +1,30 @@
import Foundation
import WebSocketKit
typealias PlayerName = String
class Player {
let name: PlayerName
let totalPoints: Int
var socket: WebSocket?
var isNextActor: Bool
init(name: PlayerName, socket: WebSocket? = nil) {
init(name: PlayerName, points: Int, socket: WebSocket? = nil) {
self.name = name
self.socket = socket
self.isNextActor = false
self.totalPoints = points
}
init(player: Player) {
self.name = player.name
self.socket = player.socket
self.isNextActor = false
self.totalPoints = player.totalPoints
}
var actions: [PlayerAction] {
@ -31,6 +37,7 @@ class Player {
var info: PlayerInfo {
var result = PlayerInfo(name: name)
result.points = totalPoints
result.isConnected = isConnected
result.isNextActor = isNextActor
result.state = states.map { $0.rawValue }

View File

@ -7,7 +7,7 @@ let numberOfCardsPerPlayer = 8
class AbstractTable<TablePlayer> where TablePlayer: Player {
/// The unique id of the table
let id: TableId
let id: UUID
/// The name of the table
let name: TableName
@ -28,6 +28,10 @@ class AbstractTable<TablePlayer> where TablePlayer: Player {
nil
}
var leavePenalty: Int {
5
}
init(table: ManageableTable, players: [TablePlayer]) {
self.id = table.id
self.name = table.name
@ -35,7 +39,7 @@ class AbstractTable<TablePlayer> where TablePlayer: Player {
self.players = players
}
init(id: TableId, name: TableName, isPublic: Bool, players: [TablePlayer]) {
init(id: UUID, name: TableName, isPublic: Bool, players: [TablePlayer]) {
self.id = id
self.name = name
self.isPublic = isPublic
@ -67,7 +71,7 @@ class AbstractTable<TablePlayer> where TablePlayer: Player {
}
func tableInfo(forPlayerAt index: Int) -> TableInfo {
var info = TableInfo(id: id, name: name)
var info = TableInfo(id: id.uuidString, name: name)
info.player = playerInfo(forIndex: index)!
info.playerLeft = playerInfo(forIndex: (index + 1) % 4)
info.playerAcross = playerInfo(forIndex: (index + 2) % 4)
@ -85,7 +89,7 @@ class AbstractTable<TablePlayer> where TablePlayer: Player {
extension AbstractTable: ManageableTable {
var publicInfo: PublicTableInfo {
.init(id: id, name: name, players: playerNames)
.init(id: id.uuidString, name: name, players: playerNames)
}
var playerNames: [PlayerName] {

View File

@ -4,7 +4,7 @@ import WebSocketKit
protocol ManageableTable {
/// The unique id of the table
var id: TableId { get }
var id: UUID { get }
/// The name of the table
var name: TableName { get }
@ -12,6 +12,8 @@ protocol ManageableTable {
/// The table is visible in the list of tables and can be joined by anyone
var isPublic: Bool { get }
var leavePenalty: Int { get }
var playerNames: [PlayerName] { get }
var allPlayers: [Player] { get }

View File

@ -1,4 +1,5 @@
import Foundation
import Fluent
/**
Represents a table where players are still joining and leaving.
@ -10,8 +11,8 @@ final class WaitingTable: AbstractTable<WaitingPlayer> {
players.count >= maximumPlayersPerTable
}
init(id: TableId, name: TableName, isPublic: Bool, players: [PlayerName]) {
let players = players.map { WaitingPlayer(name: $0) }
init(id: UUID, name: TableName, isPublic: Bool, players: [User]) {
let players = players.map { WaitingPlayer(name: $0.name, points: $0.points) }
players.first!.isNextActor = true
super.init(id: id, name: name, isPublic: isPublic, players: players)
if isFull {
@ -24,10 +25,11 @@ final class WaitingTable: AbstractTable<WaitingPlayer> {
- Parameter name: The name of the table
- Parameter isPublic: The table is visible and joinable by everyone
*/
init(newTable name: TableName, isPublic: Bool, creator: PlayerName) {
let player = WaitingPlayer(name: creator)
init(newTable object: Table) {
let user = object.players[0]
let player = WaitingPlayer(name: user.name, points: user.points)
player.isNextActor = true
super.init(id: .newToken(), name: name, isPublic: isPublic, players: [player])
super.init(id: object.id!, name: object.name, isPublic: object.isPublic, players: [player])
}
/**
@ -38,6 +40,7 @@ final class WaitingTable: AbstractTable<WaitingPlayer> {
- Parameter player: The name of the player to remove from the table.
*/
init(oldTable: ManageableTable, removing player: PlayerName) {
// TODO: End game and distribute points
let players = oldTable.allPlayers
.filter {
guard $0.name == player else {
@ -46,7 +49,7 @@ final class WaitingTable: AbstractTable<WaitingPlayer> {
_ = $0.disconnect()
return false
}
.map { WaitingPlayer(name: $0.name, socket: $0.socket) }
.map { WaitingPlayer(name: $0.name, points: $0.totalPoints, socket: $0.socket) }
players.first!.isNextActor = true
super.init(table: oldTable, players: players)
}
@ -60,7 +63,7 @@ final class WaitingTable: AbstractTable<WaitingPlayer> {
init(oldTableAdvancedByOne table: ManageableTable) {
let players = table.allPlayers
.rotatedByOne()
.map { WaitingPlayer(name: $0.name, socket: $0.socket) }
.map(WaitingPlayer.init)
super.init(table: table, players: players)
players.forEach { $0.canStartGame = true }
players.first!.isNextActor = true
@ -71,11 +74,11 @@ final class WaitingTable: AbstractTable<WaitingPlayer> {
- Parameter player: The name of the player to add
- Returns: `true`, if the player could be added, `false` if the table is full
*/
func add(player: PlayerName) -> Bool {
func add(player: PlayerName, points: Int) -> Bool {
guard !isFull else {
return false
}
let player = WaitingPlayer(name: player)
let player = WaitingPlayer(name: player, points: points)
players.append(player)
// Allow dealing of cards if table is full
if isFull {