diff options
author | Joffrey Bion <joffrey.bion@booking.com> | 2020-05-28 20:26:29 +0200 |
---|---|---|
committer | Joffrey Bion <joffrey.bion@booking.com> | 2020-05-31 11:16:00 +0200 |
commit | 36103b92ce4b6cd00925d861f4fb5e381cdc4833 (patch) | |
tree | 4c2bfced8317526b24da23fcef9febe6368c736e /sw-server/src/main/kotlin/org/luxons | |
parent | Attempt at fixing race conditions with bot subscriptions (diff) | |
download | seven-wonders-36103b92ce4b6cd00925d861f4fb5e381cdc4833.tar.gz seven-wonders-36103b92ce4b6cd00925d861f4fb5e381cdc4833.tar.bz2 seven-wonders-36103b92ce4b6cd00925d861f4fb5e381cdc4833.zip |
Simplify settings and allow choosing wonders
Diffstat (limited to 'sw-server/src/main/kotlin/org/luxons')
4 files changed, 63 insertions, 19 deletions
diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/api/Converters.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/api/Converters.kt index 6ef13b8e..61bcad89 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/api/Converters.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/api/Converters.kt @@ -2,6 +2,7 @@ package org.luxons.sevenwonders.server.api import org.luxons.sevenwonders.model.api.LobbyDTO import org.luxons.sevenwonders.model.api.PlayerDTO +import org.luxons.sevenwonders.model.wonders.AssignedWonder import org.luxons.sevenwonders.server.lobby.Lobby import org.luxons.sevenwonders.server.lobby.Player @@ -9,10 +10,12 @@ fun Lobby.toDTO(): LobbyDTO = LobbyDTO( id = id, name = name, owner = owner.username, - players = getPlayers().map { it.toDTO() }, + players = getPlayers().zip(getAssignedWonders()).map { (p, w) -> p.toDTO(w) }, + allWonders = allWonders, state = state, hasEnoughPlayers = hasEnoughPlayers(), maxPlayersReached = maxPlayersReached() ) -fun Player.toDTO() = PlayerDTO(username, displayName, icon, index, isGameOwner, isReady) +private fun Player.toDTO(wonder: AssignedWonder) = + PlayerDTO(username, displayName, icon, wonder, isGameOwner, isReady) diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameController.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameController.kt index e4b9c6ab..8b9bbd19 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameController.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameController.kt @@ -5,7 +5,6 @@ import org.luxons.sevenwonders.engine.Game import org.luxons.sevenwonders.model.api.actions.PrepareMoveAction import org.luxons.sevenwonders.model.cards.PreparedCard import org.luxons.sevenwonders.model.hideHandsAndWaitForReadiness -import org.luxons.sevenwonders.server.api.toDTO import org.luxons.sevenwonders.server.lobby.Player import org.luxons.sevenwonders.server.repositories.PlayerRepository import org.slf4j.LoggerFactory @@ -29,8 +28,7 @@ class GameController( /** * Notifies the game that the player is ready to receive his hand. * - * @param principal - * the connected user's information + * @param principal the connected user's information */ @MessageMapping("/game/sayReady") fun ready(principal: Principal) { @@ -54,17 +52,15 @@ class GameController( /** * Prepares the player's next move. When all players have prepared their moves, all moves are executed. * - * @param action - * the action to prepare the move - * @param principal - * the connected user's information + * @param action the action to prepare the move + * @param principal the connected user's information */ @MessageMapping("/game/prepareMove") fun prepareMove(action: PrepareMoveAction, principal: Principal) { val player = principal.player val game = player.game val preparedCardBack = game.prepareMove(player.index, action.move) - val preparedCard = PreparedCard(player.toDTO(), preparedCardBack) + val preparedCard = PreparedCard(player.username, preparedCardBack) logger.info("Game {}: player {} prepared move {}", game.id, principal.name, action.move) sendPreparedCard(game.id, preparedCard) @@ -85,7 +81,7 @@ class GameController( val player = principal.player val game = player.game game.unprepareMove(player.index) - val preparedCard = PreparedCard(player.toDTO(), null) + val preparedCard = PreparedCard(player.username, null) logger.info("Game {}: player {} unprepared his move", game.id, principal.name) sendPreparedCard(game.id, preparedCard) } diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/LobbyController.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/LobbyController.kt index fafcf7c3..1c8cf17e 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/LobbyController.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/LobbyController.kt @@ -5,6 +5,7 @@ import kotlinx.coroutines.launch import org.hildan.livedoc.core.annotations.Api import org.luxons.sevenwonders.bot.SevenWondersBot import org.luxons.sevenwonders.model.api.actions.AddBotAction +import org.luxons.sevenwonders.model.api.actions.ReassignWondersAction import org.luxons.sevenwonders.model.api.actions.ReorderPlayersAction import org.luxons.sevenwonders.model.api.actions.UpdateSettingsAction import org.luxons.sevenwonders.model.hideHandsAndWaitForReadiness @@ -70,6 +71,21 @@ class LobbyController( } /** + * Reassigns the wonders in the current lobby. This can only be done by the lobby's owner. + * + * @param action the action to reassign the wonders + * @param principal the connected user's information + */ + @MessageMapping("/lobby/reassignWonders") + fun reassignWonders(@Validated action: ReassignWondersAction, principal: Principal) { + val lobby = principal.player.ownedLobby + lobby.reassignWonders(action.assignedWonders) + + logger.info("Reassigned wonders in game '{}': {}", lobby.name, action.assignedWonders) + sendLobbyUpdateToPlayers(lobby) + } + + /** * Updates the game settings. This can only be done by the lobby's owner. * * @param action the action to update the settings diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/lobby/Lobby.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/lobby/Lobby.kt index 24bf5066..89d041f0 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/lobby/Lobby.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/lobby/Lobby.kt @@ -2,8 +2,11 @@ package org.luxons.sevenwonders.server.lobby import org.luxons.sevenwonders.engine.Game import org.luxons.sevenwonders.engine.data.GameDefinition -import org.luxons.sevenwonders.model.CustomizableSettings +import org.luxons.sevenwonders.model.wonders.AssignedWonder +import org.luxons.sevenwonders.model.wonders.PreGameWonder +import org.luxons.sevenwonders.model.Settings import org.luxons.sevenwonders.model.api.State +import org.luxons.sevenwonders.model.wonders.withRandomSide class Lobby( val id: Long, @@ -13,7 +16,11 @@ class Lobby( ) { private val players: MutableList<Player> = ArrayList(gameDefinition.maxPlayers) - var settings: CustomizableSettings = CustomizableSettings() + val allWonders: List<PreGameWonder> = gameDefinition.allWonders + + private val assignedWonders: MutableList<AssignedWonder> = mutableListOf() + + var settings: Settings = Settings() var state = State.LOBBY private set @@ -24,6 +31,8 @@ class Lobby( fun getPlayers(): List<Player> = players + fun getAssignedWonders(): List<AssignedWonder> = assignedWonders + @Synchronized fun addPlayer(player: Player) { if (hasStarted()) { @@ -37,8 +46,15 @@ class Lobby( } player.join(this) players.add(player) + assignedWonders.add(pickRandomWonder()) } + @Synchronized + private fun pickRandomWonder(): AssignedWonder = + allWonders.filter { !it.isAssigned() }.random().withRandomSide() + + private fun PreGameWonder.isAssigned() = name in assignedWonders.map { it.name } + private fun hasStarted(): Boolean = state != State.LOBBY fun maxPlayersReached(): Boolean = players.size >= gameDefinition.maxPlayers @@ -51,7 +67,7 @@ class Lobby( throw PlayerUnderflowException(gameDefinition.minPlayers) } state = State.PLAYING - val game = gameDefinition.initGame(id, settings, players.size) + val game = gameDefinition.createGame(id, assignedWonders, settings) players.forEachIndexed { index, player -> player.join(game, index) } return game } @@ -67,8 +83,15 @@ class Lobby( players.sortBy { orderedUsernames.indexOf(it.username) } } - private fun find(username: String): Player = - players.firstOrNull { it.username == username } ?: throw UnknownPlayerException(username) + @Synchronized + fun reassignWonders(wonders: List<AssignedWonder>) { + require(wonders.size == players.size) + wonders.forEach { + require(it.name in allWonders.map { w -> w.name }) + } + assignedWonders.clear() + assignedWonders.addAll(wonders) + } @Synchronized fun isOwner(username: String?): Boolean = owner.username == username @@ -78,16 +101,22 @@ class Lobby( @Synchronized fun removePlayer(username: String): Player { - val player = find(username) - players.remove(player) + val playerIndex = find(username) + if (playerIndex < 0) { + throw UnknownPlayerException(username) + } + assignedWonders.removeAt(playerIndex) + val player = players.removeAt(playerIndex) player.leave() - if (player == owner && !players.isEmpty()) { + if (player == owner && players.isNotEmpty()) { owner = players[0] } return player } + private fun find(username: String): Int = players.indexOfFirst { it.username == username } + fun setEndOfGame() { state = State.FINISHED } |