summaryrefslogtreecommitdiff
path: root/sw-server/src/main/kotlin/org/luxons
diff options
context:
space:
mode:
authorJoffrey Bion <joffrey.bion@booking.com>2020-05-28 20:26:29 +0200
committerJoffrey Bion <joffrey.bion@booking.com>2020-05-31 11:16:00 +0200
commit36103b92ce4b6cd00925d861f4fb5e381cdc4833 (patch)
tree4c2bfced8317526b24da23fcef9febe6368c736e /sw-server/src/main/kotlin/org/luxons
parentAttempt at fixing race conditions with bot subscriptions (diff)
downloadseven-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')
-rw-r--r--sw-server/src/main/kotlin/org/luxons/sevenwonders/server/api/Converters.kt7
-rw-r--r--sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameController.kt14
-rw-r--r--sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/LobbyController.kt16
-rw-r--r--sw-server/src/main/kotlin/org/luxons/sevenwonders/server/lobby/Lobby.kt45
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
}
bgstack15