From 36103b92ce4b6cd00925d861f4fb5e381cdc4833 Mon Sep 17 00:00:00 2001 From: Joffrey Bion Date: Thu, 28 May 2020 20:26:29 +0200 Subject: Simplify settings and allow choosing wonders --- .../luxons/sevenwonders/server/api/Converters.kt | 7 +++- .../server/controllers/GameController.kt | 14 +++---- .../server/controllers/LobbyController.kt | 16 ++++++++ .../org/luxons/sevenwonders/server/lobby/Lobby.kt | 45 ++++++++++++++++++---- .../server/controllers/LobbyControllerTest.kt | 9 ++--- .../luxons/sevenwonders/server/lobby/LobbyTest.kt | 4 +- 6 files changed, 69 insertions(+), 26 deletions(-) (limited to 'sw-server') 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 @@ -69,6 +70,21 @@ class LobbyController( sendLobbyUpdateToPlayers(lobby) } + /** + * 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. * 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 = ArrayList(gameDefinition.maxPlayers) - var settings: CustomizableSettings = CustomizableSettings() + val allWonders: List = gameDefinition.allWonders + + private val assignedWonders: MutableList = mutableListOf() + + var settings: Settings = Settings() var state = State.LOBBY private set @@ -24,6 +31,8 @@ class Lobby( fun getPlayers(): List = players + fun getAssignedWonders(): List = 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) { + 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 } diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/LobbyControllerTest.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/LobbyControllerTest.kt index 9aa1ef0e..2f6e2cdb 100644 --- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/LobbyControllerTest.kt +++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/LobbyControllerTest.kt @@ -2,8 +2,7 @@ package org.luxons.sevenwonders.server.controllers import org.junit.Before import org.junit.Test -import org.luxons.sevenwonders.model.CustomizableSettings -import org.luxons.sevenwonders.model.WonderSidePickMethod.ALL_A +import org.luxons.sevenwonders.model.Settings import org.luxons.sevenwonders.model.api.State import org.luxons.sevenwonders.model.api.actions.ReorderPlayersAction import org.luxons.sevenwonders.model.api.actions.UpdateSettingsAction @@ -142,9 +141,9 @@ class LobbyControllerTest { addPlayer(lobby, "testuser3") addPlayer(lobby, "testuser4") - assertEquals(CustomizableSettings(), lobby.settings) + assertEquals(Settings(), lobby.settings) - val newSettings = CustomizableSettings(12L, 5, ALL_A, 5, 5, 4, 10, 2, HashMap()) + val newSettings = Settings(12L, 5, 5, 5, 4, 10, 2, HashMap()) val updateSettingsAction = UpdateSettingsAction(newSettings) val principal = TestPrincipal("testuser") @@ -161,7 +160,7 @@ class LobbyControllerTest { addPlayer(lobby, "testuser2") addPlayer(lobby, "testuser3") - val updateSettingsAction = UpdateSettingsAction(CustomizableSettings()) + val updateSettingsAction = UpdateSettingsAction(Settings()) val principal = TestPrincipal("testuser2") diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/lobby/LobbyTest.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/lobby/LobbyTest.kt index 094fe7de..1742dc93 100644 --- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/lobby/LobbyTest.kt +++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/lobby/LobbyTest.kt @@ -9,7 +9,7 @@ import org.junit.experimental.theories.Theories import org.junit.experimental.theories.Theory import org.junit.runner.RunWith import org.luxons.sevenwonders.engine.data.GameDefinition -import org.luxons.sevenwonders.model.CustomizableSettings +import org.luxons.sevenwonders.model.Settings import org.luxons.sevenwonders.model.api.State import org.luxons.sevenwonders.server.lobby.Lobby.GameAlreadyStartedException import org.luxons.sevenwonders.server.lobby.Lobby.PlayerListMismatchException @@ -240,7 +240,7 @@ class LobbyTest { @Test fun setSettings() { - val settings = CustomizableSettings() + val settings = Settings() lobby.settings = settings assertSame(settings, lobby.settings) } -- cgit