From b30630782ee35cfed275217324f28285ad39d715 Mon Sep 17 00:00:00 2001 From: jbion Date: Sat, 7 Jul 2018 16:27:47 +0200 Subject: Kotlin mig: effects package --- .../serializers/ProductionIncreaseSerializer.kt | 14 +++----- .../data/serializers/ResourceTypeSerializer.kt | 2 +- .../data/serializers/ResourceTypesSerializer.kt | 2 +- .../game/data/serializers/ResourcesSerializer.kt | 2 +- .../data/serializers/ScienceProgressSerializer.kt | 4 +-- .../game/effects/BonusPerBoardElement.kt | 33 ++++++++++++++++++ .../luxons/sevenwonders/game/effects/Discount.kt | 19 ++++++++++ .../org/luxons/sevenwonders/game/effects/Effect.kt | 15 ++++++++ .../sevenwonders/game/effects/EndGameEffect.kt | 9 +++++ .../sevenwonders/game/effects/GoldIncrease.kt | 8 +++++ .../game/effects/InstantOwnBoardEffect.kt | 14 ++++++++ .../game/effects/MilitaryReinforcements.kt | 8 +++++ .../game/effects/ProductionIncrease.kt | 14 ++++++++ .../sevenwonders/game/effects/RawPointsIncrease.kt | 8 +++++ .../sevenwonders/game/effects/ScienceProgress.kt | 9 +++++ .../sevenwonders/game/effects/SpecialAbility.kt | 40 ++++++++++++++++++++++ .../game/effects/SpecialAbilityActivation.kt | 10 ++++++ 17 files changed, 196 insertions(+), 15 deletions(-) create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/BonusPerBoardElement.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/Discount.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/Effect.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/EndGameEffect.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/GoldIncrease.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/InstantOwnBoardEffect.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/MilitaryReinforcements.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/ProductionIncrease.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/RawPointsIncrease.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/ScienceProgress.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/SpecialAbility.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/SpecialAbilityActivation.kt (limited to 'game-engine/src/main/kotlin/org/luxons') diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializer.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializer.kt index 578f816b..112c0adc 100644 --- a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializer.kt +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializer.kt @@ -29,20 +29,16 @@ class ProductionIncreaseSerializer : JsonSerializer, JsonDes typeOfT: Type, context: JsonDeserializationContext ): ProductionIncrease { - var json = json - val productionIncrease = ProductionIncrease() + var prodJson = json - var resourcesStr = json.asString + var resourcesStr = prodJson.asString val isSellable = !resourcesStr.startsWith("(") if (!isSellable) { resourcesStr = unwrapBrackets(resourcesStr) - json = JsonPrimitive(resourcesStr) + prodJson = JsonPrimitive(resourcesStr) } - productionIncrease.isSellable = isSellable - - val production = context.deserialize(json, Production::class.java) - productionIncrease.production = production - return productionIncrease + val production = context.deserialize(prodJson, Production::class.java) + return ProductionIncrease(production, isSellable) } private fun unwrapBrackets(str: String): String { diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourceTypeSerializer.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourceTypeSerializer.kt index 1de9334a..74dee483 100644 --- a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourceTypeSerializer.kt +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourceTypeSerializer.kt @@ -12,7 +12,7 @@ import com.google.gson.JsonPrimitive import com.google.gson.JsonSerializationContext import com.google.gson.JsonSerializer -internal class ResourceTypeSerializer : JsonSerializer, JsonDeserializer { +class ResourceTypeSerializer : JsonSerializer, JsonDeserializer { override fun serialize(type: ResourceType, typeOfSrc: Type, context: JsonSerializationContext): JsonElement { return JsonPrimitive(type.symbol!!) diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializer.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializer.kt index 9ba21043..75fcabf0 100644 --- a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializer.kt +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializer.kt @@ -12,7 +12,7 @@ import com.google.gson.JsonPrimitive import com.google.gson.JsonSerializationContext import com.google.gson.JsonSerializer -internal class ResourceTypesSerializer : JsonSerializer>, JsonDeserializer> { +class ResourceTypesSerializer : JsonSerializer>, JsonDeserializer> { override fun serialize( resources: List, diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.kt index 2baf7a35..0a60e4cf 100644 --- a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.kt +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.kt @@ -15,7 +15,7 @@ import com.google.gson.JsonPrimitive import com.google.gson.JsonSerializationContext import com.google.gson.JsonSerializer -internal class ResourcesSerializer : JsonSerializer, JsonDeserializer { +class ResourcesSerializer : JsonSerializer, JsonDeserializer { override fun serialize(resources: Resources, typeOfSrc: Type, context: JsonSerializationContext): JsonElement { val s = resources.asList().map { it.symbol }.joinToString("") diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializer.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializer.kt index ed383d63..46ebeb25 100644 --- a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializer.kt +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializer.kt @@ -39,15 +39,13 @@ internal class ScienceProgressSerializer : JsonSerializer, Json @Throws(JsonParseException::class) override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): ScienceProgress { val s = json.asString - val scienceProgress = ScienceProgress() val science = Science() if ("any" == s) { science.addJoker(1) } else { science.add(deserializeScienceType(json, context), 1) } - scienceProgress.science = science - return scienceProgress + return ScienceProgress(science) } private fun deserializeScienceType(json: JsonElement, context: JsonDeserializationContext): ScienceType { diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/BonusPerBoardElement.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/BonusPerBoardElement.kt new file mode 100644 index 00000000..104dfc77 --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/BonusPerBoardElement.kt @@ -0,0 +1,33 @@ +package org.luxons.sevenwonders.game.effects + +import org.luxons.sevenwonders.game.api.Table +import org.luxons.sevenwonders.game.boards.Board +import org.luxons.sevenwonders.game.boards.BoardElementType +import org.luxons.sevenwonders.game.boards.RelativeBoardPosition +import org.luxons.sevenwonders.game.cards.Color + +data class BonusPerBoardElement ( + val boards: List, + val type: BoardElementType, + val gold: Int = 0, + val points: Int = 0, + // only relevant if type=CARD + val colors: List? = null +) : Effect { + + override fun apply(table: Table, playerIndex: Int) { + val goldGain = gold * computeNbOfMatchingElementsIn(table, playerIndex) + val board = table.getBoard(playerIndex) + board.addGold(goldGain) + } + + override fun computePoints(table: Table, playerIndex: Int): Int = + points * computeNbOfMatchingElementsIn(table, playerIndex) + + private fun computeNbOfMatchingElementsIn(table: Table, playerIndex: Int): Int = boards + .map { pos -> table.getBoard(playerIndex, pos) } + .map(::computeNbOfMatchingElementsIn) + .sum() + + private fun computeNbOfMatchingElementsIn(board: Board): Int = type.getElementCount(board, colors) +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/Discount.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/Discount.kt new file mode 100644 index 00000000..b1455397 --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/Discount.kt @@ -0,0 +1,19 @@ +package org.luxons.sevenwonders.game.effects + +import org.luxons.sevenwonders.game.boards.Board +import org.luxons.sevenwonders.game.resources.Provider +import org.luxons.sevenwonders.game.resources.ResourceType + +data class Discount( + val resourceTypes: List = emptyList(), + val providers: List = emptyList(), + val discountedPrice: Int = 1 +) : InstantOwnBoardEffect() { + + public override fun apply(board: Board) { + val rules = board.tradingRules + for (type in resourceTypes) { + providers.forEach { rules.setCost(type, it, discountedPrice) } + } + } +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/Effect.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/Effect.kt new file mode 100644 index 00000000..3bf48086 --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/Effect.kt @@ -0,0 +1,15 @@ +package org.luxons.sevenwonders.game.effects + +import org.luxons.sevenwonders.game.api.Table + +/** + * Represents an effect than can be applied to a player's board when playing a card or building his wonder. The effect + * may affect (or depend on) the adjacent boards. It can have an instantaneous effect on the board, or be postponed to + * the end of game where point calculations take place. + */ +interface Effect { + + fun apply(table: Table, playerIndex: Int) + + fun computePoints(table: Table, playerIndex: Int): Int +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/EndGameEffect.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/EndGameEffect.kt new file mode 100644 index 00000000..392f53b9 --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/EndGameEffect.kt @@ -0,0 +1,9 @@ +package org.luxons.sevenwonders.game.effects + +import org.luxons.sevenwonders.game.api.Table + +abstract class EndGameEffect : Effect { + + // EndGameEffects don't do anything when applied to the board, they simply give more points in the end + override fun apply(table: Table, playerIndex: Int) = Unit +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/GoldIncrease.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/GoldIncrease.kt new file mode 100644 index 00000000..0d206231 --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/GoldIncrease.kt @@ -0,0 +1,8 @@ +package org.luxons.sevenwonders.game.effects + +import org.luxons.sevenwonders.game.boards.Board + +data class GoldIncrease(val amount: Int) : InstantOwnBoardEffect() { + + public override fun apply(board: Board) = board.addGold(amount) +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/InstantOwnBoardEffect.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/InstantOwnBoardEffect.kt new file mode 100644 index 00000000..fb26dcce --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/InstantOwnBoardEffect.kt @@ -0,0 +1,14 @@ +package org.luxons.sevenwonders.game.effects + +import org.luxons.sevenwonders.game.api.Table +import org.luxons.sevenwonders.game.boards.Board + +abstract class InstantOwnBoardEffect : Effect { + + override fun apply(table: Table, playerIndex: Int) = apply(table.getBoard(playerIndex)) + + protected abstract fun apply(board: Board) + + // InstantEffects are only important when applied to the board, they don't give extra points in the end + override fun computePoints(table: Table, playerIndex: Int): Int = 0 +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/MilitaryReinforcements.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/MilitaryReinforcements.kt new file mode 100644 index 00000000..ad4d64eb --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/MilitaryReinforcements.kt @@ -0,0 +1,8 @@ +package org.luxons.sevenwonders.game.effects + +import org.luxons.sevenwonders.game.boards.Board + +data class MilitaryReinforcements(val count: Int) : InstantOwnBoardEffect() { + + public override fun apply(board: Board) = board.military.addShields(count) +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/ProductionIncrease.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/ProductionIncrease.kt new file mode 100644 index 00000000..aa56705e --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/ProductionIncrease.kt @@ -0,0 +1,14 @@ +package org.luxons.sevenwonders.game.effects + +import org.luxons.sevenwonders.game.boards.Board +import org.luxons.sevenwonders.game.resources.Production + +data class ProductionIncrease(val production: Production, val isSellable: Boolean) : InstantOwnBoardEffect() { + + public override fun apply(board: Board) { + board.production.addAll(production) + if (isSellable) { + board.publicProduction.addAll(production) + } + } +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/RawPointsIncrease.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/RawPointsIncrease.kt new file mode 100644 index 00000000..ed6eb332 --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/RawPointsIncrease.kt @@ -0,0 +1,8 @@ +package org.luxons.sevenwonders.game.effects + +import org.luxons.sevenwonders.game.api.Table + +data class RawPointsIncrease(val points: Int) : EndGameEffect() { + + override fun computePoints(table: Table, playerIndex: Int): Int = points +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/ScienceProgress.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/ScienceProgress.kt new file mode 100644 index 00000000..850f8ec3 --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/ScienceProgress.kt @@ -0,0 +1,9 @@ +package org.luxons.sevenwonders.game.effects + +import org.luxons.sevenwonders.game.boards.Board +import org.luxons.sevenwonders.game.boards.Science + +class ScienceProgress(val science: Science) : InstantOwnBoardEffect() { + + public override fun apply(board: Board) = board.science.addAll(science) +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/SpecialAbility.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/SpecialAbility.kt new file mode 100644 index 00000000..30d57e27 --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/SpecialAbility.kt @@ -0,0 +1,40 @@ +package org.luxons.sevenwonders.game.effects + +import org.luxons.sevenwonders.game.api.Table +import org.luxons.sevenwonders.game.boards.Board +import org.luxons.sevenwonders.game.cards.Card + +enum class SpecialAbility { + + /** + * The player can play the last card of each age instead of discarding it. This card can be played by paying its + * cost, discarded to gain 3 coins or used in the construction of his or her Wonder. + */ + PLAY_LAST_CARD, + + /** + * Once per age, a player can construct a building from his or her hand for free. + */ + ONE_FREE_PER_AGE, + + /** + * The player can look at all cards discarded since the beginning of the game, pick one and build it for free. + */ + PLAY_DISCARDED, + + /** + * The player can, at the end of the game, "copy" a Guild of his or her choice (purple card), built by one of his or + * her two neighboring cities. + */ + COPY_GUILD { + override fun computePoints(table: Table, playerIndex: Int): Int { + val copiedGuild = table.getBoard(playerIndex).copiedGuild + ?: throw IllegalStateException("The copied Guild has not been chosen, cannot compute points") + return copiedGuild.effects.stream().mapToInt { e -> e.computePoints(table, playerIndex) }.sum() + } + }; + + fun apply(board: Board) = board.addSpecial(this) + + open fun computePoints(table: Table, playerIndex: Int): Int = 0 +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/SpecialAbilityActivation.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/SpecialAbilityActivation.kt new file mode 100644 index 00000000..fd83d7fe --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/effects/SpecialAbilityActivation.kt @@ -0,0 +1,10 @@ +package org.luxons.sevenwonders.game.effects + +import org.luxons.sevenwonders.game.api.Table + +data class SpecialAbilityActivation(val specialAbility: SpecialAbility) : Effect { + + override fun apply(table: Table, playerIndex: Int) = specialAbility.apply(table.getBoard(playerIndex)) + + override fun computePoints(table: Table, playerIndex: Int): Int = specialAbility.computePoints(table, playerIndex) +} -- cgit