2021-11-28 15:53:47 +01:00
|
|
|
import Foundation
|
2021-11-29 11:54:50 +01:00
|
|
|
import WebSocketKit
|
|
|
|
|
|
|
|
let maximumPlayersPerTable = 4
|
|
|
|
|
|
|
|
typealias TableId = String
|
|
|
|
typealias TableName = String
|
2021-11-28 15:53:47 +01:00
|
|
|
|
|
|
|
final class TableManagement {
|
|
|
|
|
|
|
|
/// A list of table ids for public games
|
|
|
|
private var publicTables = Set<TableId>()
|
|
|
|
|
|
|
|
/// A mapping from table id to table name (for all tables)
|
|
|
|
private var tableNames = [TableId: TableName]()
|
|
|
|
|
|
|
|
/// A mapping from table id to participating players
|
|
|
|
private var tablePlayers = [TableId: [PlayerName]]()
|
|
|
|
|
|
|
|
/// A reverse list of players and their table id
|
|
|
|
private var playerTables = [PlayerName: TableId]()
|
|
|
|
|
2021-11-29 11:54:50 +01:00
|
|
|
private var playerConnections = [PlayerName : WebSocket]()
|
2021-11-28 15:53:47 +01:00
|
|
|
|
2021-11-29 11:54:50 +01:00
|
|
|
init() {
|
2021-11-28 15:53:47 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Create a new table with optional players.
|
|
|
|
- Parameter name: The name of the table
|
|
|
|
- Parameter players: The player creating the table
|
|
|
|
- Parameter visible: Indicates that this is a game joinable by everyone
|
|
|
|
- Returns: The table id
|
|
|
|
*/
|
|
|
|
func createTable(named name: TableName, player: PlayerName, visible: Bool) -> TableId {
|
|
|
|
let tableId = TableId.newToken()
|
|
|
|
|
|
|
|
tableNames[tableId] = name
|
|
|
|
tablePlayers[tableId] = [player]
|
|
|
|
playerTables[player] = tableId
|
|
|
|
|
|
|
|
if visible {
|
|
|
|
publicTables.insert(tableId)
|
|
|
|
}
|
|
|
|
return tableId
|
|
|
|
}
|
|
|
|
|
|
|
|
func getPublicTableInfos() -> [TableInfo] {
|
|
|
|
publicTables.map { tableId in
|
2021-11-30 11:29:41 +01:00
|
|
|
let players = tablePlayers[tableId]!
|
|
|
|
let connected = players.map { playerConnections[$0] != nil }
|
|
|
|
return TableInfo(
|
|
|
|
id: tableId,
|
|
|
|
name: tableNames[tableId]!,
|
|
|
|
players: players,
|
|
|
|
connected: connected)
|
2021-11-28 15:53:47 +01:00
|
|
|
}.sorted()
|
|
|
|
}
|
|
|
|
|
2021-11-29 11:54:50 +01:00
|
|
|
func currentTableOfPlayer(named player: PlayerName) -> TableId? {
|
|
|
|
playerTables[player]
|
|
|
|
}
|
|
|
|
|
2021-11-28 15:53:47 +01:00
|
|
|
/**
|
|
|
|
Join a table.
|
2021-11-29 11:54:50 +01:00
|
|
|
- Returns: The result of the join operation
|
2021-11-28 15:53:47 +01:00
|
|
|
*/
|
2021-11-29 11:54:50 +01:00
|
|
|
func join(tableId: TableId, player: PlayerName) -> JoinTableResult {
|
2021-11-28 15:53:47 +01:00
|
|
|
guard var players = tablePlayers[tableId] else {
|
2021-11-29 11:54:50 +01:00
|
|
|
return .tableNotFound
|
|
|
|
}
|
|
|
|
guard !players.contains(player) else {
|
|
|
|
return .success
|
|
|
|
}
|
|
|
|
guard players.count < maximumPlayersPerTable else {
|
|
|
|
return .tableIsFull
|
2021-11-28 15:53:47 +01:00
|
|
|
}
|
|
|
|
players.append(player)
|
|
|
|
if let oldTable = playerTables[tableId] {
|
|
|
|
remove(player: player, fromTable: oldTable)
|
2021-11-29 11:54:50 +01:00
|
|
|
// TODO: End game if needed
|
|
|
|
//
|
2021-11-28 15:53:47 +01:00
|
|
|
}
|
|
|
|
tablePlayers[tableId] = players
|
|
|
|
playerTables[tableId] = tableId
|
2021-11-29 11:54:50 +01:00
|
|
|
return .success
|
2021-11-28 15:53:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func remove(player: PlayerName, fromTable tableId: TableId) {
|
|
|
|
tablePlayers[tableId] = tablePlayers[tableId]?.filter { $0 != player }
|
|
|
|
}
|
2021-11-29 11:54:50 +01:00
|
|
|
|
|
|
|
func remove(player: PlayerName) {
|
|
|
|
fatalError()
|
|
|
|
}
|
|
|
|
|
|
|
|
func connect(player: PlayerName, using socket: WebSocket) -> Bool {
|
|
|
|
fatalError()
|
|
|
|
}
|
|
|
|
|
|
|
|
func disconnect(player: PlayerName) {
|
|
|
|
fatalError()
|
|
|
|
}
|
2021-11-28 15:53:47 +01:00
|
|
|
}
|