summaryrefslogtreecommitdiff
path: root/sw-engine
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
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')
-rw-r--r--sw-engine/build.gradle.kts3
-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
-rw-r--r--sw-engine/src/main/resources/org/luxons/sevenwonders/engine/data/cards.json439
-rw-r--r--sw-engine/src/main/resources/org/luxons/sevenwonders/engine/data/wonders.json722
-rw-r--r--sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/NumericEffectSerializerTest.kt148
-rw-r--r--sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ProductionIncreaseSerializerTest.kt192
-rw-r--r--sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ProductionSerializerTest.kt75
-rw-r--r--sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourceTypeSerializerTest.kt27
-rw-r--r--sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourceTypesSerializerTest.kt35
-rw-r--r--sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourcesSerializerTest.kt50
-rw-r--r--sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ScienceProgressSerializerTest.kt46
29 files changed, 925 insertions, 1227 deletions
diff --git a/sw-engine/build.gradle.kts b/sw-engine/build.gradle.kts
index e39d7fd2..ca2d6fec 100644
--- a/sw-engine/build.gradle.kts
+++ b/sw-engine/build.gradle.kts
@@ -1,10 +1,11 @@
plugins {
kotlin("jvm")
+ kotlin("plugin.serialization")
}
dependencies {
implementation(project(":sw-common-model"))
- implementation("com.github.salomonbrys.kotson:kotson:2.5.0")
+ implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.1")
testImplementation(kotlin("test"))
testImplementation(kotlin("test-junit"))
}
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>
diff --git a/sw-engine/src/main/resources/org/luxons/sevenwonders/engine/data/cards.json b/sw-engine/src/main/resources/org/luxons/sevenwonders/engine/data/cards.json
index 32a3a4c2..9577a4f6 100644
--- a/sw-engine/src/main/resources/org/luxons/sevenwonders/engine/data/cards.json
+++ b/sw-engine/src/main/resources/org/luxons/sevenwonders/engine/data/cards.json
@@ -5,7 +5,10 @@
"name": "Clay Pit",
"color": "BROWN",
"effect": {
- "production": "O/C"
+ "production": {
+ "resources": "O/C",
+ "isSellable": true
+ }
},
"requirements": {
"gold": 1
@@ -18,11 +21,15 @@
"7": 1
},
"image": "claypit.png"
- }, {
+ },
+ {
"name": "Clay Pool",
"color": "BROWN",
"effect": {
- "production": "C"
+ "production": {
+ "resources": "C",
+ "isSellable": true
+ }
},
"countPerNbPlayer": {
"3": 1,
@@ -32,11 +39,15 @@
"7": 2
},
"image": "claypool.png"
- }, {
+ },
+ {
"name": "Excavation",
"color": "BROWN",
"effect": {
- "production": "S/C"
+ "production": {
+ "resources": "S/C",
+ "isSellable": true
+ }
},
"requirements": {
"gold": 1
@@ -49,11 +60,15 @@
"7": 1
},
"image": "excavation.png"
- }, {
+ },
+ {
"name": "Forest Cave",
"color": "BROWN",
"effect": {
- "production": "W/O"
+ "production": {
+ "resources": "W/O",
+ "isSellable": true
+ }
},
"requirements": {
"gold": 1
@@ -66,11 +81,15 @@
"7": 1
},
"image": "forestcave.png"
- }, {
+ },
+ {
"name": "Lumber Yard",
"color": "BROWN",
"effect": {
- "production": "W"
+ "production": {
+ "resources": "W",
+ "isSellable": true
+ }
},
"countPerNbPlayer": {
"3": 1,
@@ -80,11 +99,15 @@
"7": 2
},
"image": "lumberyard.png"
- }, {
+ },
+ {
"name": "Mine",
"color": "BROWN",
"effect": {
- "production": "S/O"
+ "production": {
+ "resources": "S/O",
+ "isSellable": true
+ }
},
"requirements": {
"gold": 1
@@ -97,11 +120,15 @@
"7": 1
},
"image": "mine.png"
- }, {
+ },
+ {
"name": "Ore Vein",
"color": "BROWN",
"effect": {
- "production": "O"
+ "production": {
+ "resources": "O",
+ "isSellable": true
+ }
},
"countPerNbPlayer": {
"3": 1,
@@ -111,11 +138,15 @@
"7": 2
},
"image": "orevein.png"
- }, {
+ },
+ {
"name": "Stone Pit",
"color": "BROWN",
"effect": {
- "production": "S"
+ "production": {
+ "resources": "S",
+ "isSellable": true
+ }
},
"countPerNbPlayer": {
"3": 1,
@@ -125,11 +156,15 @@
"7": 2
},
"image": "stonepit.png"
- }, {
+ },
+ {
"name": "Timber Yard",
"color": "BROWN",
"effect": {
- "production": "W/S"
+ "production": {
+ "resources": "W/S",
+ "isSellable": true
+ }
},
"requirements": {
"gold": 1
@@ -142,11 +177,15 @@
"7": 1
},
"image": "timberyard.png"
- }, {
+ },
+ {
"name": "Tree Farm",
"color": "BROWN",
"effect": {
- "production": "W/C"
+ "production": {
+ "resources": "W/C",
+ "isSellable": true
+ }
},
"requirements": {
"gold": 1
@@ -159,11 +198,15 @@
"7": 1
},
"image": "treefarm.png"
- }, {
+ },
+ {
"name": "Glassworks",
"color": "GREY",
"effect": {
- "production": "G"
+ "production": {
+ "resources": "G",
+ "isSellable": true
+ }
},
"countPerNbPlayer": {
"3": 1,
@@ -173,11 +216,15 @@
"7": 2
},
"image": "glassworks.png"
- }, {
+ },
+ {
"name": "Loom",
"color": "GREY",
"effect": {
- "production": "L"
+ "production": {
+ "resources": "L",
+ "isSellable": true
+ }
},
"countPerNbPlayer": {
"3": 1,
@@ -187,11 +234,15 @@
"7": 2
},
"image": "loom.png"
- }, {
+ },
+ {
"name": "Press",
"color": "GREY",
"effect": {
- "production": "P"
+ "production": {
+ "resources": "P",
+ "isSellable": true
+ }
},
"countPerNbPlayer": {
"3": 1,
@@ -201,7 +252,8 @@
"7": 2
},
"image": "press.png"
- }, {
+ },
+ {
"name": "East Trading Post",
"color": "YELLOW",
"effect": {
@@ -224,16 +276,17 @@
"7": 2
},
"image": "easttradingpost.png"
- }, {
+ },
+ {
"name": "Marketplace",
"color": "YELLOW",
"effect": {
"discount": {
"resourceTypes": "LGP",
"providers": [
- "LEFT_PLAYER", "RIGHT_PLAYER"
- ],
- "discountedPrice": 1
+ "LEFT_PLAYER",
+ "RIGHT_PLAYER"
+ ]
}
},
"chainChildren": [
@@ -247,7 +300,8 @@
"7": 2
},
"image": "marketplace.png"
- }, {
+ },
+ {
"name": "Tavern",
"color": "YELLOW",
"effect": {
@@ -261,7 +315,8 @@
"7": 3
},
"image": "tavern.png"
- }, {
+ },
+ {
"name": "West Trading Post",
"color": "YELLOW",
"effect": {
@@ -284,7 +339,8 @@
"7": 2
},
"image": "westtradingpost.png"
- }, {
+ },
+ {
"name": "Altar",
"color": "BLUE",
"effect": {
@@ -301,7 +357,8 @@
"7": 2
},
"image": "altar.png"
- }, {
+ },
+ {
"name": "Baths",
"color": "BLUE",
"effect": {
@@ -321,7 +378,8 @@
"7": 2
},
"image": "baths.png"
- }, {
+ },
+ {
"name": "Pawnshop",
"color": "BLUE",
"effect": {
@@ -335,7 +393,8 @@
"7": 2
},
"image": "pawnshop.png"
- }, {
+ },
+ {
"name": "Theater",
"color": "BLUE",
"effect": {
@@ -352,7 +411,8 @@
"7": 2
},
"image": "theater.png"
- }, {
+ },
+ {
"name": "Apothecary",
"color": "GREEN",
"effect": {
@@ -362,7 +422,8 @@
"resources": "L"
},
"chainChildren": [
- "Stables", "Dispensary"
+ "Stables",
+ "Dispensary"
],
"countPerNbPlayer": {
"3": 1,
@@ -372,7 +433,8 @@
"7": 2
},
"image": "apothecary.png"
- }, {
+ },
+ {
"name": "Scriptorium",
"color": "GREEN",
"effect": {
@@ -382,7 +444,8 @@
"resources": "P"
},
"chainChildren": [
- "Courthouse", "Library"
+ "Courthouse",
+ "Library"
],
"countPerNbPlayer": {
"3": 1,
@@ -392,7 +455,8 @@
"7": 2
},
"image": "scriptorium.png"
- }, {
+ },
+ {
"name": "Workshop",
"color": "GREEN",
"effect": {
@@ -402,7 +466,8 @@
"resources": "G"
},
"chainChildren": [
- "Archery Range", "Laboratory"
+ "Archery Range",
+ "Laboratory"
],
"countPerNbPlayer": {
"3": 1,
@@ -412,7 +477,8 @@
"7": 2
},
"image": "workshop.png"
- }, {
+ },
+ {
"name": "Barracks",
"color": "RED",
"effect": {
@@ -429,7 +495,8 @@
"7": 2
},
"image": "barracks.png"
- }, {
+ },
+ {
"name": "Guard Tower",
"color": "RED",
"effect": {
@@ -446,7 +513,8 @@
"7": 2
},
"image": "guardtower.png"
- }, {
+ },
+ {
"name": "Stockade",
"color": "RED",
"effect": {
@@ -473,7 +541,10 @@
"name": "Brickyard",
"color": "BROWN",
"effect": {
- "production": "CC"
+ "production": {
+ "resources": "CC",
+ "isSellable": true
+ }
},
"requirements": {
"gold": 1
@@ -486,11 +557,15 @@
"7": 2
},
"image": "brickyard.png"
- }, {
+ },
+ {
"name": "Foundry",
"color": "BROWN",
"effect": {
- "production": "OO"
+ "production": {
+ "resources": "OO",
+ "isSellable": true
+ }
},
"requirements": {
"gold": 1
@@ -503,11 +578,15 @@
"7": 2
},
"image": "foundry.png"
- }, {
+ },
+ {
"name": "Quarry",
"color": "BROWN",
"effect": {
- "production": "SS"
+ "production": {
+ "resources": "SS",
+ "isSellable": true
+ }
},
"requirements": {
"gold": 1
@@ -520,11 +599,15 @@
"7": 2
},
"image": "quarry.png"
- }, {
+ },
+ {
"name": "Sawmill",
"color": "BROWN",
"effect": {
- "production": "WW"
+ "production": {
+ "resources": "WW",
+ "isSellable": true
+ }
},
"requirements": {
"gold": 1
@@ -537,11 +620,15 @@
"7": 2
},
"image": "sawmill.png"
- }, {
+ },
+ {
"name": "Glassworks",
"color": "GREY",
"effect": {
- "production": "G"
+ "production": {
+ "resources": "G",
+ "isSellable": true
+ }
},
"countPerNbPlayer": {
"3": 1,
@@ -551,11 +638,15 @@
"7": 2
},
"image": "glassworks.png"
- }, {
+ },
+ {
"name": "Loom",
"color": "GREY",
"effect": {
- "production": "L"
+ "production": {
+ "resources": "L",
+ "isSellable": true
+ }
},
"countPerNbPlayer": {
"3": 1,
@@ -565,11 +656,15 @@
"7": 2
},
"image": "loom.png"
- }, {
+ },
+ {
"name": "Press",
"color": "GREY",
"effect": {
- "production": "P"
+ "production": {
+ "resources": "P",
+ "isSellable": true
+ }
},
"countPerNbPlayer": {
"3": 1,
@@ -579,13 +674,16 @@
"7": 2
},
"image": "press.png"
- }, {
+ },
+ {
"name": "Bazar",
"color": "YELLOW",
"effect": {
"perBoardElement": {
"boards": [
- "SELF", "LEFT", "RIGHT"
+ "SELF",
+ "LEFT",
+ "RIGHT"
],
"gold": 2,
"type": "CARD",
@@ -602,11 +700,15 @@
"7": 2
},
"image": "bazar.png"
- }, {
+ },
+ {
"name": "Caravansery",
"color": "YELLOW",
"effect": {
- "production": "(W/S/O/C)"
+ "production": {
+ "resources": "W/S/O/C",
+ "isSellable": false
+ }
},
"requirements": {
"resources": "WW"
@@ -623,11 +725,15 @@
"7": 3
},
"image": "caravansery.png"
- }, {
+ },
+ {
"name": "Forum",
"color": "YELLOW",
"effect": {
- "production": "(G/P/L)"
+ "production": {
+ "resources": "G/P/L",
+ "isSellable": false
+ }
},
"requirements": {
"resources": "CC"
@@ -644,13 +750,16 @@
"7": 3
},
"image": "forum.png"
- }, {
+ },
+ {
"name": "Vineyard",
"color": "YELLOW",
"effect": {
"perBoardElement": {
"boards": [
- "SELF", "LEFT", "RIGHT"
+ "SELF",
+ "LEFT",
+ "RIGHT"
],
"gold": 1,
"type": "CARD",
@@ -667,7 +776,8 @@
"7": 2
},
"image": "vineyard.png"
- }, {
+ },
+ {
"name": "Aqueduct",
"color": "BLUE",
"effect": {
@@ -685,7 +795,8 @@
"7": 2
},
"image": "aqueduct.png"
- }, {
+ },
+ {
"name": "Courthouse",
"color": "BLUE",
"effect": {
@@ -703,7 +814,8 @@
"7": 2
},
"image": "courthouse.png"
- }, {
+ },
+ {
"name": "Statue",
"color": "BLUE",
"effect": {
@@ -724,7 +836,8 @@
"7": 2
},
"image": "statue.png"
- }, {
+ },
+ {
"name": "Temple",
"color": "BLUE",
"effect": {
@@ -745,7 +858,8 @@
"7": 2
},
"image": "temple.png"
- }, {
+ },
+ {
"name": "Dispensary",
"color": "GREEN",
"effect": {
@@ -756,7 +870,8 @@
},
"chainParent": "Apothecary",
"chainChildren": [
- "Arena", "Lodge"
+ "Arena",
+ "Lodge"
],
"countPerNbPlayer": {
"3": 1,
@@ -766,7 +881,8 @@
"7": 2
},
"image": "dispensary.png"
- }, {
+ },
+ {
"name": "Laboratory",
"color": "GREEN",
"effect": {
@@ -777,7 +893,8 @@
},
"chainParent": "Workshop",
"chainChildren": [
- "Siege Workshop", "Observatory"
+ "Siege Workshop",
+ "Observatory"
],
"countPerNbPlayer": {
"3": 1,
@@ -787,7 +904,8 @@
"7": 2
},
"image": "laboratory.png"
- }, {
+ },
+ {
"name": "Library",
"color": "GREEN",
"effect": {
@@ -798,7 +916,8 @@
},
"chainParent": "Scriptorium",
"chainChildren": [
- "Senate", "University"
+ "Senate",
+ "University"
],
"countPerNbPlayer": {
"3": 1,
@@ -808,7 +927,8 @@
"7": 2
},
"image": "library.png"
- }, {
+ },
+ {
"name": "School",
"color": "GREEN",
"effect": {
@@ -818,7 +938,8 @@
"resources": "WP"
},
"chainChildren": [
- "Academy", "Study"
+ "Academy",
+ "Study"
],
"countPerNbPlayer": {
"3": 1,
@@ -828,7 +949,8 @@
"7": 2
},
"image": "school.png"
- }, {
+ },
+ {
"name": "Archery Range",
"color": "RED",
"effect": {
@@ -846,7 +968,8 @@
"7": 2
},
"image": "archeryrange.png"
- }, {
+ },
+ {
"name": "Stables",
"color": "RED",
"effect": {
@@ -864,7 +987,8 @@
"7": 2
},
"image": "stables.png"
- }, {
+ },
+ {
"name": "Training Ground",
"color": "RED",
"effect": {
@@ -884,7 +1008,8 @@
"7": 3
},
"image": "trainingground.png"
- }, {
+ },
+ {
"name": "Walls",
"color": "RED",
"effect": {
@@ -918,9 +1043,9 @@
"boards": [
"SELF"
],
+ "type": "BUILT_WONDER_STAGES",
"gold": 3,
- "points": 1,
- "type": "BUILT_WONDER_STAGES"
+ "points": 1
}
},
"requirements": {
@@ -935,7 +1060,8 @@
"7": 3
},
"image": "arena.png"
- }, {
+ },
+ {
"name": "Chamber of Commerce",
"color": "YELLOW",
"effect": {
@@ -943,9 +1069,9 @@
"boards": [
"SELF"
],
+ "type": "CARD",
"gold": 2,
"points": 2,
- "type": "CARD",
"colors": [
"GREY"
]
@@ -962,7 +1088,8 @@
"7": 2
},
"image": "chamberofcommerce.png"
- }, {
+ },
+ {
"name": "Haven",
"color": "YELLOW",
"effect": {
@@ -970,9 +1097,9 @@
"boards": [
"SELF"
],
+ "type": "CARD",
"gold": 1,
"points": 1,
- "type": "CARD",
"colors": [
"BROWN"
]
@@ -990,7 +1117,8 @@
"7": 2
},
"image": "haven.png"
- }, {
+ },
+ {
"name": "Lighthouse",
"color": "YELLOW",
"effect": {
@@ -998,9 +1126,9 @@
"boards": [
"SELF"
],
+ "type": "CARD",
"gold": 1,
"points": 1,
- "type": "CARD",
"colors": [
"GREY"
]
@@ -1018,7 +1146,8 @@
"7": 2
},
"image": "lighthouse.png"
- }, {
+ },
+ {
"name": "Gardens",
"color": "BLUE",
"effect": {
@@ -1036,7 +1165,8 @@
"7": 2
},
"image": "gardens.png"
- }, {
+ },
+ {
"name": "Palace",
"color": "BLUE",
"effect": {
@@ -1053,7 +1183,8 @@
"7": 2
},
"image": "palace.png"
- }, {
+ },
+ {
"name": "Pantheon",
"color": "BLUE",
"effect": {
@@ -1071,7 +1202,8 @@
"7": 2
},
"image": "pantheon.png"
- }, {
+ },
+ {
"name": "Senate",
"color": "BLUE",
"effect": {
@@ -1089,7 +1221,8 @@
"7": 2
},
"image": "senate.png"
- }, {
+ },
+ {
"name": "Town Hall",
"color": "BLUE",
"effect": {
@@ -1106,7 +1239,8 @@
"7": 3
},
"image": "townhall.png"
- }, {
+ },
+ {
"name": "Academy",
"color": "GREEN",
"effect": {
@@ -1124,7 +1258,8 @@
"7": 2
},
"image": "academy.png"
- }, {
+ },
+ {
"name": "Lodge",
"color": "GREEN",
"effect": {
@@ -1142,7 +1277,8 @@
"7": 2
},
"image": "lodge.png"
- }, {
+ },
+ {
"name": "Observatory",
"color": "GREEN",
"effect": {
@@ -1160,7 +1296,8 @@
"7": 2
},
"image": "observatory.png"
- }, {
+ },
+ {
"name": "Study",
"color": "GREEN",
"effect": {
@@ -1178,7 +1315,8 @@
"7": 2
},
"image": "study.png"
- }, {
+ },
+ {
"name": "University",
"color": "GREEN",
"effect": {
@@ -1196,7 +1334,8 @@
"7": 2
},
"image": "university.png"
- }, {
+ },
+ {
"name": "Arsenal",
"color": "RED",
"effect": {
@@ -1213,7 +1352,8 @@
"7": 3
},
"image": "arsenal.png"
- }, {
+ },
+ {
"name": "Circus",
"color": "RED",
"effect": {
@@ -1231,7 +1371,8 @@
"7": 3
},
"image": "circus.png"
- }, {
+ },
+ {
"name": "Fortifications",
"color": "RED",
"effect": {
@@ -1249,7 +1390,8 @@
"7": 2
},
"image": "fortifications.png"
- }, {
+ },
+ {
"name": "Siege Workshop",
"color": "RED",
"effect": {
@@ -1278,28 +1420,30 @@
"effect": {
"perBoardElement": {
"boards": [
- "LEFT", "SELF", "RIGHT"
+ "LEFT",
+ "SELF",
+ "RIGHT"
],
- "gold": 0,
- "points": 1,
- "type": "BUILT_WONDER_STAGES"
+ "type": "BUILT_WONDER_STAGES",
+ "points": 1
}
},
"requirements": {
"resources": "SSCCG"
},
"image": "buildersguild.png"
- }, {
+ },
+ {
"name": "Craftsmens Guild",
"color": "PURPLE",
"effect": {
"perBoardElement": {
"boards": [
- "LEFT", "RIGHT"
+ "LEFT",
+ "RIGHT"
],
- "gold": 0,
- "points": 2,
"type": "CARD",
+ "points": 2,
"colors": [
"GREY"
]
@@ -1309,17 +1453,18 @@
"resources": "SSOO"
},
"image": "craftsmensguild.png"
- }, {
+ },
+ {
"name": "Magistrates Guild",
"color": "PURPLE",
"effect": {
"perBoardElement": {
"boards": [
- "LEFT", "RIGHT"
+ "LEFT",
+ "RIGHT"
],
- "gold": 0,
- "points": 1,
"type": "CARD",
+ "points": 1,
"colors": [
"BLUE"
]
@@ -1329,17 +1474,18 @@
"resources": "WWWSL"
},
"image": "magistratesguild.png"
- }, {
+ },
+ {
"name": "Philosophers Guild",
"color": "PURPLE",
"effect": {
"perBoardElement": {
"boards": [
- "LEFT", "RIGHT"
+ "LEFT",
+ "RIGHT"
],
- "gold": 0,
- "points": 1,
"type": "CARD",
+ "points": 1,
"colors": [
"GREEN"
]
@@ -1349,7 +1495,8 @@
"resources": "CCCPL"
},
"image": "philosophersguild.png"
- }, {
+ },
+ {
"name": "Scientists Guild",
"color": "PURPLE",
"effect": {
@@ -1359,7 +1506,8 @@
"resources": "WWOOP"
},
"image": "scientistsguild.png"
- }, {
+ },
+ {
"name": "Shipowners Guild",
"color": "PURPLE",
"effect": {
@@ -1367,11 +1515,12 @@
"boards": [
"SELF"
],
- "gold": 0,
- "points": 1,
"type": "CARD",
+ "points": 1,
"colors": [
- "BROWN", "GREY", "PURPLE"
+ "BROWN",
+ "GREY",
+ "PURPLE"
]
}
},
@@ -1379,17 +1528,18 @@
"resources": "WWWGP"
},
"image": "shipownersguild.png"
- }, {
+ },
+ {
"name": "Spies Guild",
"color": "PURPLE",
"effect": {
"perBoardElement": {
"boards": [
- "LEFT", "RIGHT"
+ "LEFT",
+ "RIGHT"
],
- "gold": 0,
- "points": 1,
"type": "CARD",
+ "points": 1,
"colors": [
"RED"
]
@@ -1399,34 +1549,36 @@
"resources": "CCCG"
},
"image": "spiesguild.png"
- }, {
+ },
+ {
"name": "Strategists Guild",
"color": "PURPLE",
"effect": {
"perBoardElement": {
"boards": [
- "LEFT", "RIGHT"
+ "LEFT",
+ "RIGHT"
],
- "gold": 0,
- "points": 1,
- "type": "DEFEAT_TOKEN"
+ "type": "DEFEAT_TOKEN",
+ "points": 1
}
},
"requirements": {
"resources": "SOOL"
},
"image": "strategistsguild.png"
- }, {
+ },
+ {
"name": "Traders Guild",
"color": "PURPLE",
"effect": {
"perBoardElement": {
"boards": [
- "LEFT", "RIGHT"
+ "LEFT",
+ "RIGHT"
],
- "gold": 0,
- "points": 1,
"type": "CARD",
+ "points": 1,
"colors": [
"YELLOW"
]
@@ -1436,17 +1588,18 @@
"resources": "GPL"
},
"image": "tradersguild.png"
- }, {
+ },
+ {
"name": "Workers Guild",
"color": "PURPLE",
"effect": {
"perBoardElement": {
"boards": [
- "LEFT", "RIGHT"
+ "LEFT",
+ "RIGHT"
],
- "gold": 0,
- "points": 1,
"type": "CARD",
+ "points": 1,
"colors": [
"BROWN"
]
@@ -1458,4 +1611,4 @@
"image": "workersguild.png"
}
]
-}
+} \ No newline at end of file
diff --git a/sw-engine/src/main/resources/org/luxons/sevenwonders/engine/data/wonders.json b/sw-engine/src/main/resources/org/luxons/sevenwonders/engine/data/wonders.json
index 9049ca5e..1088a339 100644
--- a/sw-engine/src/main/resources/org/luxons/sevenwonders/engine/data/wonders.json
+++ b/sw-engine/src/main/resources/org/luxons/sevenwonders/engine/data/wonders.json
@@ -12,14 +12,19 @@
"effects": {
"points": 3
}
- }, {
+ },
+ {
"requirements": {
"resources": "OO"
},
"effects": {
- "production": "(W/S/O/C)"
+ "production": {
+ "resources": "W/S/O/C",
+ "isSellable": false
+ }
}
- }, {
+ },
+ {
"requirements": {
"resources": "GG"
},
@@ -38,16 +43,24 @@
"resources": "CC"
},
"effects": {
- "production": "(W/S/O/C)"
+ "production": {
+ "resources": "W/S/O/C",
+ "isSellable": false
+ }
}
- }, {
+ },
+ {
"requirements": {
"resources": "WW"
},
"effects": {
- "production": "(G/P/L)"
+ "production": {
+ "resources": "G/P/L",
+ "isSellable": false
+ }
}
- }, {
+ },
+ {
"requirements": {
"resources": "SSS"
},
@@ -59,380 +72,411 @@
"image": "alexandriaB.png"
}
}
- }, {
- "name": "Babylon",
- "sides": {
- "A": {
- "initialResource": "C",
- "stages": [
- {
- "requirements": {
- "resources": "CC"
- },
- "effects": {
- "points": 3
- }
- }, {
- "requirements": {
- "resources": "WWW"
- },
- "effects": {
- "science": "any"
- }
- }, {
- "requirements": {
- "resources": "CCCC"
+ },
+ {
+ "name": "Babylon",
+ "sides": {
+ "A": {
+ "initialResource": "C",
+ "stages": [
+ {
+ "requirements": {
+ "resources": "CC"
+ },
+ "effects": {
+ "points": 3
+ }
},
- "effects": {
- "points": 7
- }
- }
- ],
- "image": "babylonA.png"
- },
- "B": {
- "initialResource": "C",
- "stages": [
- {
- "requirements": {
- "resources": "CL"
+ {
+ "requirements": {
+ "resources": "WWW"
+ },
+ "effects": {
+ "science": "any"
+ }
},
- "effects": {
- "points": 3
+ {
+ "requirements": {
+ "resources": "CCCC"
+ },
+ "effects": {
+ "points": 7
+ }
}
- }, {
- "requirements": {
- "resources": "WWG"
+ ],
+ "image": "babylonA.png"
+ },
+ "B": {
+ "initialResource": "C",
+ "stages": [
+ {
+ "requirements": {
+ "resources": "CL"
+ },
+ "effects": {
+ "points": 3
+ }
},
- "effects": {
- "action": "PLAY_LAST_CARD"
- }
- }, {
- "requirements": {
- "resources": "CCCP"
+ {
+ "requirements": {
+ "resources": "WWG"
+ },
+ "effects": {
+ "action": "PLAY_LAST_CARD"
+ }
},
- "effects": {
- "science": "any"
+ {
+ "requirements": {
+ "resources": "CCCP"
+ },
+ "effects": {
+ "science": "any"
+ }
}
- }
- ],
- "image": "babylonB.png"
+ ],
+ "image": "babylonB.png"
+ }
}
- }
-}, {
- "name": "Ephesos",
- "sides": {
- "A": {
- "initialResource": "P",
- "stages": [
- {
- "requirements": {
- "resources": "SS"
- },
- "effects": {
- "points": 3
- }
- }, {
- "requirements": {
- "resources": "WW"
- },
- "effects": {
- "gold": 9
- }
- }, {
- "requirements": {
- "resources": "PP"
+ },
+ {
+ "name": "Ephesos",
+ "sides": {
+ "A": {
+ "initialResource": "P",
+ "stages": [
+ {
+ "requirements": {
+ "resources": "SS"
+ },
+ "effects": {
+ "points": 3
+ }
},
- "effects": {
- "points": 7
- }
- }
- ],
- "image": "ephesosA.png"
- },
- "B": {
- "initialResource": "P",
- "stages": [
- {
- "requirements": {
- "resources": "SS"
+ {
+ "requirements": {
+ "resources": "WW"
+ },
+ "effects": {
+ "gold": 9
+ }
},
- "effects": {
- "gold": 4,
- "points": 2
+ {
+ "requirements": {
+ "resources": "PP"
+ },
+ "effects": {
+ "points": 7
+ }
}
- }, {
- "requirements": {
- "resources": "WW"
+ ],
+ "image": "ephesosA.png"
+ },
+ "B": {
+ "initialResource": "P",
+ "stages": [
+ {
+ "requirements": {
+ "resources": "SS"
+ },
+ "effects": {
+ "gold": 4,
+ "points": 2
+ }
},
- "effects": {
- "gold": 4,
- "points": 3
- }
- }, {
- "requirements": {
- "resources": "GPL"
+ {
+ "requirements": {
+ "resources": "WW"
+ },
+ "effects": {
+ "gold": 4,
+ "points": 3
+ }
},
- "effects": {
- "gold": 4,
- "points": 5
+ {
+ "requirements": {
+ "resources": "GPL"
+ },
+ "effects": {
+ "gold": 4,
+ "points": 5
+ }
}
- }
- ],
- "image": "ephesosB.png"
+ ],
+ "image": "ephesosB.png"
+ }
}
- }
-}, {
- "name": "Gizah",
- "sides": {
- "A": {
- "initialResource": "S",
- "stages": [
- {
- "requirements": {
- "resources": "SS"
- },
- "effects": {
- "points": 3
- }
- }, {
- "requirements": {
- "resources": "WWW"
- },
- "effects": {
- "points": 5
- }
- }, {
- "requirements": {
- "resources": "SSSS"
+ },
+ {
+ "name": "Gizah",
+ "sides": {
+ "A": {
+ "initialResource": "S",
+ "stages": [
+ {
+ "requirements": {
+ "resources": "SS"
+ },
+ "effects": {
+ "points": 3
+ }
},
- "effects": {
- "points": 7
- }
- }
- ],
- "image": "gizahA.png"
- },
- "B": {
- "initialResource": "S",
- "stages": [
- {
- "requirements": {
- "resources": "WW"
+ {
+ "requirements": {
+ "resources": "WWW"
+ },
+ "effects": {
+ "points": 5
+ }
},
- "effects": {
- "points": 3
+ {
+ "requirements": {
+ "resources": "SSSS"
+ },
+ "effects": {
+ "points": 7
+ }
}
- }, {
- "requirements": {
- "resources": "SSS"
+ ],
+ "image": "gizahA.png"
+ },
+ "B": {
+ "initialResource": "S",
+ "stages": [
+ {
+ "requirements": {
+ "resources": "WW"
+ },
+ "effects": {
+ "points": 3
+ }
},
- "effects": {
- "points": 5
- }
- }, {
- "requirements": {
- "resources": "CCC"
+ {
+ "requirements": {
+ "resources": "SSS"
+ },
+ "effects": {
+ "points": 5
+ }
},
- "effects": {
- "points": 5
- }
- }, {
- "requirements": {
- "resources": "SSSSP"
+ {
+ "requirements": {
+ "resources": "CCC"
+ },
+ "effects": {
+ "points": 5
+ }
},
- "effects": {
- "points": 7
+ {
+ "requirements": {
+ "resources": "SSSSP"
+ },
+ "effects": {
+ "points": 7
+ }
}
- }
- ],
- "image": "gizahB.png"
+ ],
+ "image": "gizahB.png"
+ }
}
- }
-}, {
- "name": "Halikarnassus",
- "sides": {
- "A": {
- "initialResource": "L",
- "stages": [
- {
- "requirements": {
- "resources": "CC"
- },
- "effects": {
- "points": 3
- }
- }, {
- "requirements": {
- "resources": "OOO"
- },
- "effects": {
- "action": "PLAY_DISCARDED"
- }
- }, {
- "requirements": {
- "resources": "LL"
+ },
+ {
+ "name": "Halikarnassus",
+ "sides": {
+ "A": {
+ "initialResource": "L",
+ "stages": [
+ {
+ "requirements": {
+ "resources": "CC"
+ },
+ "effects": {
+ "points": 3
+ }
},
- "effects": {
- "points": 7
- }
- }
- ],
- "image": "halikarnassusA.png"
- },
- "B": {
- "initialResource": "L",
- "stages": [
- {
- "requirements": {
- "resources": "OO"
+ {
+ "requirements": {
+ "resources": "OOO"
+ },
+ "effects": {
+ "action": "PLAY_DISCARDED"
+ }
},
- "effects": {
- "points": 2,
- "action": "PLAY_DISCARDED"
+ {
+ "requirements": {
+ "resources": "LL"
+ },
+ "effects": {
+ "points": 7
+ }
}
- }, {
- "requirements": {
- "resources": "CCC"
+ ],
+ "image": "halikarnassusA.png"
+ },
+ "B": {
+ "initialResource": "L",
+ "stages": [
+ {
+ "requirements": {
+ "resources": "OO"
+ },
+ "effects": {
+ "points": 2,
+ "action": "PLAY_DISCARDED"
+ }
},
- "effects": {
- "points": 1,
- "action": "PLAY_DISCARDED"
- }
- }, {
- "requirements": {
- "resources": "GPL"
+ {
+ "requirements": {
+ "resources": "CCC"
+ },
+ "effects": {
+ "points": 1,
+ "action": "PLAY_DISCARDED"
+ }
},
- "effects": {
- "action": "PLAY_DISCARDED"
+ {
+ "requirements": {
+ "resources": "GPL"
+ },
+ "effects": {
+ "action": "PLAY_DISCARDED"
+ }
}
- }
- ],
- "image": "halikarnassusB.png"
+ ],
+ "image": "halikarnassusB.png"
+ }
}
- }
-}, {
- "name": "Olympia",
- "sides": {
- "A": {
- "initialResource": "W",
- "stages": [
- {
- "requirements": {
- "resources": "WW"
- },
- "effects": {
- "points": 3
- }
- }, {
- "requirements": {
- "resources": "SS"
- },
- "effects": {
- "action": "ONE_FREE_PER_AGE"
- }
- }, {
- "requirements": {
- "resources": "OO"
+ },
+ {
+ "name": "Olympia",
+ "sides": {
+ "A": {
+ "initialResource": "W",
+ "stages": [
+ {
+ "requirements": {
+ "resources": "WW"
+ },
+ "effects": {
+ "points": 3
+ }
},
- "effects": {
- "points": 7
- }
- }
- ],
- "image": "olympiaA.png"
- },
- "B": {
- "initialResource": "W",
- "stages": [
- {
- "requirements": {
- "resources": "WW"
+ {
+ "requirements": {
+ "resources": "SS"
+ },
+ "effects": {
+ "action": "ONE_FREE_PER_AGE"
+ }
},
- "effects": {
- "discount": {
- "resourceTypes": "WSOC",
- "providers": [
- "LEFT_PLAYER", "RIGHT_PLAYER"
- ],
- "discountedPrice": 1
+ {
+ "requirements": {
+ "resources": "OO"
+ },
+ "effects": {
+ "points": 7
}
}
- }, {
- "requirements": {
- "resources": "SS"
+ ],
+ "image": "olympiaA.png"
+ },
+ "B": {
+ "initialResource": "W",
+ "stages": [
+ {
+ "requirements": {
+ "resources": "WW"
+ },
+ "effects": {
+ "discount": {
+ "resourceTypes": "WSOC",
+ "providers": [
+ "LEFT_PLAYER",
+ "RIGHT_PLAYER"
+ ],
+ "discountedPrice": 1
+ }
+ }
},
- "effects": {
- "points": 5
- }
- }, {
- "requirements": {
- "resources": "OOL"
+ {
+ "requirements": {
+ "resources": "SS"
+ },
+ "effects": {
+ "points": 5
+ }
},
- "effects": {
- "action": "COPY_GUILD"
+ {
+ "requirements": {
+ "resources": "OOL"
+ },
+ "effects": {
+ "action": "COPY_GUILD"
+ }
}
- }
- ],
- "image": "olympiaB.png"
+ ],
+ "image": "olympiaB.png"
+ }
}
- }
-}, {
- "name": "Rhodos",
- "sides": {
- "A": {
- "initialResource": "O",
- "stages": [
- {
- "requirements": {
- "resources": "WW"
- },
- "effects": {
- "points": 3
- }
- }, {
- "requirements": {
- "resources": "CCC"
- },
- "effects": {
- "military": 2
- }
- }, {
- "requirements": {
- "resources": "OOOO"
+ },
+ {
+ "name": "Rhodos",
+ "sides": {
+ "A": {
+ "initialResource": "O",
+ "stages": [
+ {
+ "requirements": {
+ "resources": "WW"
+ },
+ "effects": {
+ "points": 3
+ }
},
- "effects": {
- "points": 7
- }
- }
- ],
- "image": "rhodosA.png"
- },
- "B": {
- "initialResource": "O",
- "stages": [
- {
- "requirements": {
- "resources": "SSS"
+ {
+ "requirements": {
+ "resources": "CCC"
+ },
+ "effects": {
+ "military": 2
+ }
},
- "effects": {
- "gold": 3,
- "military": 1,
- "points": 3
+ {
+ "requirements": {
+ "resources": "OOOO"
+ },
+ "effects": {
+ "points": 7
+ }
}
- }, {
- "requirements": {
- "resources": "OOOO"
+ ],
+ "image": "rhodosA.png"
+ },
+ "B": {
+ "initialResource": "O",
+ "stages": [
+ {
+ "requirements": {
+ "resources": "SSS"
+ },
+ "effects": {
+ "gold": 3,
+ "military": 1,
+ "points": 3
+ }
},
- "effects": {
- "gold": 4,
- "military": 1,
- "points": 4
+ {
+ "requirements": {
+ "resources": "OOOO"
+ },
+ "effects": {
+ "gold": 4,
+ "military": 1,
+ "points": 4
+ }
}
- }
- ],
- "image": "rhodosB.png"
+ ],
+ "image": "rhodosB.png"
+ }
}
}
-}
]
diff --git a/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/NumericEffectSerializerTest.kt b/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/NumericEffectSerializerTest.kt
deleted file mode 100644
index 520db340..00000000
--- a/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/NumericEffectSerializerTest.kt
+++ /dev/null
@@ -1,148 +0,0 @@
-package org.luxons.sevenwonders.engine.data.serializers
-
-import com.github.salomonbrys.kotson.fromJson
-import com.google.gson.Gson
-import com.google.gson.GsonBuilder
-import org.junit.Before
-import org.junit.Test
-import org.junit.experimental.theories.DataPoints
-import org.junit.experimental.theories.Theories
-import org.junit.experimental.theories.Theory
-import org.junit.runner.RunWith
-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.resources.Production
-import kotlin.test.assertEquals
-import kotlin.test.assertFailsWith
-
-@RunWith(Theories::class)
-class NumericEffectSerializerTest {
-
- private lateinit var gson: Gson
-
- @Before
- fun setUp() {
- gson = GsonBuilder().registerTypeAdapter(MilitaryReinforcements::class.java, NumericEffectSerializer())
- .registerTypeAdapter(RawPointsIncrease::class.java, NumericEffectSerializer())
- .registerTypeAdapter(GoldIncrease::class.java, NumericEffectSerializer())
- // ProductionIncrease is not a numeric effect, it is here for negative testing purpose
- .registerTypeAdapter(ProductionIncrease::class.java, NumericEffectSerializer())
- .create()
- }
-
- @Test
- fun serialize_militaryReinforcements_null() {
- assertEquals("null", gson.toJson(null, MilitaryReinforcements::class.java))
- }
-
- @Test
- fun serialize_rawPointsIncrease_null() {
- assertEquals("null", gson.toJson(null, RawPointsIncrease::class.java))
- }
-
- @Test
- fun serialize_goldIncrease_null() {
- assertEquals("null", gson.toJson(null, GoldIncrease::class.java))
- }
-
- @Test
- fun serialize_failOnUnknownType() {
- assertFailsWith<IllegalArgumentException> {
- gson.toJson(ProductionIncrease(Production(), false))
- }
- }
-
- @Theory
- fun serialize_militaryReinforcements(count: Int) {
- val reinforcements = MilitaryReinforcements(count)
- assertEquals(count.toString(), gson.toJson(reinforcements))
- }
-
- @Theory
- fun serialize_rawPointsIncrease(count: Int) {
- val points = RawPointsIncrease(count)
- assertEquals(count.toString(), gson.toJson(points))
- }
-
- @Theory
- fun serialize_goldIncrease(count: Int) {
- val goldIncrease = GoldIncrease(count)
- assertEquals(count.toString(), gson.toJson(goldIncrease))
- }
-
- @Theory
- fun deserialize_militaryReinforcements(count: Int) {
- val reinforcements = MilitaryReinforcements(count)
- assertEquals(reinforcements, gson.fromJson<MilitaryReinforcements>(count.toString()))
- }
-
- @Theory
- fun deserialize_rawPointsIncrease(count: Int) {
- val points = RawPointsIncrease(count)
- assertEquals(points, gson.fromJson<RawPointsIncrease>(count.toString()))
- }
-
- @Theory
- fun deserialize_goldIncrease(count: Int) {
- val goldIncrease = GoldIncrease(count)
- assertEquals(goldIncrease, gson.fromJson<GoldIncrease>(count.toString()))
- }
-
- @Test
- fun deserialize_militaryReinforcements_failOnEmptyString() {
- assertFailsWith<NumberFormatException> {
- gson.fromJson<MilitaryReinforcements>("\"\"")
- }
- }
-
- @Test
- fun deserialize_rawPointsIncrease_failOnEmptyString() {
- assertFailsWith<NumberFormatException> {
- gson.fromJson<RawPointsIncrease>("\"\"")
- }
- }
-
- @Test
- fun deserialize_goldIncrease_failOnEmptyString() {
- assertFailsWith<NumberFormatException> {
- gson.fromJson<GoldIncrease>("\"\"")
- }
- }
-
- @Test
- fun deserialize_militaryReinforcements_failOnNonNumericString() {
- assertFailsWith<NumberFormatException> {
- gson.fromJson<MilitaryReinforcements>("\"abc\"")
- }
- }
-
- @Test
- fun deserialize_rawPointsIncrease_failOnNonNumericString() {
- assertFailsWith<NumberFormatException> {
- gson.fromJson<RawPointsIncrease>("\"abc\"")
- }
- }
-
- @Test
- fun deserialize_goldIncrease_failOnNonNumericString() {
- assertFailsWith<NumberFormatException> {
- gson.fromJson<GoldIncrease>("\"abc\"")
- }
- }
-
- @Test
- fun deserialize_failOnUnknownType() {
- assertFailsWith<IllegalArgumentException> {
- gson.fromJson<ProductionIncrease>("\"2\"")
- }
- }
-
- companion object {
-
- @JvmStatic
- @DataPoints
- fun dataPoints(): IntArray = intArrayOf(-2, -1, 0, 1, 2, 5)
- }
-}
diff --git a/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ProductionIncreaseSerializerTest.kt b/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ProductionIncreaseSerializerTest.kt
deleted file mode 100644
index 664ccedc..00000000
--- a/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ProductionIncreaseSerializerTest.kt
+++ /dev/null
@@ -1,192 +0,0 @@
-package org.luxons.sevenwonders.engine.data.serializers
-
-import com.github.salomonbrys.kotson.fromJson
-import com.google.gson.Gson
-import com.google.gson.GsonBuilder
-import com.google.gson.reflect.TypeToken
-import org.junit.Before
-import org.junit.Test
-import org.luxons.sevenwonders.engine.effects.ProductionIncrease
-import org.luxons.sevenwonders.engine.resources.MutableResources
-import org.luxons.sevenwonders.engine.resources.Production
-import org.luxons.sevenwonders.engine.resources.Resources
-import org.luxons.sevenwonders.model.resources.ResourceType
-import kotlin.test.assertEquals
-import kotlin.test.assertFailsWith
-import kotlin.test.assertNull
-
-class ProductionIncreaseSerializerTest {
-
- private lateinit var gson: Gson
-
- @Before
- fun setUp() {
- val resourceTypeList = object : TypeToken<List<ResourceType>>() {}.type
- gson = GsonBuilder().registerTypeAdapter(Resources::class.java, ResourcesSerializer())
- .registerTypeAdapter(MutableResources::class.java, ResourcesSerializer())
- .registerTypeAdapter(ResourceType::class.java, ResourceTypeSerializer())
- .registerTypeAdapter(resourceTypeList, ResourceTypesSerializer())
- .registerTypeAdapter(Production::class.java, ProductionSerializer())
- .registerTypeAdapter(ProductionIncrease::class.java, ProductionIncreaseSerializer())
- .create()
- }
-
- private fun create(sellable: Boolean, wood: Int, stone: Int, clay: Int): ProductionIncrease {
- val production = Production()
- if (wood > 0) {
- production.addFixedResource(ResourceType.WOOD, wood)
- }
- if (stone > 0) {
- production.addFixedResource(ResourceType.STONE, stone)
- }
- if (clay > 0) {
- production.addFixedResource(ResourceType.CLAY, clay)
- }
- return ProductionIncrease(production, sellable)
- }
-
- private fun createChoice(sellable: Boolean, vararg types: ResourceType): ProductionIncrease {
- val production = Production()
- production.addChoice(*types)
- return ProductionIncrease(production, sellable)
- }
-
- @Test
- fun serialize_nullAsNull() {
- assertEquals("null", gson.toJson(null, ProductionIncrease::class.java))
- }
-
- @Test
- fun serialize_emptyProdIncreaseAsNull() {
- val prodIncrease = ProductionIncrease(Production(), false)
- assertEquals("null", gson.toJson(prodIncrease))
- }
-
- @Test
- fun serialize_singleType() {
- val prodIncrease = create(true, 1, 0, 0)
- assertEquals("\"W\"", gson.toJson(prodIncrease))
- }
-
- @Test
- fun serialize_mixedTypes() {
- val prodIncrease = create(true, 1, 1, 1)
- assertEquals("\"WSC\"", gson.toJson(prodIncrease))
- }
-
- @Test
- fun serialize_mixedTypes_notSellable() {
- val prodIncrease = create(false, 1, 1, 1)
- assertEquals("\"(WSC)\"", gson.toJson(prodIncrease))
- }
-
- @Test
- fun serialize_choice2() {
- val prodIncrease = createChoice(true, ResourceType.WOOD, ResourceType.CLAY)
- assertEquals("\"W/C\"", gson.toJson(prodIncrease))
- }
-
- @Test
- fun serialize_choice3() {
- val prodIncrease = createChoice(true, ResourceType.WOOD, ResourceType.ORE, ResourceType.CLAY)
- assertEquals("\"W/O/C\"", gson.toJson(prodIncrease))
- }
-
- @Test
- fun serialize_choice3_notSellable() {
- val prodIncrease = createChoice(false, ResourceType.WOOD, ResourceType.ORE, ResourceType.CLAY)
- assertEquals("\"(W/O/C)\"", gson.toJson(prodIncrease))
- }
-
- @Test
- fun serialize_choice2_unordered() {
- val prodIncrease = createChoice(true, ResourceType.CLAY, ResourceType.WOOD)
- assertEquals("\"W/C\"", gson.toJson(prodIncrease))
- }
-
- @Test
- fun serialize_choice3_unordered() {
- val prodIncrease = createChoice(true, ResourceType.WOOD, ResourceType.CLAY, ResourceType.ORE)
- assertEquals("\"W/O/C\"", gson.toJson(prodIncrease))
- }
-
- @Test
- fun serialize_failIfMultipleChoices() {
- val prodIncrease = createChoice(true, ResourceType.WOOD, ResourceType.CLAY)
- prodIncrease.production.addChoice(ResourceType.ORE, ResourceType.GLASS)
- assertFailsWith<IllegalArgumentException> {
- gson.toJson(prodIncrease)
- }
- }
-
- @Test
- fun serialize_failIfMixedFixedAndChoices() {
- val prodIncrease = create(true, 1, 0, 0)
- prodIncrease.production.addChoice(ResourceType.WOOD, ResourceType.CLAY)
- assertFailsWith<IllegalArgumentException> {
- gson.toJson(prodIncrease)
- }
- }
-
- @Test
- fun deserialize_nullFromNull() {
- assertNull(gson.fromJson("null", ProductionIncrease::class.java))
- }
-
- @Test
- fun deserialize_emptyList() {
- val prodIncrease = ProductionIncrease(Production(), true)
- assertEquals(prodIncrease, gson.fromJson("\"\""))
- }
-
- @Test
- fun deserialize_failOnGarbageString() {
- assertFailsWith(IllegalArgumentException::class) {
- gson.fromJson<ProductionIncrease>("\"this is garbage\"")
- }
- }
-
- @Test
- fun deserialize_failOnGarbageStringWithSlashes() {
- assertFailsWith(IllegalArgumentException::class) {
- gson.fromJson<ProductionIncrease>("\"this/is/garbage\"")
- }
- }
-
- @Test
- fun deserialize_singleType() {
- val prodIncrease = create(true, 1, 0, 0)
- assertEquals(prodIncrease, gson.fromJson("\"W\""))
- }
-
- @Test
- fun deserialize_multipleTimesSameType_notSellable() {
- val prodIncrease = create(false, 3, 0, 0)
- assertEquals(prodIncrease, gson.fromJson("\"(WWW)\""))
- }
-
- @Test
- fun deserialize_mixedTypes() {
- val prodIncrease = create(true, 1, 1, 1)
- assertEquals(prodIncrease, gson.fromJson("\"WCS\""))
- }
-
- @Test
- fun deserialize_choice2() {
- val prodIncrease = createChoice(true, ResourceType.WOOD, ResourceType.CLAY)
- assertEquals(prodIncrease, gson.fromJson("\"W/C\""))
- }
-
- @Test
- fun deserialize_choice3_notSellable() {
- val prodIncrease = createChoice(false, ResourceType.WOOD, ResourceType.ORE, ResourceType.CLAY)
- assertEquals(prodIncrease, gson.fromJson("\"(W/O/C)\""))
- }
-
- @Test
- fun deserialize_failOnMultipleResourcesInChoice() {
- assertFailsWith(IllegalArgumentException::class) {
- gson.fromJson<ProductionIncrease>("\"W/SS/C\"")
- }
- }
-}
diff --git a/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ProductionSerializerTest.kt b/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ProductionSerializerTest.kt
index 314bc43c..25e9d68c 100644
--- a/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ProductionSerializerTest.kt
+++ b/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ProductionSerializerTest.kt
@@ -1,14 +1,11 @@
package org.luxons.sevenwonders.engine.data.serializers
-import com.github.salomonbrys.kotson.fromJson
-import com.google.gson.Gson
-import com.google.gson.GsonBuilder
-import com.google.gson.reflect.TypeToken
-import org.junit.Before
+import kotlinx.serialization.builtins.nullable
+import kotlinx.serialization.decodeFromString
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.Json
import org.junit.Test
-import org.luxons.sevenwonders.engine.resources.MutableResources
import org.luxons.sevenwonders.engine.resources.Production
-import org.luxons.sevenwonders.engine.resources.Resources
import org.luxons.sevenwonders.model.resources.ResourceType
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
@@ -16,19 +13,6 @@ import kotlin.test.assertNull
class ProductionSerializerTest {
- private lateinit var gson: Gson
-
- @Before
- fun setUp() {
- val resourceTypeList = object : TypeToken<List<ResourceType>>() {}.type
- gson = GsonBuilder().registerTypeAdapter(Resources::class.java, ResourcesSerializer())
- .registerTypeAdapter(MutableResources::class.java, ResourcesSerializer())
- .registerTypeAdapter(ResourceType::class.java, ResourceTypeSerializer())
- .registerTypeAdapter(resourceTypeList, ResourceTypesSerializer())
- .registerTypeAdapter(Production::class.java, ProductionSerializer())
- .create()
- }
-
private fun create(wood: Int, stone: Int, clay: Int): Production {
val production = Production()
if (wood > 0) {
@@ -51,61 +35,61 @@ class ProductionSerializerTest {
@Test
fun serialize_nullAsNull() {
- assertEquals("null", gson.toJson(null, Production::class.java))
+ assertEquals("null", Json.encodeToString(Production.serializer().nullable, null))
}
@Test
fun serialize_emptyProdIncreaseAsNull() {
val prodIncrease = Production()
- assertEquals("null", gson.toJson(prodIncrease))
+ assertEquals("null", Json.encodeToString(prodIncrease))
}
@Test
fun serialize_singleType() {
val prodIncrease = create(1, 0, 0)
- assertEquals("\"W\"", gson.toJson(prodIncrease))
+ assertEquals("\"W\"", Json.encodeToString(prodIncrease))
}
@Test
fun serialize_multipleTimesSameType() {
val prodIncrease = create(3, 0, 0)
- assertEquals("\"WWW\"", gson.toJson(prodIncrease))
+ assertEquals("\"WWW\"", Json.encodeToString(prodIncrease))
}
@Test
fun serialize_mixedTypes() {
val prodIncrease = create(1, 1, 1)
- assertEquals("\"WSC\"", gson.toJson(prodIncrease))
+ assertEquals("\"WSC\"", Json.encodeToString(prodIncrease))
}
@Test
fun serialize_mixedTypesMultiple() {
val prodIncrease = create(2, 1, 2)
- assertEquals("\"WWSCC\"", gson.toJson(prodIncrease))
+ assertEquals("\"WWSCC\"", Json.encodeToString(prodIncrease))
}
@Test
fun serialize_choice2() {
val prodIncrease = createChoice(ResourceType.WOOD, ResourceType.CLAY)
- assertEquals("\"W/C\"", gson.toJson(prodIncrease))
+ assertEquals("\"W/C\"", Json.encodeToString(prodIncrease))
}
@Test
fun serialize_choice3() {
val prodIncrease = createChoice(ResourceType.WOOD, ResourceType.ORE, ResourceType.CLAY)
- assertEquals("\"W/O/C\"", gson.toJson(prodIncrease))
+ assertEquals("\"W/O/C\"", Json.encodeToString(prodIncrease))
}
@Test
fun serialize_choice2_unordered() {
val prodIncrease = createChoice(ResourceType.CLAY, ResourceType.WOOD)
- assertEquals("\"W/C\"", gson.toJson(prodIncrease))
+ assertEquals("\"W/C\"", Json.encodeToString(prodIncrease))
}
@Test
fun serialize_choice3_unordered() {
val prodIncrease = createChoice(ResourceType.WOOD, ResourceType.CLAY, ResourceType.ORE)
- assertEquals("\"W/O/C\"", gson.toJson(prodIncrease))
+ assertEquals("\"W/O/C\"", Json.encodeToString(prodIncrease))
}
@Test
@@ -113,7 +97,7 @@ class ProductionSerializerTest {
val production = createChoice(ResourceType.WOOD, ResourceType.CLAY)
production.addChoice(ResourceType.ORE, ResourceType.GLASS)
assertFailsWith<IllegalArgumentException> {
- gson.toJson(production)
+ Json.encodeToString(production)
}
}
@@ -122,87 +106,86 @@ class ProductionSerializerTest {
val production = create(1, 0, 0)
production.addChoice(ResourceType.WOOD, ResourceType.CLAY)
assertFailsWith<IllegalArgumentException> {
- gson.toJson(production)
+ Json.encodeToString(production)
}
}
@Test
fun deserialize_nullFromNull() {
- assertNull(gson.fromJson("null", Production::class.java))
+ assertNull(Json.decodeFromString<Production?>("null"))
}
@Test
fun deserialize_emptyList() {
- val prodIncrease = Production()
- assertEquals(prodIncrease, gson.fromJson("\"\""))
+ assertEquals(Production(), Json.decodeFromString("\"\""))
}
@Test
fun deserialize_failOnGarbageString() {
assertFailsWith<IllegalArgumentException> {
- gson.fromJson<Production>("\"this is garbage\"")
+ Json.decodeFromString<Production>("\"this is garbage\"")
}
}
@Test
fun deserialize_failOnGarbageStringWithSlashes() {
assertFailsWith<IllegalArgumentException> {
- gson.fromJson<Production>("\"this/is/garbage\"")
+ Json.decodeFromString<Production>("\"this/is/garbage\"")
}
}
@Test
fun deserialize_singleType() {
val prodIncrease = create(1, 0, 0)
- assertEquals(prodIncrease, gson.fromJson("\"W\""))
+ assertEquals(prodIncrease, Json.decodeFromString("\"W\""))
}
@Test
fun deserialize_multipleTimesSameType() {
val prodIncrease = create(3, 0, 0)
- assertEquals(prodIncrease, gson.fromJson("\"WWW\""))
+ assertEquals(prodIncrease, Json.decodeFromString("\"WWW\""))
}
@Test
fun deserialize_mixedTypes() {
val prodIncrease = create(1, 1, 1)
- assertEquals(prodIncrease, gson.fromJson("\"WCS\""))
+ assertEquals(prodIncrease, Json.decodeFromString("\"WCS\""))
}
@Test
fun deserialize_mixedTypes_unordered() {
val prodIncrease = create(1, 3, 2)
- assertEquals(prodIncrease, gson.fromJson("\"SCWCSS\""))
+ assertEquals(prodIncrease, Json.decodeFromString("\"SCWCSS\""))
}
@Test
fun deserialize_choice2() {
val prodIncrease = createChoice(ResourceType.WOOD, ResourceType.CLAY)
- assertEquals(prodIncrease, gson.fromJson("\"W/C\""))
+ assertEquals(prodIncrease, Json.decodeFromString("\"W/C\""))
}
@Test
fun deserialize_choice3() {
val prodIncrease = createChoice(ResourceType.WOOD, ResourceType.ORE, ResourceType.CLAY)
- assertEquals(prodIncrease, gson.fromJson("\"W/O/C\""))
+ assertEquals(prodIncrease, Json.decodeFromString("\"W/O/C\""))
}
@Test
fun deserialize_choice2_unordered() {
val prodIncrease = createChoice(ResourceType.CLAY, ResourceType.WOOD)
- assertEquals(prodIncrease, gson.fromJson("\"W/C\""))
+ assertEquals(prodIncrease, Json.decodeFromString("\"W/C\""))
}
@Test
fun deserialize_choice3_unordered() {
val prodIncrease = createChoice(ResourceType.WOOD, ResourceType.CLAY, ResourceType.ORE)
- assertEquals(prodIncrease, gson.fromJson("\"W/O/C\""))
+ assertEquals(prodIncrease, Json.decodeFromString("\"W/O/C\""))
}
@Test
fun deserialize_failOnMultipleResourcesInChoice() {
assertFailsWith<IllegalArgumentException> {
- gson.fromJson<Production>("\"W/SS/C\"")
+ Json.decodeFromString<Production>("\"W/SS/C\"")
}
}
}
diff --git a/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourceTypeSerializerTest.kt b/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourceTypeSerializerTest.kt
index e256efc3..3956ff0c 100644
--- a/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourceTypeSerializerTest.kt
+++ b/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourceTypeSerializerTest.kt
@@ -1,9 +1,7 @@
package org.luxons.sevenwonders.engine.data.serializers
-import com.github.salomonbrys.kotson.fromJson
-import com.google.gson.Gson
-import com.google.gson.GsonBuilder
-import org.junit.Before
+import kotlinx.serialization.builtins.nullable
+import kotlinx.serialization.json.Json
import org.junit.Test
import org.luxons.sevenwonders.model.resources.ResourceType
import kotlin.test.assertEquals
@@ -12,45 +10,38 @@ import kotlin.test.assertNull
class ResourceTypeSerializerTest {
- private lateinit var gson: Gson
-
- @Before
- fun setUp() {
- gson = GsonBuilder().registerTypeAdapter(ResourceType::class.java, ResourceTypeSerializer()).create()
- }
-
@Test
fun serialize_useSymbolForEachType() {
ResourceType.values().forEach { type ->
- val expectedJson = "\"" + type.symbol + "\""
- assertEquals(expectedJson, gson.toJson(type))
+ val expectedjson = "\"" + type.symbol + "\""
+ assertEquals(expectedjson, Json.encodeToString(ResourceTypeSerializer, type))
}
}
@Test
fun deserialize_useSymbolForEachType() {
ResourceType.values().forEach { type ->
- val typeInJson = "\"" + type.symbol + "\""
- assertEquals(type, gson.fromJson(typeInJson))
+ val typeInjson = "\"" + type.symbol + "\""
+ assertEquals(type, Json.decodeFromString(ResourceTypeSerializer, typeInjson))
}
}
@Test
fun deserialize_nullFromNull() {
- assertNull(gson.fromJson("null", ResourceType::class.java))
+ assertNull(Json.decodeFromString(ResourceTypeSerializer.nullable, "null"))
}
@Test
fun deserialize_failsOnEmptyString() {
assertFailsWith<IllegalArgumentException> {
- gson.fromJson<ResourceType>("\"\"")
+ Json.decodeFromString(ResourceTypeSerializer, "\"\"")
}
}
@Test
fun deserialize_failsOnGarbageString() {
assertFailsWith<IllegalArgumentException> {
- gson.fromJson<ResourceType>("\"thisisgarbage\"")
+ Json.decodeFromString(ResourceTypeSerializer, "\"thisisgarbage\"")
}
}
}
diff --git a/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourceTypesSerializerTest.kt b/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourceTypesSerializerTest.kt
index 8c2ce2fc..b7ea6c9e 100644
--- a/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourceTypesSerializerTest.kt
+++ b/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourceTypesSerializerTest.kt
@@ -1,11 +1,7 @@
package org.luxons.sevenwonders.engine.data.serializers
-import com.github.salomonbrys.kotson.fromJson
-import com.github.salomonbrys.kotson.typeToken
-import com.github.salomonbrys.kotson.typedToJson
-import com.google.gson.Gson
-import com.google.gson.GsonBuilder
-import org.junit.Before
+import kotlinx.serialization.builtins.nullable
+import kotlinx.serialization.json.Json
import org.junit.Test
import org.luxons.sevenwonders.model.resources.ResourceType
import kotlin.test.assertEquals
@@ -13,68 +9,61 @@ import kotlin.test.assertNull
class ResourceTypesSerializerTest {
- private lateinit var gson: Gson
-
- @Before
- fun setUp() {
- gson = GsonBuilder().registerTypeAdapter(typeToken<List<ResourceType>>(), ResourceTypesSerializer()).create()
- }
-
@Test
fun serialize_null() {
- assertEquals("null", gson.toJson(null, typeToken<List<ResourceType>>()))
+ assertEquals("null", Json.encodeToString(ResourceTypesSerializer.nullable, null))
}
@Test
fun serialize_emptyList() {
val types = emptyList<ResourceType>()
- assertEquals("\"\"", gson.typedToJson(types))
+ assertEquals("\"\"", Json.encodeToString(ResourceTypesSerializer, types))
}
@Test
fun serialize_singleType() {
val types = listOf(ResourceType.WOOD)
- assertEquals("\"W\"", gson.typedToJson(types))
+ assertEquals("\"W\"", Json.encodeToString(ResourceTypesSerializer, types))
}
@Test
fun serialize_multipleTimesSameType() {
val types = List(3) { ResourceType.WOOD }
- assertEquals("\"WWW\"", gson.typedToJson(types))
+ assertEquals("\"WWW\"", Json.encodeToString(ResourceTypesSerializer, types))
}
@Test
fun serialize_mixedTypes() {
val types = listOf(ResourceType.WOOD, ResourceType.CLAY, ResourceType.STONE)
- assertEquals("\"WCS\"", gson.typedToJson(types))
+ assertEquals("\"WCS\"", Json.encodeToString(ResourceTypesSerializer, types))
}
@Test
fun deserialize_null() {
- assertNull(gson.fromJson("null", typeToken<List<ResourceType>>()))
+ assertNull(Json.decodeFromString(ResourceTypesSerializer.nullable, "null"))
}
@Test
fun deserialize_emptyList() {
val types = emptyList<ResourceType>()
- assertEquals(types, gson.fromJson("\"\""))
+ assertEquals(types, Json.decodeFromString(ResourceTypesSerializer, "\"\""))
}
@Test
fun deserialize_singleType() {
val types = listOf(ResourceType.WOOD)
- assertEquals(types, gson.fromJson("\"W\""))
+ assertEquals(types, Json.decodeFromString(ResourceTypesSerializer, "\"W\""))
}
@Test
fun deserialize_multipleTimesSameType() {
val types = List(3) { ResourceType.WOOD }
- assertEquals(types, gson.fromJson("\"WWW\""))
+ assertEquals(types, Json.decodeFromString(ResourceTypesSerializer, "\"WWW\""))
}
@Test
fun deserialize_mixedTypes() {
val types = listOf(ResourceType.WOOD, ResourceType.CLAY, ResourceType.STONE)
- assertEquals(types, gson.fromJson("\"WCS\""))
+ assertEquals(types, Json.decodeFromString(ResourceTypesSerializer, "\"WCS\""))
}
}
diff --git a/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourcesSerializerTest.kt b/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourcesSerializerTest.kt
index bc5808a0..614babe4 100644
--- a/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourcesSerializerTest.kt
+++ b/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ResourcesSerializerTest.kt
@@ -1,99 +1,93 @@
package org.luxons.sevenwonders.engine.data.serializers
-import com.github.salomonbrys.kotson.fromJson
-import com.google.gson.Gson
-import com.google.gson.GsonBuilder
-import org.junit.Before
+import kotlinx.serialization.builtins.nullable
+import kotlinx.serialization.decodeFromString
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.Json
+import kotlinx.serialization.modules.SerializersModule
import org.junit.Test
-import org.luxons.sevenwonders.engine.resources.MutableResources
import org.luxons.sevenwonders.engine.resources.Resources
import org.luxons.sevenwonders.engine.resources.emptyResources
import org.luxons.sevenwonders.engine.resources.resourcesOf
-import org.luxons.sevenwonders.model.resources.ResourceType.CLAY
-import org.luxons.sevenwonders.model.resources.ResourceType.STONE
-import org.luxons.sevenwonders.model.resources.ResourceType.WOOD
+import org.luxons.sevenwonders.model.resources.ResourceType.*
import kotlin.test.assertEquals
import kotlin.test.assertNull
class ResourcesSerializerTest {
- private lateinit var gson: Gson
-
- @Before
- fun setUp() {
- gson = GsonBuilder() //
- .registerTypeAdapter(Resources::class.java, ResourcesSerializer())
- .registerTypeAdapter(MutableResources::class.java, ResourcesSerializer())
- .create()
+ private val json: Json = Json {
+ serializersModule = SerializersModule {
+ contextual(Resources::class, ResourcesSerializer)
+ }
}
@Test
fun serialize_null() {
- assertEquals("null", gson.toJson(null, Resources::class.java))
+ assertEquals("null", json.encodeToString(ResourcesSerializer.nullable, null))
}
@Test
fun serialize_emptyResourcesToNull() {
val resources = emptyResources()
- assertEquals("null", gson.toJson(resources))
+ assertEquals("null", json.encodeToString(resources))
}
@Test
fun serialize_singleType() {
val resources = resourcesOf(WOOD)
- assertEquals("\"W\"", gson.toJson(resources))
+ assertEquals("\"W\"", json.encodeToString(resources))
}
@Test
fun serialize_multipleTimesSameType() {
val resources = resourcesOf(WOOD to 3)
- assertEquals("\"WWW\"", gson.toJson(resources))
+ assertEquals("\"WWW\"", json.encodeToString(resources))
}
@Test
fun serialize_mixedTypes() {
val resources = resourcesOf(WOOD, STONE, CLAY)
- assertEquals("\"WSC\"", gson.toJson(resources))
+ assertEquals("\"WSC\"", json.encodeToString(resources))
}
@Test
fun serialize_mixedTypes_unordered() {
val resources = resourcesOf(CLAY to 1, WOOD to 2, CLAY to 1, STONE to 1)
- assertEquals("\"CCWWS\"", gson.toJson(resources))
+ assertEquals("\"CCWWS\"", json.encodeToString(resources))
}
@Test
fun deserialize_null() {
- assertNull(gson.fromJson("null", Resources::class.java))
+ assertNull(json.decodeFromString<Resources?>("null"))
}
@Test
fun deserialize_emptyList() {
val resources = emptyResources()
- assertEquals(resources, gson.fromJson("\"\""))
+ assertEquals(resources, json.decodeFromString("\"\""))
}
@Test
fun deserialize_singleType() {
val resources = resourcesOf(WOOD)
- assertEquals(resources, gson.fromJson("\"W\""))
+ assertEquals(resources, json.decodeFromString("\"W\""))
}
@Test
fun deserialize_multipleTimesSameType() {
val resources = resourcesOf(WOOD to 3)
- assertEquals(resources, gson.fromJson("\"WWW\""))
+ assertEquals(resources, json.decodeFromString("\"WWW\""))
}
@Test
fun deserialize_mixedTypes() {
val resources = resourcesOf(WOOD, CLAY, STONE)
- assertEquals(resources, gson.fromJson("\"WCS\""))
+ assertEquals(resources, json.decodeFromString("\"WCS\""))
}
@Test
fun deserialize_mixedTypes_unordered() {
val resources = resourcesOf(WOOD to 1, CLAY to 2, STONE to 3)
- assertEquals(resources, gson.fromJson("\"SCWCSS\""))
+ assertEquals(resources, json.decodeFromString("\"SCWCSS\""))
}
}
diff --git a/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ScienceProgressSerializerTest.kt b/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ScienceProgressSerializerTest.kt
index 19b1e572..1519ec7e 100644
--- a/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ScienceProgressSerializerTest.kt
+++ b/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/data/serializers/ScienceProgressSerializerTest.kt
@@ -1,9 +1,8 @@
package org.luxons.sevenwonders.engine.data.serializers
-import com.github.salomonbrys.kotson.fromJson
-import com.google.gson.Gson
-import com.google.gson.GsonBuilder
-import org.junit.Before
+import kotlinx.serialization.decodeFromString
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.Json
import org.junit.Test
import org.luxons.sevenwonders.engine.boards.ScienceType
import org.luxons.sevenwonders.engine.effects.ScienceProgress
@@ -19,45 +18,38 @@ private const val JOKER_STR = "\"any\""
class ScienceProgressSerializerTest {
- private lateinit var gson: Gson
-
- @Before
- fun setUp() {
- gson = GsonBuilder().registerTypeAdapter(ScienceProgress::class.java, ScienceProgressSerializer()).create()
- }
-
@Test
fun serialize_emptyToNull() {
val progress = createScienceProgress(0, 0, 0, 0)
- val json = gson.toJson(progress)
+ val json = Json.encodeToString(progress)
assertEquals("null", json)
}
@Test
fun serialize_oneCompass() {
val progress = createScienceProgress(1, 0, 0, 0)
- val json = gson.toJson(progress)
+ val json = Json.encodeToString(progress)
assertEquals(COMPASS_STR, json)
}
@Test
fun serialize_oneWheel() {
val progress = createScienceProgress(0, 1, 0, 0)
- val json = gson.toJson(progress)
+ val json = Json.encodeToString(progress)
assertEquals(WHEEL_STR, json)
}
@Test
fun serialize_oneTablet() {
val progress = createScienceProgress(0, 0, 1, 0)
- val json = gson.toJson(progress)
+ val json = Json.encodeToString(progress)
assertEquals(TABLET_STR, json)
}
@Test
fun serialize_oneJoker() {
val progress = createScienceProgress(0, 0, 0, 1)
- val json = gson.toJson(progress)
+ val json = Json.encodeToString(progress)
assertEquals(JOKER_STR, json)
}
@@ -65,7 +57,7 @@ class ScienceProgressSerializerTest {
fun serialize_failOnMultipleCompasses() {
assertFailsWith<UnsupportedOperationException> {
val progress = createScienceProgress(2, 0, 0, 0)
- gson.toJson(progress)
+ Json.encodeToString(progress)
}
}
@@ -73,7 +65,7 @@ class ScienceProgressSerializerTest {
fun serialize_failOnMultipleWheels() {
assertFailsWith<UnsupportedOperationException> {
val progress = createScienceProgress(0, 2, 0, 0)
- gson.toJson(progress)
+ Json.encodeToString(progress)
}
}
@@ -81,7 +73,7 @@ class ScienceProgressSerializerTest {
fun serialize_failOnMultipleTablets() {
assertFailsWith<UnsupportedOperationException> {
val progress = createScienceProgress(0, 0, 2, 0)
- gson.toJson(progress)
+ Json.encodeToString(progress)
}
}
@@ -89,7 +81,7 @@ class ScienceProgressSerializerTest {
fun serialize_failOnMultipleJokers() {
assertFailsWith<UnsupportedOperationException> {
val progress = createScienceProgress(0, 0, 0, 2)
- gson.toJson(progress)
+ Json.encodeToString(progress)
}
}
@@ -97,27 +89,27 @@ class ScienceProgressSerializerTest {
fun serialize_failOnMixedElements() {
assertFailsWith<UnsupportedOperationException> {
val progress = createScienceProgress(1, 1, 0, 0)
- gson.toJson(progress)
+ Json.encodeToString(progress)
}
}
@Test
fun deserialize_failOnEmptyString() {
assertFailsWith<IllegalArgumentException> {
- gson.fromJson<ScienceProgress>("\"\"")
+ Json.decodeFromString<ScienceProgress>("\"\"")
}
}
@Test
fun deserialize_failOnGarbageString() {
assertFailsWith<IllegalArgumentException> {
- gson.fromJson<ScienceProgress>("thisisgarbage")
+ Json.decodeFromString<ScienceProgress>("thisisgarbage")
}
}
@Test
fun deserialize_compass() {
- val progress = gson.fromJson<ScienceProgress>(COMPASS_STR)
+ val progress = Json.decodeFromString<ScienceProgress>(COMPASS_STR)
assertNotNull(progress.science)
assertEquals(1, progress.science.getQuantity(ScienceType.COMPASS))
assertEquals(0, progress.science.getQuantity(ScienceType.WHEEL))
@@ -127,7 +119,7 @@ class ScienceProgressSerializerTest {
@Test
fun deserialize_wheel() {
- val progress = gson.fromJson<ScienceProgress>(WHEEL_STR)
+ val progress = Json.decodeFromString<ScienceProgress>(WHEEL_STR)
assertNotNull(progress.science)
assertEquals(0, progress.science.getQuantity(ScienceType.COMPASS))
assertEquals(1, progress.science.getQuantity(ScienceType.WHEEL))
@@ -137,7 +129,7 @@ class ScienceProgressSerializerTest {
@Test
fun deserialize_tablet() {
- val progress = gson.fromJson<ScienceProgress>(TABLET_STR)
+ val progress = Json.decodeFromString<ScienceProgress>(TABLET_STR)
assertNotNull(progress.science)
assertEquals(0, progress.science.getQuantity(ScienceType.COMPASS))
assertEquals(0, progress.science.getQuantity(ScienceType.WHEEL))
@@ -147,7 +139,7 @@ class ScienceProgressSerializerTest {
@Test
fun deserialize_joker() {
- val progress = gson.fromJson<ScienceProgress>(JOKER_STR)
+ val progress = Json.decodeFromString<ScienceProgress>(JOKER_STR)
assertNotNull(progress.science)
assertEquals(0, progress.science.getQuantity(ScienceType.COMPASS))
assertEquals(0, progress.science.getQuantity(ScienceType.WHEEL))
bgstack15