From 36a3b94972fb30a1e9a17973d55179c7a4595b28 Mon Sep 17 00:00:00 2001 From: Joffrey BION Date: Wed, 22 May 2019 02:17:33 +0200 Subject: Make common project multiplatform --- settings.gradle | 18 ++--- sw-common-model/build.gradle.kts | 44 +++++++++-- .../sevenwonders/game/api/CustomizableSettings.kt | 45 +++++++++++ .../org/luxons/sevenwonders/game/api/Moves.kt | 49 ++++++++++++ .../org/luxons/sevenwonders/game/api/Table.kt | 15 ++++ .../luxons/sevenwonders/game/api/boards/Boards.kt | 40 ++++++++++ .../game/api/boards/RelativeBoardPosition.kt | 16 ++++ .../luxons/sevenwonders/game/api/cards/Cards.kt | 65 ++++++++++++++++ .../game/api/cards/HandRotationDirection.kt | 11 +++ .../sevenwonders/game/api/resources/Resources.kt | 44 +++++++++++ .../sevenwonders/game/api/wonders/Wonders.kt | 32 ++++++++ .../game/api/WonderSidePickMethodTest.kt | 87 ++++++++++++++++++++++ .../sevenwonders/game/api/CustomizableSettings.kt | 45 ----------- .../org/luxons/sevenwonders/game/api/Moves.kt | 49 ------------ .../org/luxons/sevenwonders/game/api/Table.kt | 15 ---- .../luxons/sevenwonders/game/api/boards/Boards.kt | 40 ---------- .../game/api/boards/RelativeBoardPosition.kt | 16 ---- .../luxons/sevenwonders/game/api/cards/Cards.kt | 65 ---------------- .../game/api/cards/HandRotationDirection.kt | 11 --- .../sevenwonders/game/api/resources/Resources.kt | 44 ----------- .../sevenwonders/game/api/wonders/Wonders.kt | 32 -------- .../game/api/WonderSidePickMethodTest.kt | 87 ---------------------- 22 files changed, 451 insertions(+), 419 deletions(-) create mode 100644 sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/CustomizableSettings.kt create mode 100644 sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/Moves.kt create mode 100644 sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/Table.kt create mode 100644 sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/boards/Boards.kt create mode 100644 sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/boards/RelativeBoardPosition.kt create mode 100644 sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/cards/Cards.kt create mode 100644 sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/cards/HandRotationDirection.kt create mode 100644 sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/resources/Resources.kt create mode 100644 sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/wonders/Wonders.kt create mode 100644 sw-common-model/src/commonTest/kotlin/org/luxons/sevenwonders/game/api/WonderSidePickMethodTest.kt delete mode 100644 sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/CustomizableSettings.kt delete mode 100644 sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/Moves.kt delete mode 100644 sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/Table.kt delete mode 100644 sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/boards/Boards.kt delete mode 100644 sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/boards/RelativeBoardPosition.kt delete mode 100644 sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/cards/Cards.kt delete mode 100644 sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/cards/HandRotationDirection.kt delete mode 100644 sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/resources/Resources.kt delete mode 100644 sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/wonders/Wonders.kt delete mode 100644 sw-common-model/src/test/kotlin/org/luxons/sevenwonders/game/api/WonderSidePickMethodTest.kt diff --git a/settings.gradle b/settings.gradle index ca9aea78..11445e6c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,12 +1,12 @@ -//pluginManagement { -// resolutionStrategy { -// eachPlugin { -// if (requested.id.id == "kotlin-multiplatform") { -// useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}") -// } -// } -// } -//} +pluginManagement { + resolutionStrategy { + eachPlugin { + if (requested.id.id == "kotlin-multiplatform") { + useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}") + } + } + } +} rootProject.name = "seven-wonders" diff --git a/sw-common-model/build.gradle.kts b/sw-common-model/build.gradle.kts index 81c58543..c1c6e3fe 100644 --- a/sw-common-model/build.gradle.kts +++ b/sw-common-model/build.gradle.kts @@ -1,11 +1,43 @@ plugins { - kotlin("jvm") + kotlin("multiplatform") id("org.jlleitschuh.gradle.ktlint") } -dependencies { - implementation(kotlin("stdlib-jdk8")) - - testImplementation(kotlin("test")) - testImplementation(kotlin("test-junit")) +kotlin { + jvm() + js() + sourceSets { + val commonMain by getting { + dependencies { + implementation(kotlin("stdlib-common")) + } + } + val commonTest by getting { + dependencies { + implementation(kotlin("test-common")) + implementation(kotlin("test-annotations-common")) + } + } + val jvmMain by getting { + dependencies { + implementation(kotlin("stdlib-jdk8")) + } + } + val jvmTest by getting { + dependencies { + implementation(kotlin("test")) + implementation(kotlin("test-junit")) + } + } + val jsMain by getting { + dependencies { + implementation(kotlin("stdlib-js")) + } + } + val jsTest by getting { + dependencies { + implementation(kotlin("test-js")) + } + } + } } diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/CustomizableSettings.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/CustomizableSettings.kt new file mode 100644 index 00000000..ac2c2b14 --- /dev/null +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/CustomizableSettings.kt @@ -0,0 +1,45 @@ +package org.luxons.sevenwonders.game.api + +import kotlin.random.Random + +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/game/api/Moves.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/Moves.kt new file mode 100644 index 00000000..79a238b0 --- /dev/null +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/Moves.kt @@ -0,0 +1,49 @@ +package org.luxons.sevenwonders.game.api + +import org.luxons.sevenwonders.game.api.cards.HandCard +import org.luxons.sevenwonders.game.api.cards.TableCard +import org.luxons.sevenwonders.game.api.resources.ResourceTransactions +import org.luxons.sevenwonders.game.api.resources.noTransactions +import org.luxons.sevenwonders.game.api.wonders.WonderBuildability + +enum class Action(val message: String) { + PLAY("Pick the card you want to play or discard."), + PLAY_2("Pick the first card you want to play or discard. Note that you have the ability to play these 2 last cards. You will choose how to play the last one during your next turn."), + PLAY_LAST("You have the special ability to play your last card. Choose how you want to play it."), + PICK_NEIGHBOR_GUILD("Choose a Guild card (purple) that you want to copy from one of your neighbours."), + WAIT("Please wait for other players to perform extra actions.") +} + +data class PlayerTurnInfo( + val playerIndex: Int, + val table: ApiTable, + val action: Action, + val hand: List, + val preparedMove: PlayedMove?, + val neighbourGuildCards: List +) { + val currentAge: Int = table.currentAge + val message: String = action.message + val wonderBuildability: WonderBuildability = table.boards[playerIndex].wonder.buildability +} + +data class PlayedMove( + val playerIndex: Int, + val type: MoveType, + val card: TableCard, + val transactions: ResourceTransactions +) + +data class PlayerMove( + val type: MoveType, + val cardName: String, + val transactions: ResourceTransactions = noTransactions() +) + +enum class MoveType { + PLAY, + PLAY_FREE, + UPGRADE_WONDER, + DISCARD, + COPY_GUILD; +} diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/Table.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/Table.kt new file mode 100644 index 00000000..62f66b21 --- /dev/null +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/Table.kt @@ -0,0 +1,15 @@ +package org.luxons.sevenwonders.game.api + +import org.luxons.sevenwonders.game.api.boards.ApiBoard +import org.luxons.sevenwonders.game.api.cards.HandRotationDirection + +typealias Age = Int + +data class ApiTable( + val boards: List, + val currentAge: Age, + val handRotationDirection: HandRotationDirection, + val lastPlayedMoves: List +) { + val nbPlayers: Int = boards.size +} diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/boards/Boards.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/boards/Boards.kt new file mode 100644 index 00000000..061bdcad --- /dev/null +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/boards/Boards.kt @@ -0,0 +1,40 @@ +package org.luxons.sevenwonders.game.api.boards + +import org.luxons.sevenwonders.game.api.cards.TableCard +import org.luxons.sevenwonders.game.api.resources.CountedResource +import org.luxons.sevenwonders.game.api.resources.ResourceType +import org.luxons.sevenwonders.game.api.wonders.ApiWonder + +data class ApiBoard( + val playerIndex: Int, + val wonder: ApiWonder, + val production: ApiProduction, + val publicProduction: ApiProduction, + val science: ApiScience, + val military: ApiMilitary, + val playedCards: List>, + val gold: Int +) + +data class ApiRequirements( + val gold: Int = 0, + val resources: List = emptyList() +) + +data class ApiProduction( + val fixedResources: List, + val alternativeResources: Set> +) + +data class ApiMilitary( + val nbShields: Int, + val totalPoints: Int, + val nbDefeatTokens: Int +) + +data class ApiScience( + val jokers: Int, + val nbWheels: Int, + val nbCompasses: Int, + val nbTablets: Int +) diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/boards/RelativeBoardPosition.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/boards/RelativeBoardPosition.kt new file mode 100644 index 00000000..c7c3b5dc --- /dev/null +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/boards/RelativeBoardPosition.kt @@ -0,0 +1,16 @@ +package org.luxons.sevenwonders.game.api.boards + +enum class RelativeBoardPosition(private val offset: Int) { + LEFT(-1), + SELF(0), + RIGHT(1); + + fun getIndexFrom(playerIndex: Int, nbPlayers: Int): Int = (playerIndex + offset) floorMod nbPlayers +} + +fun neighboursPositions() = listOf(RelativeBoardPosition.LEFT, RelativeBoardPosition.RIGHT) + +private infix fun Int.floorMod(divisor: Int): Int { + val rem = this % divisor + return if (rem >= 0) rem else rem + divisor +} diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/cards/Cards.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/cards/Cards.kt new file mode 100644 index 00000000..4ccfe23b --- /dev/null +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/cards/Cards.kt @@ -0,0 +1,65 @@ +package org.luxons.sevenwonders.game.api.cards + +import org.luxons.sevenwonders.game.api.boards.ApiRequirements +import org.luxons.sevenwonders.game.api.resources.ResourceTransactions + +data class TableCard( + val name: String, + val color: Color, + val requirements: ApiRequirements, + val chainParent: String?, + val chainChildren: List, + val image: String, + val back: CardBack, + val playedDuringLastMove: Boolean +) + +/** + * A card with contextual information relative to the hand it is sitting in. The extra information is especially useful + * because it frees the client from a painful business logic implementation. + */ +data class HandCard( + val name: String, + val color: Color, + val requirements: ApiRequirements, + val chainParent: String?, + val chainChildren: List, + val image: String, + val back: CardBack, + val playability: CardPlayability +) + +data class CardBack(val image: String) + +enum class PlayabilityLevel { + CHAINABLE, + NO_REQUIREMENTS, + ENOUGH_RESOURCES, + ENOUGH_GOLD, + ENOUGH_GOLD_AND_RES, + REQUIRES_HELP, + MISSING_REQUIRED_GOLD, + MISSING_GOLD_FOR_RES, + UNAVAILABLE_RESOURCES, + INCOMPATIBLE_WITH_BOARD +} + +enum class Color(val isResource: Boolean) { + BROWN(true), + GREY(true), + YELLOW(false), + BLUE(false), + GREEN(false), + RED(false), + PURPLE(false) +} + +data class CardPlayability( + val isPlayable: Boolean, + val isChainable: Boolean = false, + val minPrice: Int = Int.MAX_VALUE, + val cheapestTransactions: Set = emptySet(), + val playabilityLevel: PlayabilityLevel +) { + val isFree: Boolean = minPrice == 0 +} diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/cards/HandRotationDirection.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/cards/HandRotationDirection.kt new file mode 100644 index 00000000..b4669fbb --- /dev/null +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/cards/HandRotationDirection.kt @@ -0,0 +1,11 @@ +package org.luxons.sevenwonders.game.api.cards + +enum class HandRotationDirection { + LEFT, + RIGHT; + + companion object { + // clockwise (pass to the left) at age 1, and alternating + fun forAge(age: Int): HandRotationDirection = if (age % 2 == 0) RIGHT else LEFT + } +} diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/resources/Resources.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/resources/Resources.kt new file mode 100644 index 00000000..fcfdd634 --- /dev/null +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/resources/Resources.kt @@ -0,0 +1,44 @@ +package org.luxons.sevenwonders.game.api.resources + +import org.luxons.sevenwonders.game.api.boards.RelativeBoardPosition + +enum class ResourceType(val symbol: Char) { + WOOD('W'), + STONE('S'), + ORE('O'), + CLAY('C'), + GLASS('G'), + PAPYRUS('P'), + LOOM('L'); + + companion object { + + private val typesPerSymbol = values().map { it.symbol to it }.toMap() + + fun fromSymbol(symbol: String): ResourceType { + if (symbol.length != 1) { + throw IllegalArgumentException("The given symbol must be a valid single-char resource type, got $symbol") + } + return fromSymbol(symbol[0]) + } + + fun fromSymbol(symbol: Char?): ResourceType = + typesPerSymbol[symbol] ?: throw IllegalArgumentException("Unknown resource type symbol '$symbol'") + } +} + +data class CountedResource( + val count: Int, + val type: ResourceType +) + +enum class Provider(val boardPosition: RelativeBoardPosition) { + LEFT_PLAYER(RelativeBoardPosition.LEFT), + RIGHT_PLAYER(RelativeBoardPosition.RIGHT) +} + +data class ResourceTransaction(val provider: Provider, val resources: List) + +typealias ResourceTransactions = Collection + +fun noTransactions(): ResourceTransactions = emptySet() diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/wonders/Wonders.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/wonders/Wonders.kt new file mode 100644 index 00000000..7148a924 --- /dev/null +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/wonders/Wonders.kt @@ -0,0 +1,32 @@ +package org.luxons.sevenwonders.game.api.wonders + +import org.luxons.sevenwonders.game.api.boards.ApiRequirements +import org.luxons.sevenwonders.game.api.cards.CardBack +import org.luxons.sevenwonders.game.api.cards.PlayabilityLevel +import org.luxons.sevenwonders.game.api.resources.ResourceTransactions +import org.luxons.sevenwonders.game.api.resources.ResourceType + +data class ApiWonder( + val name: String, + val initialResource: ResourceType, + val stages: List, + val image: String, + val nbBuiltStages: Int, + val buildability: WonderBuildability +) + +data class ApiWonderStage( + val cardBack: CardBack?, + val isBuilt: Boolean, + val requirements: ApiRequirements, + val builtDuringLastMove: Boolean +) + +data class WonderBuildability( + val isBuildable: Boolean, + val minPrice: Int = Int.MAX_VALUE, + val cheapestTransactions: Set = emptySet(), + val playabilityLevel: PlayabilityLevel +) { + val isFree: Boolean = minPrice == 0 +} diff --git a/sw-common-model/src/commonTest/kotlin/org/luxons/sevenwonders/game/api/WonderSidePickMethodTest.kt b/sw-common-model/src/commonTest/kotlin/org/luxons/sevenwonders/game/api/WonderSidePickMethodTest.kt new file mode 100644 index 00000000..9757ff86 --- /dev/null +++ b/sw-common-model/src/commonTest/kotlin/org/luxons/sevenwonders/game/api/WonderSidePickMethodTest.kt @@ -0,0 +1,87 @@ +package org.luxons.sevenwonders.game.api + +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)) + } +} diff --git a/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/CustomizableSettings.kt b/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/CustomizableSettings.kt deleted file mode 100644 index ac2c2b14..00000000 --- a/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/CustomizableSettings.kt +++ /dev/null @@ -1,45 +0,0 @@ -package org.luxons.sevenwonders.game.api - -import kotlin.random.Random - -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/main/kotlin/org/luxons/sevenwonders/game/api/Moves.kt b/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/Moves.kt deleted file mode 100644 index 79a238b0..00000000 --- a/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/Moves.kt +++ /dev/null @@ -1,49 +0,0 @@ -package org.luxons.sevenwonders.game.api - -import org.luxons.sevenwonders.game.api.cards.HandCard -import org.luxons.sevenwonders.game.api.cards.TableCard -import org.luxons.sevenwonders.game.api.resources.ResourceTransactions -import org.luxons.sevenwonders.game.api.resources.noTransactions -import org.luxons.sevenwonders.game.api.wonders.WonderBuildability - -enum class Action(val message: String) { - PLAY("Pick the card you want to play or discard."), - PLAY_2("Pick the first card you want to play or discard. Note that you have the ability to play these 2 last cards. You will choose how to play the last one during your next turn."), - PLAY_LAST("You have the special ability to play your last card. Choose how you want to play it."), - PICK_NEIGHBOR_GUILD("Choose a Guild card (purple) that you want to copy from one of your neighbours."), - WAIT("Please wait for other players to perform extra actions.") -} - -data class PlayerTurnInfo( - val playerIndex: Int, - val table: ApiTable, - val action: Action, - val hand: List, - val preparedMove: PlayedMove?, - val neighbourGuildCards: List -) { - val currentAge: Int = table.currentAge - val message: String = action.message - val wonderBuildability: WonderBuildability = table.boards[playerIndex].wonder.buildability -} - -data class PlayedMove( - val playerIndex: Int, - val type: MoveType, - val card: TableCard, - val transactions: ResourceTransactions -) - -data class PlayerMove( - val type: MoveType, - val cardName: String, - val transactions: ResourceTransactions = noTransactions() -) - -enum class MoveType { - PLAY, - PLAY_FREE, - UPGRADE_WONDER, - DISCARD, - COPY_GUILD; -} diff --git a/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/Table.kt b/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/Table.kt deleted file mode 100644 index 62f66b21..00000000 --- a/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/Table.kt +++ /dev/null @@ -1,15 +0,0 @@ -package org.luxons.sevenwonders.game.api - -import org.luxons.sevenwonders.game.api.boards.ApiBoard -import org.luxons.sevenwonders.game.api.cards.HandRotationDirection - -typealias Age = Int - -data class ApiTable( - val boards: List, - val currentAge: Age, - val handRotationDirection: HandRotationDirection, - val lastPlayedMoves: List -) { - val nbPlayers: Int = boards.size -} diff --git a/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/boards/Boards.kt b/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/boards/Boards.kt deleted file mode 100644 index 061bdcad..00000000 --- a/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/boards/Boards.kt +++ /dev/null @@ -1,40 +0,0 @@ -package org.luxons.sevenwonders.game.api.boards - -import org.luxons.sevenwonders.game.api.cards.TableCard -import org.luxons.sevenwonders.game.api.resources.CountedResource -import org.luxons.sevenwonders.game.api.resources.ResourceType -import org.luxons.sevenwonders.game.api.wonders.ApiWonder - -data class ApiBoard( - val playerIndex: Int, - val wonder: ApiWonder, - val production: ApiProduction, - val publicProduction: ApiProduction, - val science: ApiScience, - val military: ApiMilitary, - val playedCards: List>, - val gold: Int -) - -data class ApiRequirements( - val gold: Int = 0, - val resources: List = emptyList() -) - -data class ApiProduction( - val fixedResources: List, - val alternativeResources: Set> -) - -data class ApiMilitary( - val nbShields: Int, - val totalPoints: Int, - val nbDefeatTokens: Int -) - -data class ApiScience( - val jokers: Int, - val nbWheels: Int, - val nbCompasses: Int, - val nbTablets: Int -) diff --git a/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/boards/RelativeBoardPosition.kt b/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/boards/RelativeBoardPosition.kt deleted file mode 100644 index c7c3b5dc..00000000 --- a/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/boards/RelativeBoardPosition.kt +++ /dev/null @@ -1,16 +0,0 @@ -package org.luxons.sevenwonders.game.api.boards - -enum class RelativeBoardPosition(private val offset: Int) { - LEFT(-1), - SELF(0), - RIGHT(1); - - fun getIndexFrom(playerIndex: Int, nbPlayers: Int): Int = (playerIndex + offset) floorMod nbPlayers -} - -fun neighboursPositions() = listOf(RelativeBoardPosition.LEFT, RelativeBoardPosition.RIGHT) - -private infix fun Int.floorMod(divisor: Int): Int { - val rem = this % divisor - return if (rem >= 0) rem else rem + divisor -} diff --git a/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/cards/Cards.kt b/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/cards/Cards.kt deleted file mode 100644 index 4ccfe23b..00000000 --- a/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/cards/Cards.kt +++ /dev/null @@ -1,65 +0,0 @@ -package org.luxons.sevenwonders.game.api.cards - -import org.luxons.sevenwonders.game.api.boards.ApiRequirements -import org.luxons.sevenwonders.game.api.resources.ResourceTransactions - -data class TableCard( - val name: String, - val color: Color, - val requirements: ApiRequirements, - val chainParent: String?, - val chainChildren: List, - val image: String, - val back: CardBack, - val playedDuringLastMove: Boolean -) - -/** - * A card with contextual information relative to the hand it is sitting in. The extra information is especially useful - * because it frees the client from a painful business logic implementation. - */ -data class HandCard( - val name: String, - val color: Color, - val requirements: ApiRequirements, - val chainParent: String?, - val chainChildren: List, - val image: String, - val back: CardBack, - val playability: CardPlayability -) - -data class CardBack(val image: String) - -enum class PlayabilityLevel { - CHAINABLE, - NO_REQUIREMENTS, - ENOUGH_RESOURCES, - ENOUGH_GOLD, - ENOUGH_GOLD_AND_RES, - REQUIRES_HELP, - MISSING_REQUIRED_GOLD, - MISSING_GOLD_FOR_RES, - UNAVAILABLE_RESOURCES, - INCOMPATIBLE_WITH_BOARD -} - -enum class Color(val isResource: Boolean) { - BROWN(true), - GREY(true), - YELLOW(false), - BLUE(false), - GREEN(false), - RED(false), - PURPLE(false) -} - -data class CardPlayability( - val isPlayable: Boolean, - val isChainable: Boolean = false, - val minPrice: Int = Int.MAX_VALUE, - val cheapestTransactions: Set = emptySet(), - val playabilityLevel: PlayabilityLevel -) { - val isFree: Boolean = minPrice == 0 -} diff --git a/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/cards/HandRotationDirection.kt b/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/cards/HandRotationDirection.kt deleted file mode 100644 index b4669fbb..00000000 --- a/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/cards/HandRotationDirection.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.luxons.sevenwonders.game.api.cards - -enum class HandRotationDirection { - LEFT, - RIGHT; - - companion object { - // clockwise (pass to the left) at age 1, and alternating - fun forAge(age: Int): HandRotationDirection = if (age % 2 == 0) RIGHT else LEFT - } -} diff --git a/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/resources/Resources.kt b/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/resources/Resources.kt deleted file mode 100644 index fcfdd634..00000000 --- a/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/resources/Resources.kt +++ /dev/null @@ -1,44 +0,0 @@ -package org.luxons.sevenwonders.game.api.resources - -import org.luxons.sevenwonders.game.api.boards.RelativeBoardPosition - -enum class ResourceType(val symbol: Char) { - WOOD('W'), - STONE('S'), - ORE('O'), - CLAY('C'), - GLASS('G'), - PAPYRUS('P'), - LOOM('L'); - - companion object { - - private val typesPerSymbol = values().map { it.symbol to it }.toMap() - - fun fromSymbol(symbol: String): ResourceType { - if (symbol.length != 1) { - throw IllegalArgumentException("The given symbol must be a valid single-char resource type, got $symbol") - } - return fromSymbol(symbol[0]) - } - - fun fromSymbol(symbol: Char?): ResourceType = - typesPerSymbol[symbol] ?: throw IllegalArgumentException("Unknown resource type symbol '$symbol'") - } -} - -data class CountedResource( - val count: Int, - val type: ResourceType -) - -enum class Provider(val boardPosition: RelativeBoardPosition) { - LEFT_PLAYER(RelativeBoardPosition.LEFT), - RIGHT_PLAYER(RelativeBoardPosition.RIGHT) -} - -data class ResourceTransaction(val provider: Provider, val resources: List) - -typealias ResourceTransactions = Collection - -fun noTransactions(): ResourceTransactions = emptySet() diff --git a/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/wonders/Wonders.kt b/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/wonders/Wonders.kt deleted file mode 100644 index 7148a924..00000000 --- a/sw-common-model/src/main/kotlin/org/luxons/sevenwonders/game/api/wonders/Wonders.kt +++ /dev/null @@ -1,32 +0,0 @@ -package org.luxons.sevenwonders.game.api.wonders - -import org.luxons.sevenwonders.game.api.boards.ApiRequirements -import org.luxons.sevenwonders.game.api.cards.CardBack -import org.luxons.sevenwonders.game.api.cards.PlayabilityLevel -import org.luxons.sevenwonders.game.api.resources.ResourceTransactions -import org.luxons.sevenwonders.game.api.resources.ResourceType - -data class ApiWonder( - val name: String, - val initialResource: ResourceType, - val stages: List, - val image: String, - val nbBuiltStages: Int, - val buildability: WonderBuildability -) - -data class ApiWonderStage( - val cardBack: CardBack?, - val isBuilt: Boolean, - val requirements: ApiRequirements, - val builtDuringLastMove: Boolean -) - -data class WonderBuildability( - val isBuildable: Boolean, - val minPrice: Int = Int.MAX_VALUE, - val cheapestTransactions: Set = emptySet(), - val playabilityLevel: PlayabilityLevel -) { - val isFree: Boolean = minPrice == 0 -} diff --git a/sw-common-model/src/test/kotlin/org/luxons/sevenwonders/game/api/WonderSidePickMethodTest.kt b/sw-common-model/src/test/kotlin/org/luxons/sevenwonders/game/api/WonderSidePickMethodTest.kt deleted file mode 100644 index 9757ff86..00000000 --- a/sw-common-model/src/test/kotlin/org/luxons/sevenwonders/game/api/WonderSidePickMethodTest.kt +++ /dev/null @@ -1,87 +0,0 @@ -package org.luxons.sevenwonders.game.api - -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