summaryrefslogtreecommitdiff
path: root/sw-common-model/src/commonMain/kotlin
diff options
context:
space:
mode:
Diffstat (limited to 'sw-common-model/src/commonMain/kotlin')
-rw-r--r--sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/Boards.kt44
-rw-r--r--sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/CustomizableSettings.kt45
-rw-r--r--sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/PlayerTurnInfo.kt35
-rw-r--r--sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/Table.kt24
-rw-r--r--sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/boards/RelativeBoardPosition.kt16
-rw-r--r--sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/cards/Cards.kt65
-rw-r--r--sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/cards/HandRotationDirection.kt11
-rw-r--r--sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/moves/MoveType.kt9
-rw-r--r--sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/resources/Provider.kt8
-rw-r--r--sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/resources/ResourceTransactions.kt9
-rw-r--r--sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/resources/ResourceType.kt26
-rw-r--r--sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/wonders/Wonder.kt32
12 files changed, 324 insertions, 0 deletions
diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/Boards.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/Boards.kt
new file mode 100644
index 00000000..698615e9
--- /dev/null
+++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/Boards.kt
@@ -0,0 +1,44 @@
+package org.luxons.sevenwonders.game.api
+
+import org.luxons.sevenwonders.game.cards.TableCard
+import org.luxons.sevenwonders.game.resources.ResourceType
+import org.luxons.sevenwonders.game.wonders.ApiWonder
+
+data class Board(
+ val playerIndex: Int,
+ val wonder: ApiWonder,
+ val production: ApiProduction,
+ val publicProduction: ApiProduction,
+ val science: ApiScience,
+ val military: ApiMilitary,
+ val playedCards: List<List<TableCard>>,
+ val gold: Int
+)
+
+data class ApiRequirements(
+ val gold: Int = 0,
+ val resources: List<ApiCountedResource> = emptyList()
+)
+
+data class ApiProduction(
+ val fixedResources: List<ApiCountedResource>,
+ val alternativeResources: Set<Set<ResourceType>>
+)
+
+data class ApiCountedResource(
+ val count: Int,
+ val type: ResourceType
+)
+
+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/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<Int, Int> = 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/PlayerTurnInfo.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/PlayerTurnInfo.kt
new file mode 100644
index 00000000..c5feb6c5
--- /dev/null
+++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/PlayerTurnInfo.kt
@@ -0,0 +1,35 @@
+package org.luxons.sevenwonders.game.api
+
+import org.luxons.sevenwonders.game.cards.HandCard
+import org.luxons.sevenwonders.game.cards.TableCard
+import org.luxons.sevenwonders.game.moves.MoveType
+import org.luxons.sevenwonders.game.resources.ResourceTransactions
+import org.luxons.sevenwonders.game.resources.noTransactions
+import org.luxons.sevenwonders.game.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: Table,
+ val action: Action,
+ val hand: List<HandCard>,
+ val preparedMove: PlayedMove?,
+ val neighbourGuildCards: List<TableCard>
+) {
+ val currentAge: Int = table.currentAge
+ val message: String = action.message
+ val wonderBuildability: WonderBuildability = table.boards[playerIndex].wonder.buildability
+}
+
+data class PlayerMove(
+ val type: MoveType,
+ val cardName: String,
+ val transactions: ResourceTransactions = noTransactions()
+)
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..23ab6ee2
--- /dev/null
+++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/api/Table.kt
@@ -0,0 +1,24 @@
+package org.luxons.sevenwonders.game.api
+
+import org.luxons.sevenwonders.game.cards.HandRotationDirection
+import org.luxons.sevenwonders.game.cards.TableCard
+import org.luxons.sevenwonders.game.moves.MoveType
+import org.luxons.sevenwonders.game.resources.ResourceTransactions
+
+typealias Age = Int
+
+data class Table(
+ val boards: List<Board>,
+ val currentAge: Age,
+ val handRotationDirection: HandRotationDirection,
+ val lastPlayedMoves: List<PlayedMove>
+) {
+ val nbPlayers: Int = boards.size
+}
+
+data class PlayedMove(
+ val playerIndex: Int,
+ val type: MoveType,
+ val card: TableCard,
+ val transactions: ResourceTransactions
+)
diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/boards/RelativeBoardPosition.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/boards/RelativeBoardPosition.kt
new file mode 100644
index 00000000..3a8387a3
--- /dev/null
+++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/boards/RelativeBoardPosition.kt
@@ -0,0 +1,16 @@
+package org.luxons.sevenwonders.game.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/cards/Cards.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/cards/Cards.kt
new file mode 100644
index 00000000..ab0e0297
--- /dev/null
+++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/cards/Cards.kt
@@ -0,0 +1,65 @@
+package org.luxons.sevenwonders.game.cards
+
+import org.luxons.sevenwonders.game.api.ApiRequirements
+import org.luxons.sevenwonders.game.resources.ResourceTransactions
+
+data class TableCard(
+ val name: String,
+ val color: Color,
+ val requirements: ApiRequirements,
+ val chainParent: String?,
+ val chainChildren: List<String>,
+ 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<String>,
+ 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<ResourceTransactions> = emptySet(),
+ val playabilityLevel: PlayabilityLevel
+) {
+ val isFree: Boolean = minPrice == 0
+}
diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/cards/HandRotationDirection.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/cards/HandRotationDirection.kt
new file mode 100644
index 00000000..a10ec19f
--- /dev/null
+++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/cards/HandRotationDirection.kt
@@ -0,0 +1,11 @@
+package org.luxons.sevenwonders.game.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/moves/MoveType.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/moves/MoveType.kt
new file mode 100644
index 00000000..d982c100
--- /dev/null
+++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/moves/MoveType.kt
@@ -0,0 +1,9 @@
+package org.luxons.sevenwonders.game.moves
+
+enum class MoveType {
+ PLAY,
+ PLAY_FREE,
+ UPGRADE_WONDER,
+ DISCARD,
+ COPY_GUILD;
+}
diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/resources/Provider.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/resources/Provider.kt
new file mode 100644
index 00000000..5d0f3159
--- /dev/null
+++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/resources/Provider.kt
@@ -0,0 +1,8 @@
+package org.luxons.sevenwonders.game.resources
+
+import org.luxons.sevenwonders.game.boards.RelativeBoardPosition
+
+enum class Provider(val boardPosition: RelativeBoardPosition) {
+ LEFT_PLAYER(RelativeBoardPosition.LEFT),
+ RIGHT_PLAYER(RelativeBoardPosition.RIGHT)
+}
diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/resources/ResourceTransactions.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/resources/ResourceTransactions.kt
new file mode 100644
index 00000000..77a8670d
--- /dev/null
+++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/resources/ResourceTransactions.kt
@@ -0,0 +1,9 @@
+package org.luxons.sevenwonders.game.resources
+
+import org.luxons.sevenwonders.game.api.ApiCountedResource
+
+typealias ResourceTransactions = Collection<ResourceTransaction>
+
+data class ResourceTransaction(val provider: Provider, val resources: List<ApiCountedResource>)
+
+fun noTransactions(): ResourceTransactions = emptySet()
diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/resources/ResourceType.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/resources/ResourceType.kt
new file mode 100644
index 00000000..5c92b887
--- /dev/null
+++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/resources/ResourceType.kt
@@ -0,0 +1,26 @@
+package org.luxons.sevenwonders.game.resources
+
+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'")
+ }
+}
diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/wonders/Wonder.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/wonders/Wonder.kt
new file mode 100644
index 00000000..6480e935
--- /dev/null
+++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/game/wonders/Wonder.kt
@@ -0,0 +1,32 @@
+package org.luxons.sevenwonders.game.wonders
+
+import org.luxons.sevenwonders.game.api.ApiRequirements
+import org.luxons.sevenwonders.game.cards.CardBack
+import org.luxons.sevenwonders.game.cards.PlayabilityLevel
+import org.luxons.sevenwonders.game.resources.ResourceTransactions
+import org.luxons.sevenwonders.game.resources.ResourceType
+
+data class ApiWonder(
+ val name: String,
+ val initialResource: ResourceType,
+ val stages: List<ApiWonderStage>,
+ 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<ResourceTransactions> = emptySet(),
+ val playabilityLevel: PlayabilityLevel
+) {
+ val isFree: Boolean = minPrice == 0
+}
bgstack15