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 --- .../sevenwonders/model/CustomizableSettings.kt | 47 ----------- .../org/luxons/sevenwonders/model/Settings.kt | 18 +++++ .../org/luxons/sevenwonders/model/api/Api.kt | 68 ---------------- .../org/luxons/sevenwonders/model/api/Lobby.kt | 46 +++++++++++ .../org/luxons/sevenwonders/model/api/Player.kt | 28 +++++++ .../sevenwonders/model/api/actions/Actions.kt | 21 ++++- .../org/luxons/sevenwonders/model/cards/Cards.kt | 2 +- .../luxons/sevenwonders/model/wonders/Wonders.kt | 31 ++++++++ .../sevenwonders/model/WonderSidePickMethodTest.kt | 91 ---------------------- 9 files changed, 141 insertions(+), 211 deletions(-) delete mode 100644 sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/CustomizableSettings.kt create mode 100644 sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/Settings.kt delete mode 100644 sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Api.kt create mode 100644 sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Lobby.kt create mode 100644 sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Player.kt delete mode 100644 sw-common-model/src/commonTest/kotlin/org/luxons/sevenwonders/model/WonderSidePickMethodTest.kt (limited to 'sw-common-model') diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/CustomizableSettings.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/CustomizableSettings.kt deleted file mode 100644 index 86a11bc1..00000000 --- a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/CustomizableSettings.kt +++ /dev/null @@ -1,47 +0,0 @@ -package org.luxons.sevenwonders.model - -import kotlinx.serialization.Serializable -import kotlin.random.Random - -@Serializable -data class CustomizableSettings( - val randomSeedForTests: Long? = null, - val timeLimitInSeconds: Int = 45, - val wonderSidePickMethod: WonderSidePickMethod = WonderSidePickMethod.EACH_RANDOM, - val initialGold: Int = 3, - val discardedCardGold: Int = 3, - val defaultTradingCost: Int = 2, - val pointsPer3Gold: Int = 1, - val lostPointsPerDefeat: Int = 1, - val wonPointsPerVictoryPerAge: Map = mapOf(1 to 1, 2 to 3, 3 to 5) -) - -enum class WonderSide { - A, - B -} - -enum class WonderSidePickMethod { - ALL_A { - override fun pickSide(random: Random, lastPickedSide: WonderSide?): WonderSide { - return WonderSide.A - } - }, - ALL_B { - override fun pickSide(random: Random, lastPickedSide: WonderSide?): WonderSide { - return WonderSide.B - } - }, - EACH_RANDOM { - override fun pickSide(random: Random, lastPickedSide: WonderSide?): WonderSide { - return if (random.nextBoolean()) WonderSide.A else WonderSide.B - } - }, - SAME_RANDOM_FOR_ALL { - override fun pickSide(random: Random, lastPickedSide: WonderSide?): WonderSide { - return lastPickedSide ?: if (random.nextBoolean()) WonderSide.A else WonderSide.B - } - }; - - abstract fun pickSide(random: Random, lastPickedSide: WonderSide?): WonderSide -} diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/Settings.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/Settings.kt new file mode 100644 index 00000000..21be1c1b --- /dev/null +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/Settings.kt @@ -0,0 +1,18 @@ +package org.luxons.sevenwonders.model + +import kotlinx.serialization.Serializable +import kotlin.random.Random + +@Serializable +data class Settings( + val randomSeedForTests: Long? = null, + val timeLimitInSeconds: Int = 45, + val initialGold: Int = 3, + val discardedCardGold: Int = 3, + val defaultTradingCost: Int = 2, + val pointsPer3Gold: Int = 1, + val lostPointsPerDefeat: Int = 1, + val wonPointsPerVictoryPerAge: Map = mapOf(1 to 1, 2 to 3, 3 to 5) +) { + val random: Random by lazy { randomSeedForTests?.let { Random(it) } ?: Random } +} diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Api.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Api.kt deleted file mode 100644 index d22a350a..00000000 --- a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Api.kt +++ /dev/null @@ -1,68 +0,0 @@ -package org.luxons.sevenwonders.model.api - -import kotlinx.serialization.Serializable -import org.luxons.sevenwonders.model.api.actions.Icon - -const val SEVEN_WONDERS_WS_ENDPOINT = "/seven-wonders-websocket" - -enum class State { - LOBBY, PLAYING, FINISHED -} - -@Serializable -data class LobbyDTO( - val id: Long, - val name: String, - val owner: String, - val players: List, - val state: State, - val hasEnoughPlayers: Boolean, - val maxPlayersReached: Boolean -) { - fun joinability(userDisplayName: String): Actionability = when { - state != State.LOBBY -> Actionability(false, "Cannot join: the game has already started") - maxPlayersReached -> Actionability(false, "Cannot join: the game is full") - playerNameAlreadyUsed(userDisplayName) -> Actionability( - false, - "Cannot join: already a player named '$userDisplayName' in this game" - ) - else -> Actionability(true, "Join game") - } - - fun startability(username: String): Actionability = when { - !hasEnoughPlayers -> Actionability(false, "Cannot start the game, more players needed") - owner != username -> Actionability(false, "Cannot start the game: only the owner can") - else -> Actionability(true, "Start game") - } - - private fun playerNameAlreadyUsed(name: String): Boolean = players.any { it.displayName == name } -} - -@Serializable -data class Actionability( - val canDo: Boolean, - val tooltip: String -) - -interface BasicPlayerInfo { - val username: String - val displayName: String - val icon: Icon? -} - -@Serializable -data class ConnectedPlayer( - override val username: String, - override val displayName: String, - override val icon: Icon? -) : BasicPlayerInfo - -@Serializable -data class PlayerDTO( - override val username: String, - override val displayName: String, - override val icon: Icon?, - val index: Int, - val isGameOwner: Boolean, - val isReady: Boolean -) : BasicPlayerInfo diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Lobby.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Lobby.kt new file mode 100644 index 00000000..1438600a --- /dev/null +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Lobby.kt @@ -0,0 +1,46 @@ +package org.luxons.sevenwonders.model.api + +import kotlinx.serialization.Serializable +import org.luxons.sevenwonders.model.wonders.PreGameWonder + +const val SEVEN_WONDERS_WS_ENDPOINT = "/seven-wonders-websocket" + +enum class State { + LOBBY, PLAYING, FINISHED +} + +@Serializable +data class LobbyDTO( + val id: Long, + val name: String, + val owner: String, + val players: List, + val allWonders: List, + val state: State, + val hasEnoughPlayers: Boolean, + val maxPlayersReached: Boolean +) { + fun joinability(userDisplayName: String): Actionability = when { + state != State.LOBBY -> Actionability(false, "Cannot join: the game has already started") + maxPlayersReached -> Actionability(false, "Cannot join: the game is full") + playerNameAlreadyUsed(userDisplayName) -> Actionability( + false, + "Cannot join: already a player named '$userDisplayName' in this game" + ) + else -> Actionability(true, "Join game") + } + + fun startability(username: String): Actionability = when { + !hasEnoughPlayers -> Actionability(false, "Cannot start the game, more players needed") + owner != username -> Actionability(false, "Cannot start the game: only the owner can") + else -> Actionability(true, "Start game") + } + + private fun playerNameAlreadyUsed(name: String): Boolean = players.any { it.displayName == name } +} + +@Serializable +data class Actionability( + val canDo: Boolean, + val tooltip: String +) diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Player.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Player.kt new file mode 100644 index 00000000..7161b53d --- /dev/null +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Player.kt @@ -0,0 +1,28 @@ +package org.luxons.sevenwonders.model.api + +import kotlinx.serialization.Serializable +import org.luxons.sevenwonders.model.api.actions.Icon +import org.luxons.sevenwonders.model.wonders.AssignedWonder + +interface BasicPlayerInfo { + val username: String + val displayName: String + val icon: Icon? +} + +@Serializable +data class ConnectedPlayer( + override val username: String, + override val displayName: String, + override val icon: Icon? +) : BasicPlayerInfo + +@Serializable +data class PlayerDTO( + override val username: String, + override val displayName: String, + override val icon: Icon?, + val wonder: AssignedWonder, + val isGameOwner: Boolean, + val isReady: Boolean +) : BasicPlayerInfo diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/actions/Actions.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/actions/Actions.kt index 0687e968..4a721a94 100644 --- a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/actions/Actions.kt +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/actions/Actions.kt @@ -1,7 +1,8 @@ package org.luxons.sevenwonders.model.api.actions import kotlinx.serialization.Serializable -import org.luxons.sevenwonders.model.CustomizableSettings +import org.luxons.sevenwonders.model.wonders.AssignedWonder +import org.luxons.sevenwonders.model.Settings import org.luxons.sevenwonders.model.PlayerMove /** @@ -58,8 +59,8 @@ class PrepareMoveAction( ) /** - * The action to update the order of the players around the table. Can only be called in the lobby by the owner of the - * game. + * The action to update the order of the players around the table. + * Can only be called in the lobby by the owner of the game. */ @Serializable class ReorderPlayersAction( @@ -69,6 +70,18 @@ class ReorderPlayersAction( val orderedPlayers: List ) +/** + * The action to update the wonders assigned to each player. + * Can only be called in the lobby by the owner of the game. + */ +@Serializable +class ReassignWondersAction( + /** + * The list of wonders assigned to each player, in the players' order. + */ + val assignedWonders: List +) + /** * The action to update the settings of the game. Can only be called in the lobby by the owner of the game. */ @@ -77,7 +90,7 @@ class UpdateSettingsAction( /** * The new values for the settings. */ - val settings: CustomizableSettings + val settings: Settings ) /** diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/cards/Cards.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/cards/Cards.kt index 96027612..b0e73ed5 100644 --- a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/cards/Cards.kt +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/cards/Cards.kt @@ -46,7 +46,7 @@ data class HandCard( @Serializable data class PreparedCard( - val player: PlayerDTO, + val username: String, val cardBack: CardBack? ) diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/wonders/Wonders.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/wonders/Wonders.kt index 9e9a5b38..888e1c47 100644 --- a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/wonders/Wonders.kt +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/wonders/Wonders.kt @@ -6,6 +6,37 @@ import org.luxons.sevenwonders.model.cards.CardBack import org.luxons.sevenwonders.model.cards.PlayabilityLevel import org.luxons.sevenwonders.model.resources.ResourceTransactions import org.luxons.sevenwonders.model.resources.ResourceType +import kotlin.random.Random + +typealias WonderName = String + +@Serializable +data class PreGameWonder( + val name: WonderName, + val images: Map +) + +@Serializable +data class AssignedWonder( + val name: WonderName, + val side: WonderSide, + val image: String +) + +@Serializable +enum class WonderSide { + A, + B +} + +fun List.deal(nbPlayers: Int, random: Random = Random): List = + shuffled(random).take(nbPlayers).map { it.withRandomSide(random) } + +fun PreGameWonder.withRandomSide(random: Random = Random): AssignedWonder { + val side = WonderSide.values().random(random) + val sideImage = images.getValue(side) + return AssignedWonder(name, side, sideImage) +} @Serializable data class ApiWonder( diff --git a/sw-common-model/src/commonTest/kotlin/org/luxons/sevenwonders/model/WonderSidePickMethodTest.kt b/sw-common-model/src/commonTest/kotlin/org/luxons/sevenwonders/model/WonderSidePickMethodTest.kt deleted file mode 100644 index 70a061e3..00000000 --- a/sw-common-model/src/commonTest/kotlin/org/luxons/sevenwonders/model/WonderSidePickMethodTest.kt +++ /dev/null @@ -1,91 +0,0 @@ -package org.luxons.sevenwonders.model - -import kotlin.random.Random -import kotlin.test.BeforeTest -import kotlin.test.Test -import kotlin.test.assertEquals - -class WonderSidePickMethodTest { - - private lateinit var random: Random - - private lateinit var random2: Random - - @BeforeTest - fun setUp() { - random = Random(421) // starts with TRUE - random2 = Random(42) // starts with FALSE - } - - @Test - fun pick_allA() { - var side: WonderSide? = null - repeat(10) { - side = WonderSidePickMethod.ALL_A.pickSide(random, side) - assertEquals(WonderSide.A, side) - } - } - - @Test - fun pick_allB() { - var side: WonderSide? = null - repeat(10) { - side = WonderSidePickMethod.ALL_B.pickSide(random, side) - assertEquals(WonderSide.B, side) - } - } - - @Test - fun pick_eachRandom() { - var side = WonderSidePickMethod.EACH_RANDOM.pickSide(random, null) - assertEquals(WonderSide.A, side) - side = WonderSidePickMethod.EACH_RANDOM.pickSide(random, side) - assertEquals(WonderSide.A, side) - side = WonderSidePickMethod.EACH_RANDOM.pickSide(random, side) - assertEquals(WonderSide.B, side) - side = WonderSidePickMethod.EACH_RANDOM.pickSide(random, side) - assertEquals(WonderSide.A, side) - side = WonderSidePickMethod.EACH_RANDOM.pickSide(random, side) - assertEquals(WonderSide.B, side) - side = WonderSidePickMethod.EACH_RANDOM.pickSide(random, side) - assertEquals(WonderSide.B, side) - } - - @Test - fun pick_eachRandom2() { - var side = WonderSidePickMethod.EACH_RANDOM.pickSide(random2, null) - assertEquals(WonderSide.B, side) - side = WonderSidePickMethod.EACH_RANDOM.pickSide(random2, side) - assertEquals(WonderSide.B, side) - side = WonderSidePickMethod.EACH_RANDOM.pickSide(random2, side) - assertEquals(WonderSide.A, side) - side = WonderSidePickMethod.EACH_RANDOM.pickSide(random2, side) - assertEquals(WonderSide.A, side) - side = WonderSidePickMethod.EACH_RANDOM.pickSide(random2, side) - assertEquals(WonderSide.B, side) - side = WonderSidePickMethod.EACH_RANDOM.pickSide(random2, side) - assertEquals(WonderSide.B, side) - } - - @Test - fun pick_allSameRandom_sameAsFirst() { - repeat(10) { - val side = WonderSidePickMethod.SAME_RANDOM_FOR_ALL.pickSide(random, - WonderSide.A - ) - assertEquals(WonderSide.A, side) - } - repeat(10) { - val side = WonderSidePickMethod.SAME_RANDOM_FOR_ALL.pickSide(random, - WonderSide.B - ) - assertEquals(WonderSide.B, side) - } - } - - @Test - fun pick_allSameRandom_firstIsRandom() { - assertEquals(WonderSide.A, WonderSidePickMethod.SAME_RANDOM_FOR_ALL.pickSide(random, null)) - assertEquals(WonderSide.B, WonderSidePickMethod.SAME_RANDOM_FOR_ALL.pickSide(random2, null)) - } -} -- cgit