summaryrefslogtreecommitdiff
path: root/sw-engine
diff options
context:
space:
mode:
authorJoffrey Bion <joffrey.bion@booking.com>2020-05-28 13:03:36 +0200
committerJoffrey Bion <joffrey.bion@booking.com>2020-05-28 13:34:57 +0200
commit4178ba9700ffd6619f995482a369bd5133276e2e (patch)
tree497223513f61a7162d78213e1c9fe7de16064e25 /sw-engine
parentClarify message for unavailable resources (diff)
downloadseven-wonders-4178ba9700ffd6619f995482a369bd5133276e2e.tar.gz
seven-wonders-4178ba9700ffd6619f995482a369bd5133276e2e.tar.bz2
seven-wonders-4178ba9700ffd6619f995482a369bd5133276e2e.zip
Fix production alternative duplicates
Having twice the same choice wasn't supported so far. This can happen with Alexandria's bonuses (4 primary resources, or 3 secondary) associated to the yellow Market/Caravansery cards. Resolves: https://github.com/joffrey-bion/seven-wonders/issues/19
Diffstat (limited to 'sw-engine')
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/converters/Boards.kt2
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/data/serializers/ProductionSerializer.kt4
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/resources/BestPriceCalculator.kt2
-rw-r--r--sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/resources/Production.kt11
-rw-r--r--sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/resources/ProductionTest.kt41
5 files changed, 45 insertions, 15 deletions
diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/converters/Boards.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/converters/Boards.kt
index 7ff870cf..0d8369ac 100644
--- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/converters/Boards.kt
+++ b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/converters/Boards.kt
@@ -73,7 +73,7 @@ internal fun InternalWonderStage.toApiWonderStage(isLastBuiltStage: Boolean, las
internal fun InternalProduction.toApiProduction(): ApiProduction =
ApiProduction(
fixedResources = getFixedResources().toCountedResourcesList(),
- alternativeResources = getAlternativeResources()
+ alternativeResources = getAlternativeResources().sortedBy { it.size }
)
internal fun InternalRequirements.toApiRequirements(): ApiRequirements =
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 467b0912..c98f20a8 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
@@ -24,14 +24,14 @@ internal class ProductionSerializer : JsonSerializer<Production>, JsonDeserializ
}
}
- private fun serializeAsChoice(choices: Set<Set<ResourceType>>, context: JsonSerializationContext): JsonElement {
+ private fun serializeAsChoice(choices: List<Set<ResourceType>>, context: JsonSerializationContext): JsonElement {
if (choices.isEmpty()) {
return JsonNull.INSTANCE
}
if (choices.size > 1) {
throw IllegalArgumentException("Cannot serialize a production with more than one choice")
}
- val str = choices.flatten().map { it.symbol }.joinToString("/")
+ val str = choices[0].map { it.symbol }.joinToString("/")
return context.serialize(str)
}
diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/resources/BestPriceCalculator.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/resources/BestPriceCalculator.kt
index 85b07a80..dd2d2cae 100644
--- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/resources/BestPriceCalculator.kt
+++ b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/resources/BestPriceCalculator.kt
@@ -15,7 +15,7 @@ data class TransactionPlan(val price: Int, val possibleTransactions: Set<Resourc
private class ResourcePool(
val provider: Provider?,
private val rules: TradingRules,
- choices: Set<Set<ResourceType>>
+ choices: List<Set<ResourceType>>
) {
val choices: Set<MutableSet<ResourceType>> = choices.mapTo(HashSet()) { it.toMutableSet() }
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 46ec66f7..4f9bbe90 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
@@ -5,11 +5,12 @@ import java.util.EnumSet
data class Production internal constructor(
private val fixedResources: MutableResources = mutableResourcesOf(),
- private val alternativeResources: MutableSet<Set<ResourceType>> = mutableSetOf()
+ // cannot be a Set because the same choices can be there multiple times
+ private val alternativeResources: MutableList<Set<ResourceType>> = mutableListOf()
) {
fun getFixedResources(): Resources = fixedResources
- fun getAlternativeResources(): Set<Set<ResourceType>> = alternativeResources
+ fun getAlternativeResources(): List<Set<ResourceType>> = alternativeResources
fun addFixedResource(type: ResourceType, quantity: Int) = fixedResources.add(type, quantity)
@@ -25,8 +26,8 @@ data class Production internal constructor(
alternativeResources.addAll(production.getAlternativeResources())
}
- internal fun asChoices(): Set<Set<ResourceType>> {
- val fixedAsChoices = fixedResources.toList().mapTo(HashSet()) { EnumSet.of(it) }
+ internal fun asChoices(): List<Set<ResourceType>> {
+ val fixedAsChoices = fixedResources.toList().map { EnumSet.of(it) }
return fixedAsChoices + alternativeResources
}
@@ -42,7 +43,7 @@ data class Production internal constructor(
private fun containedInAlternatives(
resources: MutableResources,
- alternatives: MutableSet<Set<ResourceType>>
+ alternatives: MutableList<Set<ResourceType>>
): Boolean {
if (resources.isEmpty()) {
return true
diff --git a/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/resources/ProductionTest.kt b/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/resources/ProductionTest.kt
index c449c784..9bc04142 100644
--- a/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/resources/ProductionTest.kt
+++ b/sw-engine/src/test/kotlin/org/luxons/sevenwonders/engine/resources/ProductionTest.kt
@@ -11,7 +11,6 @@ import org.luxons.sevenwonders.model.resources.ResourceType.PAPYRUS
import org.luxons.sevenwonders.model.resources.ResourceType.STONE
import org.luxons.sevenwonders.model.resources.ResourceType.WOOD
import java.util.EnumSet
-import java.util.HashSet
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
@@ -228,12 +227,22 @@ class ProductionTest {
}
@Test
+ fun asChoices_withDuplicateChoices() {
+ val production = Production()
+ production.addChoice(STONE, WOOD)
+ production.addChoice(STONE, ORE)
+ production.addChoice(STONE, ORE)
+ production.addChoice(CLAY, LOOM, GLASS)
+ assertEquals(production.getAlternativeResources(), production.asChoices())
+ }
+
+ @Test
fun asChoices_onlyFixed() {
val production = Production()
production.addFixedResource(WOOD, 1)
production.addFixedResource(CLAY, 2)
- val expected = HashSet<Set<ResourceType>>()
+ val expected = mutableListOf<Set<ResourceType>>()
expected.add(EnumSet.of(WOOD))
expected.add(EnumSet.of(CLAY))
expected.add(EnumSet.of(CLAY))
@@ -249,12 +258,32 @@ class ProductionTest {
production.addFixedResource(WOOD, 1)
production.addFixedResource(CLAY, 2)
- val expected = HashSet<Set<ResourceType>>()
+ val expected = mutableListOf<Set<ResourceType>>()
+ expected.add(EnumSet.of(WOOD))
+ expected.add(EnumSet.of(CLAY))
+ expected.add(EnumSet.of(CLAY))
expected.add(EnumSet.of(STONE, ORE))
expected.add(EnumSet.of(CLAY, LOOM, GLASS))
+
+ assertEquals(expected, production.asChoices())
+ }
+
+ @Test
+ fun asChoices_mixed_withDuplicates() {
+ val production = Production()
+ production.addChoice(STONE, ORE)
+ production.addChoice(CLAY, LOOM, GLASS)
+ production.addChoice(STONE, ORE)
+ production.addFixedResource(WOOD, 1)
+ production.addFixedResource(CLAY, 2)
+
+ val expected = mutableListOf<Set<ResourceType>>()
expected.add(EnumSet.of(WOOD))
expected.add(EnumSet.of(CLAY))
expected.add(EnumSet.of(CLAY))
+ expected.add(EnumSet.of(STONE, ORE))
+ expected.add(EnumSet.of(CLAY, LOOM, GLASS))
+ expected.add(EnumSet.of(STONE, ORE))
assertEquals(expected, production.asChoices())
}
@@ -269,13 +298,13 @@ class ProductionTest {
fun equals_trueWhenSameContent() {
val production1 = Production()
val production2 = Production()
- assertTrue(production1 == production2)
+ assertEquals(production1, production2)
production1.addFixedResource(GLASS, 1)
production2.addFixedResource(GLASS, 1)
- assertTrue(production1 == production2)
+ assertEquals(production1, production2)
production1.addChoice(ORE, WOOD)
production2.addChoice(ORE, WOOD)
- assertTrue(production1 == production2)
+ assertEquals(production1, production2)
}
@Test
bgstack15