summaryrefslogtreecommitdiff
path: root/sw-engine/src/main/kotlin
diff options
context:
space:
mode:
authorjoffrey-bion <joffrey.bion@gmail.com>2021-01-29 03:02:48 +0100
committerjoffrey-bion <joffrey.bion@gmail.com>2021-01-29 03:02:48 +0100
commit459ee67652d01fd37b3dd696e4fa96f123ae44ee (patch)
treedb38c61cd5c0816eebb28561fc1bce5ec1b6f305 /sw-engine/src/main/kotlin
parentClarify docker local run (diff)
downloadseven-wonders-459ee67652d01fd37b3dd696e4fa96f123ae44ee.tar.gz
seven-wonders-459ee67652d01fd37b3dd696e4fa96f123ae44ee.tar.bz2
seven-wonders-459ee67652d01fd37b3dd696e4fa96f123ae44ee.zip
Move from Gson to Kotlin Serialization for definitions
Diffstat (limited to 'sw-engine/src/main/kotlin')
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/cards/Requirements.kt2
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/GameDefinition.kt50
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/definitions/CardDefinition.kt12
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/definitions/DecksDefinition.kt11
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/definitions/EffectsDefinition.kt14
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/definitions/WonderDefinition.kt6
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/NumericEffectSerializer.kt38
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ProductionIncreaseSerializer.kt47
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ProductionSerializer.kt56
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourceTypeSerializer.kt30
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourceTypesSerializer.kt35
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourcesSerializer.kt33
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ScienceProgressSerializer.kt55
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/effects/BonusPerBoardElement.kt2
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/effects/Discount.kt4
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/effects/ProductionIncrease.kt11
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/effects/ScienceProgress.kt3
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/resources/Production.kt3
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/resources/Resources.kt3
19 files changed, 153 insertions, 262 deletions
diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/cards/Requirements.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/cards/Requirements.kt
index b78a5057..1d03aa76 100644
--- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/cards/Requirements.kt
+++ b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/cards/Requirements.kt
@@ -1,11 +1,13 @@
package org.luxons.sevenwonders.engine.cards
+import kotlinx.serialization.Serializable
import org.luxons.sevenwonders.engine.Player
import org.luxons.sevenwonders.engine.boards.Board
import org.luxons.sevenwonders.engine.resources.*
import org.luxons.sevenwonders.model.resources.ResourceTransactions
import org.luxons.sevenwonders.model.resources.bestPrice
+@Serializable
data class Requirements internal constructor(
val gold: Int = 0,
val resources: Resources = emptyResources(),
diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/GameDefinition.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/GameDefinition.kt
index 07c101e6..64d6be3b 100644
--- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/GameDefinition.kt
+++ b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/GameDefinition.kt
@@ -1,34 +1,20 @@
package org.luxons.sevenwonders.engine.data
-import com.github.salomonbrys.kotson.typeToken
-import com.google.gson.Gson
-import com.google.gson.GsonBuilder
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.decodeFromString
+import kotlinx.serialization.json.Json
import org.luxons.sevenwonders.engine.Game
import org.luxons.sevenwonders.engine.boards.Board
import org.luxons.sevenwonders.engine.data.definitions.DecksDefinition
import org.luxons.sevenwonders.engine.data.definitions.WonderDefinition
-import org.luxons.sevenwonders.engine.data.serializers.NumericEffectSerializer
-import org.luxons.sevenwonders.engine.data.serializers.ProductionIncreaseSerializer
-import org.luxons.sevenwonders.engine.data.serializers.ProductionSerializer
-import org.luxons.sevenwonders.engine.data.serializers.ResourceTypeSerializer
-import org.luxons.sevenwonders.engine.data.serializers.ResourceTypesSerializer
-import org.luxons.sevenwonders.engine.data.serializers.ResourcesSerializer
-import org.luxons.sevenwonders.engine.data.serializers.ScienceProgressSerializer
-import org.luxons.sevenwonders.engine.effects.GoldIncrease
-import org.luxons.sevenwonders.engine.effects.MilitaryReinforcements
-import org.luxons.sevenwonders.engine.effects.ProductionIncrease
-import org.luxons.sevenwonders.engine.effects.RawPointsIncrease
-import org.luxons.sevenwonders.engine.effects.ScienceProgress
-import org.luxons.sevenwonders.engine.resources.Production
-import org.luxons.sevenwonders.engine.resources.Resources
import org.luxons.sevenwonders.model.Age
import org.luxons.sevenwonders.model.Settings
-import org.luxons.sevenwonders.model.resources.ResourceType
import org.luxons.sevenwonders.model.wonders.AssignedWonder
import org.luxons.sevenwonders.model.wonders.PreGameWonder
internal const val LAST_AGE: Age = 3
+@Serializable
internal data class GlobalRules(
val minPlayers: Int,
val maxPlayers: Int,
@@ -63,36 +49,18 @@ class GameDefinition internal constructor(
companion object {
fun load(): GameDefinition {
- val gson: Gson = createGson()
- val rules = loadJson("global_rules.json", GlobalRules::class.java, gson)
- val wonders = loadJson("wonders.json", Array<WonderDefinition>::class.java, gson)
- val decksDefinition = loadJson("cards.json", DecksDefinition::class.java, gson)
+ val rules = loadJson<GlobalRules>("global_rules.json")
+ val wonders = loadJson<Array<WonderDefinition>>("wonders.json")
+ val decksDefinition = loadJson<DecksDefinition>("cards.json")
return GameDefinition(rules, wonders.toList(), decksDefinition)
}
}
}
-private fun <T> loadJson(filename: String, clazz: Class<T>, gson: Gson): T {
+private inline fun <reified T> loadJson(filename: String): T {
val packageAsPath = GameDefinition::class.java.`package`.name.replace('.', '/')
val resourcePath = "/$packageAsPath/$filename"
val resource = GameDefinition::class.java.getResource(resourcePath)
val json = resource.readText()
- return gson.fromJson(json, clazz)
+ return Json.decodeFromString(json)
}
-
-private fun createGson(): Gson {
- return GsonBuilder().disableHtmlEscaping()
- .registerTypeAdapter<Resources>(ResourcesSerializer())
- .registerTypeAdapter<ResourceType>(ResourceTypeSerializer())
- .registerTypeAdapter<List<ResourceType>>(ResourceTypesSerializer())
- .registerTypeAdapter<Production>(ProductionSerializer())
- .registerTypeAdapter<ProductionIncrease>(ProductionIncreaseSerializer())
- .registerTypeAdapter<MilitaryReinforcements>(NumericEffectSerializer())
- .registerTypeAdapter<RawPointsIncrease>(NumericEffectSerializer())
- .registerTypeAdapter<GoldIncrease>(NumericEffectSerializer())
- .registerTypeAdapter<ScienceProgress>(ScienceProgressSerializer())
- .create()
-}
-
-private inline fun <reified T : Any> GsonBuilder.registerTypeAdapter(typeAdapter: Any): GsonBuilder =
- this.registerTypeAdapter(typeToken<T>(), typeAdapter)
diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/definitions/CardDefinition.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/definitions/CardDefinition.kt
index cc42641a..0b9fbb7d 100644
--- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/definitions/CardDefinition.kt
+++ b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/definitions/CardDefinition.kt
@@ -1,21 +1,23 @@
package org.luxons.sevenwonders.engine.data.definitions
+import kotlinx.serialization.Serializable
import org.luxons.sevenwonders.engine.cards.Card
import org.luxons.sevenwonders.engine.cards.Requirements
import org.luxons.sevenwonders.model.cards.CardBack
import org.luxons.sevenwonders.model.cards.Color
+@Serializable
internal class CardDefinition(
private val name: String,
private val color: Color,
- private val requirements: Requirements?,
private val effect: EffectsDefinition,
- private val chainParent: String?,
- private val chainChildren: List<String>?,
+ private val requirements: Requirements? = null,
+ private val chainParent: String? = null,
+ private val chainChildren: List<String>? = null,
+ private val countPerNbPlayer: Map<Int, Int>? = null,
private val image: String,
- private val countPerNbPlayer: Map<Int, Int>,
) {
- fun create(back: CardBack, nbPlayers: Int): List<Card> = List(countPerNbPlayer[nbPlayers] ?: 0) { create(back) }
+ fun create(back: CardBack, nbPlayers: Int): List<Card> = List(countPerNbPlayer!![nbPlayers] ?: 0) { create(back) }
fun create(back: CardBack): Card {
val reqs = requirements ?: Requirements()
diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/definitions/DecksDefinition.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/definitions/DecksDefinition.kt
index f3dc42f4..ed2b1214 100644
--- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/definitions/DecksDefinition.kt
+++ b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/definitions/DecksDefinition.kt
@@ -1,17 +1,20 @@
package org.luxons.sevenwonders.engine.data.definitions
+import kotlinx.serialization.Serializable
import org.luxons.sevenwonders.engine.cards.Card
import org.luxons.sevenwonders.engine.cards.Decks
import org.luxons.sevenwonders.model.cards.CardBack
import kotlin.random.Random
+@Serializable
internal class DeckDefinition(
val cards: List<CardDefinition>,
val backImage: String,
) {
- fun create(nbPlayers: Int): List<Card> = cards.flatMap { it.create(CardBack(backImage), nbPlayers) }
+ fun prepareFor(nbPlayers: Int): List<Card> = cards.flatMap { it.create(CardBack(backImage), nbPlayers) }
}
+@Serializable
internal class DecksDefinition(
private val age1: DeckDefinition,
private val age2: DeckDefinition,
@@ -20,9 +23,9 @@ internal class DecksDefinition(
) {
fun prepareDecks(nbPlayers: Int, random: Random) = Decks(
mapOf(
- 1 to age1.create(nbPlayers).shuffled(random),
- 2 to age2.create(nbPlayers).shuffled(random),
- 3 to (age3.create(nbPlayers) + pickGuildCards(nbPlayers, random)).shuffled(random),
+ 1 to age1.prepareFor(nbPlayers).shuffled(random),
+ 2 to age2.prepareFor(nbPlayers).shuffled(random),
+ 3 to (age3.prepareFor(nbPlayers) + pickGuildCards(nbPlayers, random)).shuffled(random),
),
)
diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/definitions/EffectsDefinition.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/definitions/EffectsDefinition.kt
index 86829eca..efd92c90 100644
--- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/definitions/EffectsDefinition.kt
+++ b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/definitions/EffectsDefinition.kt
@@ -1,5 +1,6 @@
package org.luxons.sevenwonders.engine.data.definitions
+import kotlinx.serialization.Serializable
import org.luxons.sevenwonders.engine.effects.BonusPerBoardElement
import org.luxons.sevenwonders.engine.effects.Discount
import org.luxons.sevenwonders.engine.effects.Effect
@@ -11,24 +12,25 @@ import org.luxons.sevenwonders.engine.effects.ScienceProgress
import org.luxons.sevenwonders.engine.effects.SpecialAbility
import org.luxons.sevenwonders.engine.effects.SpecialAbilityActivation
+@Serializable
internal class EffectsDefinition(
- private val gold: GoldIncrease? = null,
- private val military: MilitaryReinforcements? = null,
+ private val gold: Int? = null,
+ private val military: Int? = null,
private val science: ScienceProgress? = null,
private val discount: Discount? = null,
private val perBoardElement: BonusPerBoardElement? = null,
private val production: ProductionIncrease? = null,
- private val points: RawPointsIncrease? = null,
+ private val points: Int? = null,
private val action: SpecialAbility? = null,
) {
fun create(): List<Effect> = mutableListOf<Effect>().apply {
- gold?.let { add(it) }
- military?.let { add(it) }
+ gold?.let { add(GoldIncrease(it)) }
+ military?.let { add(MilitaryReinforcements(it)) }
science?.let { add(it) }
discount?.let { add(it) }
perBoardElement?.let { add(it) }
production?.let { add(it) }
- points?.let { add(it) }
+ points?.let { add(RawPointsIncrease(it)) }
action?.let { add(SpecialAbilityActivation(it)) }
}
}
diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/definitions/WonderDefinition.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/definitions/WonderDefinition.kt
index 2a59f6dc..3d9956bc 100644
--- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/definitions/WonderDefinition.kt
+++ b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/definitions/WonderDefinition.kt
@@ -1,12 +1,15 @@
package org.luxons.sevenwonders.engine.data.definitions
+import kotlinx.serialization.Serializable
import org.luxons.sevenwonders.engine.cards.Requirements
+import org.luxons.sevenwonders.engine.data.serializers.ResourceTypeSerializer
import org.luxons.sevenwonders.engine.wonders.Wonder
import org.luxons.sevenwonders.engine.wonders.WonderStage
import org.luxons.sevenwonders.model.resources.ResourceType
import org.luxons.sevenwonders.model.wonders.WonderName
import org.luxons.sevenwonders.model.wonders.WonderSide
+@Serializable
internal class WonderDefinition(
val name: WonderName,
val sides: Map<WonderSide, WonderSideDefinition>,
@@ -14,7 +17,9 @@ internal class WonderDefinition(
fun create(wonderSide: WonderSide): Wonder = sides[wonderSide]!!.createWonder(name)
}
+@Serializable
internal class WonderSideDefinition(
+ @Serializable(with = ResourceTypeSerializer::class)
private val initialResource: ResourceType,
private val stages: List<WonderStageDefinition>,
val image: String,
@@ -22,6 +27,7 @@ internal class WonderSideDefinition(
fun createWonder(name: String): Wonder = Wonder(name, initialResource, stages.map { it.create() }, image)
}
+@Serializable
internal class WonderStageDefinition(
private val requirements: Requirements,
private val effects: EffectsDefinition,
diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/NumericEffectSerializer.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/NumericEffectSerializer.kt
deleted file mode 100644
index a149e8a0..00000000
--- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/NumericEffectSerializer.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.luxons.sevenwonders.engine.data.serializers
-
-import com.google.gson.JsonDeserializationContext
-import com.google.gson.JsonDeserializer
-import com.google.gson.JsonElement
-import com.google.gson.JsonParseException
-import com.google.gson.JsonPrimitive
-import com.google.gson.JsonSerializationContext
-import com.google.gson.JsonSerializer
-import org.luxons.sevenwonders.engine.effects.Effect
-import org.luxons.sevenwonders.engine.effects.GoldIncrease
-import org.luxons.sevenwonders.engine.effects.MilitaryReinforcements
-import org.luxons.sevenwonders.engine.effects.RawPointsIncrease
-import java.lang.reflect.Type
-
-internal class NumericEffectSerializer : JsonSerializer<Effect>, JsonDeserializer<Effect> {
-
- override fun serialize(effect: Effect, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
- val value: Int = when (effect) {
- is MilitaryReinforcements -> effect.count
- is GoldIncrease -> effect.amount
- is RawPointsIncrease -> effect.points
- else -> throw IllegalArgumentException("Unknown numeric effect " + effect.javaClass.name)
- }
- return JsonPrimitive(value)
- }
-
- @Throws(JsonParseException::class)
- override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Effect {
- val value = json.asInt
- return when (typeOfT) {
- MilitaryReinforcements::class.java -> MilitaryReinforcements(value)
- GoldIncrease::class.java -> GoldIncrease(value)
- RawPointsIncrease::class.java -> RawPointsIncrease(value)
- else -> throw IllegalArgumentException("Unknown numeric effet " + typeOfT.typeName)
- }
- }
-}
diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ProductionIncreaseSerializer.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ProductionIncreaseSerializer.kt
deleted file mode 100644
index dc340578..00000000
--- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ProductionIncreaseSerializer.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.luxons.sevenwonders.engine.data.serializers
-
-import com.google.gson.JsonDeserializationContext
-import com.google.gson.JsonDeserializer
-import com.google.gson.JsonElement
-import com.google.gson.JsonParseException
-import com.google.gson.JsonPrimitive
-import com.google.gson.JsonSerializationContext
-import com.google.gson.JsonSerializer
-import org.luxons.sevenwonders.engine.effects.ProductionIncrease
-import org.luxons.sevenwonders.engine.resources.Production
-import java.lang.reflect.Type
-
-internal class ProductionIncreaseSerializer : JsonSerializer<ProductionIncrease>, JsonDeserializer<ProductionIncrease> {
-
- override fun serialize(
- productionIncrease: ProductionIncrease,
- typeOfSrc: Type,
- context: JsonSerializationContext,
- ): JsonElement {
- val production = productionIncrease.production
- val json = context.serialize(production)
- return if (!json.isJsonNull && !productionIncrease.isSellable) JsonPrimitive("(${json.asString})") else json
- }
-
- @Throws(JsonParseException::class)
- override fun deserialize(
- json: JsonElement,
- typeOfT: Type,
- context: JsonDeserializationContext,
- ): ProductionIncrease {
- var prodJson = json
-
- var resourcesStr = prodJson.asString
- val isSellable = !resourcesStr.startsWith("(")
- if (!isSellable) {
- resourcesStr = unwrapBrackets(resourcesStr)
- prodJson = JsonPrimitive(resourcesStr)
- }
- val production = context.deserialize<Production>(prodJson, Production::class.java)
- return ProductionIncrease(production, isSellable)
- }
-
- private fun unwrapBrackets(str: String): String {
- return str.substring(1, str.length - 1)
- }
-}
diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ProductionSerializer.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ProductionSerializer.kt
index c98f20a8..48efaedb 100644
--- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ProductionSerializer.kt
+++ b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ProductionSerializer.kt
@@ -1,53 +1,47 @@
package org.luxons.sevenwonders.engine.data.serializers
-import com.google.gson.JsonDeserializationContext
-import com.google.gson.JsonDeserializer
-import com.google.gson.JsonElement
-import com.google.gson.JsonNull
-import com.google.gson.JsonParseException
-import com.google.gson.JsonSerializationContext
-import com.google.gson.JsonSerializer
+import kotlinx.serialization.ExperimentalSerializationApi
+import kotlinx.serialization.KSerializer
+import kotlinx.serialization.descriptors.PrimitiveKind
+import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
+import kotlinx.serialization.descriptors.SerialDescriptor
+import kotlinx.serialization.encoding.Decoder
+import kotlinx.serialization.encoding.Encoder
import org.luxons.sevenwonders.engine.resources.Production
-import org.luxons.sevenwonders.engine.resources.Resources
import org.luxons.sevenwonders.model.resources.ResourceType
-import java.lang.reflect.Type
-internal class ProductionSerializer : JsonSerializer<Production>, JsonDeserializer<Production> {
+internal object ProductionSerializer : KSerializer<Production> {
- override fun serialize(production: Production, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
- val fixedResources = production.getFixedResources()
- val choices = production.getAlternativeResources()
- return when {
- fixedResources.isEmpty() -> serializeAsChoice(choices, context)
- choices.isEmpty() -> serializeAsResources(fixedResources, context)
+ override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Production", PrimitiveKind.STRING)
+
+ @OptIn(ExperimentalSerializationApi::class)
+ override fun serialize(encoder: Encoder, value: Production) {
+ val fixedResources = value.getFixedResources()
+ val choices = value.getAlternativeResources()
+ when {
+ fixedResources.isEmpty() -> choices.toChoiceString()?.let { encoder.encodeString(it) } ?: encoder.encodeNull()
+ choices.isEmpty() -> encoder.encodeSerializableValue(ResourcesSerializer, fixedResources)
else -> throw IllegalArgumentException("Cannot serialize a production with mixed fixed resources and choices")
}
}
- private fun serializeAsChoice(choices: List<Set<ResourceType>>, context: JsonSerializationContext): JsonElement {
- if (choices.isEmpty()) {
- return JsonNull.INSTANCE
+ private fun List<Set<ResourceType>>.toChoiceString(): String? {
+ if (isEmpty()) {
+ return null
}
- if (choices.size > 1) {
+ if (size > 1) {
throw IllegalArgumentException("Cannot serialize a production with more than one choice")
}
- val str = choices[0].map { it.symbol }.joinToString("/")
- return context.serialize(str)
- }
-
- private fun serializeAsResources(fixedResources: Resources, context: JsonSerializationContext): JsonElement {
- return context.serialize(fixedResources)
+ return this[0].map { it.symbol }.joinToString("/")
}
- @Throws(JsonParseException::class)
- override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Production {
- val resourcesStr = json.asString
+ override fun deserialize(decoder: Decoder): Production {
+ val resourcesStr = decoder.decodeString()
val production = Production()
if (resourcesStr.contains("/")) {
production.addChoice(*createChoice(resourcesStr))
} else {
- val fixedResources = context.deserialize<Resources>(json, Resources::class.java)
- production.addAll(fixedResources)
+ production.addAll(ResourcesSerializer.deserializeString(resourcesStr))
}
return production
}
diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourceTypeSerializer.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourceTypeSerializer.kt
index b308fd24..ccbb9560 100644
--- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourceTypeSerializer.kt
+++ b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourceTypeSerializer.kt
@@ -1,26 +1,20 @@
package org.luxons.sevenwonders.engine.data.serializers
-import com.google.gson.JsonDeserializationContext
-import com.google.gson.JsonDeserializer
-import com.google.gson.JsonElement
-import com.google.gson.JsonParseException
-import com.google.gson.JsonPrimitive
-import com.google.gson.JsonSerializationContext
-import com.google.gson.JsonSerializer
+import kotlinx.serialization.KSerializer
+import kotlinx.serialization.descriptors.PrimitiveKind
+import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
+import kotlinx.serialization.descriptors.SerialDescriptor
+import kotlinx.serialization.encoding.Decoder
+import kotlinx.serialization.encoding.Encoder
import org.luxons.sevenwonders.model.resources.ResourceType
-import java.lang.reflect.Type
-internal class ResourceTypeSerializer : JsonSerializer<ResourceType>, JsonDeserializer<ResourceType> {
+internal object ResourceTypeSerializer : KSerializer<ResourceType> {
- override fun serialize(type: ResourceType, typeOfSrc: Type, context: JsonSerializationContext): JsonElement =
- JsonPrimitive(type.symbol)
+ override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("ResourceType", PrimitiveKind.STRING)
- @Throws(JsonParseException::class)
- override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): ResourceType {
- val str = json.asString
- if (str.isEmpty()) {
- throw IllegalArgumentException("Empty string is not a valid resource level")
- }
- return ResourceType.fromSymbol(str[0])
+ override fun serialize(encoder: Encoder, value: ResourceType) {
+ encoder.encodeString(value.symbol.toString())
}
+
+ override fun deserialize(decoder: Decoder): ResourceType = ResourceType.fromSymbol(decoder.decodeString())
}
diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourceTypesSerializer.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourceTypesSerializer.kt
index ebbee8fd..8bd35f52 100644
--- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourceTypesSerializer.kt
+++ b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourceTypesSerializer.kt
@@ -1,30 +1,21 @@
package org.luxons.sevenwonders.engine.data.serializers
-import com.google.gson.JsonDeserializationContext
-import com.google.gson.JsonDeserializer
-import com.google.gson.JsonElement
-import com.google.gson.JsonParseException
-import com.google.gson.JsonPrimitive
-import com.google.gson.JsonSerializationContext
-import com.google.gson.JsonSerializer
+import kotlinx.serialization.KSerializer
+import kotlinx.serialization.descriptors.PrimitiveKind
+import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
+import kotlinx.serialization.descriptors.SerialDescriptor
+import kotlinx.serialization.encoding.Decoder
+import kotlinx.serialization.encoding.Encoder
import org.luxons.sevenwonders.model.resources.ResourceType
-import java.lang.reflect.Type
-internal class ResourceTypesSerializer : JsonSerializer<List<ResourceType>>, JsonDeserializer<List<ResourceType>> {
+internal object ResourceTypesSerializer : KSerializer<List<ResourceType>> {
- override fun serialize(
- resources: List<ResourceType>,
- typeOfSrc: Type,
- context: JsonSerializationContext,
- ): JsonElement {
- val s = resources.map { it.symbol }.joinToString("")
- return JsonPrimitive(s)
+ override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("ResourceTypeList", PrimitiveKind.STRING)
+
+ override fun serialize(encoder: Encoder, value: List<ResourceType>) {
+ encoder.encodeString(value.map { it.symbol }.joinToString(""))
}
- @Throws(JsonParseException::class)
- override fun deserialize(
- json: JsonElement,
- typeOfT: Type,
- context: JsonDeserializationContext,
- ): List<ResourceType> = json.asString.map { ResourceType.fromSymbol(it) }
+ override fun deserialize(decoder: Decoder): List<ResourceType> =
+ decoder.decodeString().map { ResourceType.fromSymbol(it) }
}
diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourcesSerializer.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourcesSerializer.kt
index 4226411d..cf31c380 100644
--- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourcesSerializer.kt
+++ b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourcesSerializer.kt
@@ -1,26 +1,27 @@
package org.luxons.sevenwonders.engine.data.serializers
-import com.google.gson.JsonDeserializationContext
-import com.google.gson.JsonDeserializer
-import com.google.gson.JsonElement
-import com.google.gson.JsonNull
-import com.google.gson.JsonParseException
-import com.google.gson.JsonPrimitive
-import com.google.gson.JsonSerializationContext
-import com.google.gson.JsonSerializer
+import kotlinx.serialization.ExperimentalSerializationApi
+import kotlinx.serialization.KSerializer
+import kotlinx.serialization.descriptors.PrimitiveKind
+import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
+import kotlinx.serialization.descriptors.SerialDescriptor
+import kotlinx.serialization.encoding.Decoder
+import kotlinx.serialization.encoding.Encoder
import org.luxons.sevenwonders.engine.resources.Resources
import org.luxons.sevenwonders.engine.resources.toResources
import org.luxons.sevenwonders.model.resources.ResourceType
-import java.lang.reflect.Type
-internal class ResourcesSerializer : JsonSerializer<Resources>, JsonDeserializer<Resources> {
+internal object ResourcesSerializer : KSerializer<Resources> {
- override fun serialize(resources: Resources, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
- val s = resources.toList().map { it.symbol }.joinToString("")
- return if (s.isEmpty()) JsonNull.INSTANCE else JsonPrimitive(s)
+ override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Resources", PrimitiveKind.STRING)
+
+ @OptIn(ExperimentalSerializationApi::class)
+ override fun serialize(encoder: Encoder, value: Resources) {
+ val s = value.toList().map { it.symbol }.joinToString("")
+ if (s.isEmpty()) encoder.encodeNull() else encoder.encodeString(s)
}
- @Throws(JsonParseException::class)
- override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Resources =
- json.asString.map { ResourceType.fromSymbol(it) to 1 }.toResources()
+ override fun deserialize(decoder: Decoder): Resources = deserializeString(decoder.decodeString())
+
+ fun deserializeString(symbols: String): Resources = symbols.map { ResourceType.fromSymbol(it) to 1 }.toResources()
}
diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ScienceProgressSerializer.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ScienceProgressSerializer.kt
index 1193c94b..b4493c70 100644
--- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ScienceProgressSerializer.kt
+++ b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ScienceProgressSerializer.kt
@@ -1,55 +1,48 @@
package org.luxons.sevenwonders.engine.data.serializers
-import com.google.gson.JsonDeserializationContext
-import com.google.gson.JsonDeserializer
-import com.google.gson.JsonElement
-import com.google.gson.JsonNull
-import com.google.gson.JsonParseException
-import com.google.gson.JsonPrimitive
-import com.google.gson.JsonSerializationContext
-import com.google.gson.JsonSerializer
+import kotlinx.serialization.ExperimentalSerializationApi
+import kotlinx.serialization.KSerializer
+import kotlinx.serialization.descriptors.PrimitiveKind
+import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
+import kotlinx.serialization.descriptors.SerialDescriptor
+import kotlinx.serialization.encoding.Decoder
+import kotlinx.serialization.encoding.Encoder
+import kotlinx.serialization.serializer
import org.luxons.sevenwonders.engine.boards.Science
import org.luxons.sevenwonders.engine.boards.ScienceType
import org.luxons.sevenwonders.engine.effects.ScienceProgress
-import java.lang.reflect.Type
-internal class ScienceProgressSerializer : JsonSerializer<ScienceProgress>, JsonDeserializer<ScienceProgress> {
+internal object ScienceProgressSerializer : KSerializer<ScienceProgress> {
- override fun serialize(
- scienceProgress: ScienceProgress,
- typeOfSrc: Type,
- context: JsonSerializationContext,
- ): JsonElement {
- val science = scienceProgress.science
+ override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("ScienceProgress", PrimitiveKind.STRING)
- if (science.size() > 1) {
+ @OptIn(ExperimentalSerializationApi::class)
+ override fun serialize(encoder: Encoder, value: ScienceProgress) {
+ if (value.science.size() > 1) {
throw UnsupportedOperationException("Cannot serialize science containing more than one element")
}
-
+ if (value.science.jokers == 1) {
+ encoder.encodeString("any")
+ return
+ }
for (type in ScienceType.values()) {
- val quantity = science.getQuantity(type)
+ val quantity = value.science.getQuantity(type)
if (quantity == 1) {
- return context.serialize(type)
+ encoder.encodeSerializableValue(serializer(), type)
+ return
}
}
-
- return if (science.jokers == 1) JsonPrimitive("any") else JsonNull.INSTANCE
+ encoder.encodeNull()
}
- @Throws(JsonParseException::class)
- override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): ScienceProgress {
- val s = json.asString
+ override fun deserialize(decoder: Decoder): ScienceProgress {
+ val s = decoder.decodeString()
val science = Science()
if ("any" == s) {
science.addJoker(1)
} else {
- science.add(deserializeScienceType(json, context), 1)
+ science.add(ScienceType.valueOf(s), 1)
}
return ScienceProgress(science)
}
-
- private fun deserializeScienceType(json: JsonElement, context: JsonDeserializationContext): ScienceType {
- return context.deserialize<ScienceType>(json, ScienceType::class.java)
- ?: throw IllegalArgumentException("Invalid science level " + json.asString)
- }
}
diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/effects/BonusPerBoardElement.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/effects/BonusPerBoardElement.kt
index 41dbd937..6f1cee51 100644
--- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/effects/BonusPerBoardElement.kt
+++ b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/effects/BonusPerBoardElement.kt
@@ -1,5 +1,6 @@
package org.luxons.sevenwonders.engine.effects
+import kotlinx.serialization.Serializable
import org.luxons.sevenwonders.engine.Player
import org.luxons.sevenwonders.engine.boards.Board
import org.luxons.sevenwonders.model.boards.RelativeBoardPosition
@@ -11,6 +12,7 @@ enum class BoardElementType {
DEFEAT_TOKEN,
}
+@Serializable
internal data class BonusPerBoardElement(
val boards: List<RelativeBoardPosition>,
val type: BoardElementType,
diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/effects/Discount.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/effects/Discount.kt
index 83a45e28..f74f79c8 100644
--- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/effects/Discount.kt
+++ b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/effects/Discount.kt
@@ -1,10 +1,14 @@
package org.luxons.sevenwonders.engine.effects
+import kotlinx.serialization.Serializable
import org.luxons.sevenwonders.engine.boards.Board
+import org.luxons.sevenwonders.engine.data.serializers.ResourceTypesSerializer
import org.luxons.sevenwonders.model.resources.Provider
import org.luxons.sevenwonders.model.resources.ResourceType
+@Serializable
internal data class Discount(
+ @Serializable(with = ResourceTypesSerializer::class)
val resourceTypes: List<ResourceType> = emptyList(),
val providers: List<Provider> = emptyList(),
val discountedPrice: Int = 1,
diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/effects/ProductionIncrease.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/effects/ProductionIncrease.kt
index 6458ad20..006d7516 100644
--- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/effects/ProductionIncrease.kt
+++ b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/effects/ProductionIncrease.kt
@@ -1,14 +1,19 @@
package org.luxons.sevenwonders.engine.effects
+import kotlinx.serialization.Serializable
import org.luxons.sevenwonders.engine.boards.Board
import org.luxons.sevenwonders.engine.resources.Production
-internal data class ProductionIncrease(val production: Production, val isSellable: Boolean) : InstantOwnBoardEffect() {
+@Serializable
+internal data class ProductionIncrease(
+ val resources: Production,
+ val isSellable: Boolean
+) : InstantOwnBoardEffect() {
public override fun applyTo(board: Board) {
- board.production.addAll(production)
+ board.production.addAll(resources)
if (isSellable) {
- board.publicProduction.addAll(production)
+ board.publicProduction.addAll(resources)
}
}
}
diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/effects/ScienceProgress.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/effects/ScienceProgress.kt
index 4ea8626f..50a670bb 100644
--- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/effects/ScienceProgress.kt
+++ b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/effects/ScienceProgress.kt
@@ -1,8 +1,11 @@
package org.luxons.sevenwonders.engine.effects
+import kotlinx.serialization.Serializable
import org.luxons.sevenwonders.engine.boards.Board
import org.luxons.sevenwonders.engine.boards.Science
+import org.luxons.sevenwonders.engine.data.serializers.ScienceProgressSerializer
+@Serializable(with = ScienceProgressSerializer::class)
internal class ScienceProgress(val science: Science) : InstantOwnBoardEffect() {
public override fun applyTo(board: Board) = board.science.addAll(science)
diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/resources/Production.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/resources/Production.kt
index 3eb59bd5..ad11faab 100644
--- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/resources/Production.kt
+++ b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/resources/Production.kt
@@ -1,8 +1,11 @@
package org.luxons.sevenwonders.engine.resources
+import kotlinx.serialization.Serializable
+import org.luxons.sevenwonders.engine.data.serializers.ProductionSerializer
import org.luxons.sevenwonders.model.resources.ResourceType
import java.util.EnumSet
+@Serializable(with = ProductionSerializer::class)
data class Production internal constructor(
private val fixedResources: MutableResources = mutableResourcesOf(),
// cannot be a Set because the same choices can be there multiple times
diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/resources/Resources.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/resources/Resources.kt
index b2dfc964..53556a3d 100644
--- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/resources/Resources.kt
+++ b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/resources/Resources.kt
@@ -1,5 +1,7 @@
package org.luxons.sevenwonders.engine.resources
+import kotlinx.serialization.Serializable
+import org.luxons.sevenwonders.engine.data.serializers.ResourcesSerializer
import org.luxons.sevenwonders.model.resources.ResourceType
fun emptyResources(): Resources = MutableResources()
@@ -34,6 +36,7 @@ internal fun Map<ResourceType, Int>.toMutableResources(): MutableResources = Mut
internal fun Resources.toMutableResources(): MutableResources = quantities.toMutableResources()
+@Serializable(with = ResourcesSerializer::class)
interface Resources {
val quantities: Map<ResourceType, Int>
bgstack15