From 719fcf03862174be1454731c59128d278e9523be Mon Sep 17 00:00:00 2001 From: joffrey-bion Date: Fri, 27 Nov 2020 01:25:09 +0100 Subject: Introduce priced transactions This is useful to provide information about the price per provider. --- .../engine/cards/RequirementsSatisfaction.kt | 8 +++---- .../engine/resources/BestPriceCalculator.kt | 26 ++++++++++++---------- .../engine/resources/ResourceTransactions.kt | 9 +++----- 3 files changed, 21 insertions(+), 22 deletions(-) (limited to 'sw-engine/src/main') diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/cards/RequirementsSatisfaction.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/cards/RequirementsSatisfaction.kt index 3a1ac5ce..f9566981 100644 --- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/cards/RequirementsSatisfaction.kt +++ b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/cards/RequirementsSatisfaction.kt @@ -1,14 +1,14 @@ package org.luxons.sevenwonders.engine.cards import org.luxons.sevenwonders.model.cards.PlayabilityLevel -import org.luxons.sevenwonders.model.resources.ResourceTransactions +import org.luxons.sevenwonders.model.resources.PricedResourceTransactions import org.luxons.sevenwonders.model.resources.noTransactions internal data class RequirementsSatisfaction( val satisfied: Boolean, val level: PlayabilityLevel, val minPrice: Int, - val cheapestTransactions: Set, + val cheapestTransactions: Set, ) { companion object { @@ -24,13 +24,13 @@ internal data class RequirementsSatisfaction( internal fun enoughResourcesAndGold(minPrice: Int) = RequirementsSatisfaction(true, PlayabilityLevel.ENOUGH_GOLD_AND_RES, minPrice, setOf(noTransactions())) - internal fun metWithHelp(minPrice: Int, cheapestTransactions: Set) = + internal fun metWithHelp(minPrice: Int, cheapestTransactions: Set) = RequirementsSatisfaction(true, PlayabilityLevel.REQUIRES_HELP, minPrice, cheapestTransactions) internal fun missingRequiredGold(minPrice: Int) = RequirementsSatisfaction(false, PlayabilityLevel.MISSING_REQUIRED_GOLD, minPrice, emptySet()) - internal fun missingGoldForResources(minPrice: Int, cheapestTransactions: Set) = + internal fun missingGoldForResources(minPrice: Int, cheapestTransactions: Set) = RequirementsSatisfaction(false, PlayabilityLevel.MISSING_GOLD_FOR_RES, minPrice, cheapestTransactions) internal fun unavailableResources() = 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 846e7fd2..967bee2c 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 @@ -1,16 +1,15 @@ package org.luxons.sevenwonders.engine.resources import org.luxons.sevenwonders.engine.Player +import org.luxons.sevenwonders.model.resources.PricedResourceTransactions import org.luxons.sevenwonders.model.resources.Provider -import org.luxons.sevenwonders.model.resources.ResourceTransactions import org.luxons.sevenwonders.model.resources.ResourceType -import java.util.EnumMap -import java.util.EnumSet +import java.util.* internal fun bestSolution(resources: Resources, player: Player): TransactionPlan = BestPriceCalculator(resources, player).computeBestSolution() -data class TransactionPlan(val price: Int, val possibleTransactions: Set) +data class TransactionPlan(val price: Int, val possibleTransactions: Set) private class ResourcePool( val provider: Provider?, @@ -27,9 +26,10 @@ private class BestPriceCalculator(resourcesToPay: Resources, player: Player) { private val pools: List private val resourcesLeftToPay: MutableResources private val boughtResources: MutableMap = EnumMap(Provider::class.java) - private var pricePaid: Int = 0 + private val pricePaid: MutableMap = EnumMap(Provider::class.java) + private var totalPricePaid: Int = 0 - private var bestSolutions: MutableSet = mutableSetOf() + private var bestSolutions: MutableSet = mutableSetOf() private var bestPrice: Int = Integer.MAX_VALUE init { @@ -93,11 +93,13 @@ private class BestPriceCalculator(resourcesToPay: Resources, player: Player) { fun buyOne(provider: Provider, type: ResourceType, cost: Int) { boughtResources.getOrPut(provider) { MutableResources() }.add(type, 1) - pricePaid += cost + pricePaid.merge(provider, cost) { old, new -> old + new } + totalPricePaid += cost } fun unbuyOne(provider: Provider, type: ResourceType, cost: Int) { - pricePaid -= cost + totalPricePaid -= cost + pricePaid.merge(provider, -cost) { old, new -> old + new } boughtResources[provider]!!.remove(type, 1) } @@ -113,14 +115,14 @@ private class BestPriceCalculator(resourcesToPay: Resources, player: Player) { } private fun updateBestSolutionIfNeeded() { - if (pricePaid > bestPrice) return + if (totalPricePaid > bestPrice) return - if (pricePaid < bestPrice) { - bestPrice = pricePaid + if (totalPricePaid < bestPrice) { + bestPrice = totalPricePaid bestSolutions.clear() } // avoid mutating the resources from the transactions - val transactionSet = boughtResources.mapValues { (_, res) -> res.copy() }.toTransactions() + val transactionSet = boughtResources.mapValues { (_, res) -> res.copy() }.toTransactions(pricePaid) bestSolutions.add(transactionSet) } } diff --git a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/resources/ResourceTransactions.kt b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/resources/ResourceTransactions.kt index c3e0fefa..c6309151 100644 --- a/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/resources/ResourceTransactions.kt +++ b/sw-engine/src/main/kotlin/org/luxons/sevenwonders/engine/resources/ResourceTransactions.kt @@ -2,14 +2,11 @@ package org.luxons.sevenwonders.engine.resources import org.luxons.sevenwonders.engine.Player import org.luxons.sevenwonders.engine.converters.toCountedResourcesList -import org.luxons.sevenwonders.model.resources.CountedResource -import org.luxons.sevenwonders.model.resources.Provider -import org.luxons.sevenwonders.model.resources.ResourceTransaction -import org.luxons.sevenwonders.model.resources.ResourceTransactions +import org.luxons.sevenwonders.model.resources.* -fun Map.toTransactions(): ResourceTransactions = // +fun Map.toTransactions(price: Map): PricedResourceTransactions = // filterValues { !it.isEmpty() } // - .map { (p, res) -> ResourceTransaction(p, res.toCountedResourcesList()) } // + .map { (p, res) -> PricedResourceTransaction(p, res.toCountedResourcesList(), price[p]!!) } // .toSet() fun ResourceTransactions.asResources(): Resources = flatMap { it.resources }.asResources() -- cgit