diff options
5 files changed, 72 insertions, 26 deletions
diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.java b/backend/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.java index fb6c4e4b..2786143b 100644 --- a/backend/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.java +++ b/backend/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.java @@ -2,10 +2,6 @@ package org.luxons.sevenwonders.game.data.serializers; import java.lang.reflect.Type; import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.luxons.sevenwonders.game.resources.ResourceType; -import org.luxons.sevenwonders.game.resources.Resources; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; @@ -15,23 +11,24 @@ import com.google.gson.JsonParseException; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; +import org.luxons.sevenwonders.game.resources.ResourceType; +import org.luxons.sevenwonders.game.resources.Resources; public class ResourcesSerializer implements JsonSerializer<Resources>, JsonDeserializer<Resources> { @Override public JsonElement serialize(Resources resources, Type typeOfSrc, JsonSerializationContext context) { - String s = resources.getQuantities() - .entrySet() + String s = resources.asList() .stream() - .flatMap(e -> Stream.generate(() -> e.getKey().getSymbol()).limit(e.getValue())) + .map(ResourceType::getSymbol) .map(Object::toString) .collect(Collectors.joining()); return s.isEmpty() ? JsonNull.INSTANCE : new JsonPrimitive(s); } @Override - public Resources deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { + public Resources deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws + JsonParseException { String s = json.getAsString(); Resources resources = new Resources(); for (char c : s.toCharArray()) { diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/resources/Production.java b/backend/src/main/java/org/luxons/sevenwonders/game/resources/Production.java index ea824277..f85fb896 100644 --- a/backend/src/main/java/org/luxons/sevenwonders/game/resources/Production.java +++ b/backend/src/main/java/org/luxons/sevenwonders/game/resources/Production.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.EnumSet; import java.util.List; -import java.util.Map.Entry; import java.util.Objects; import java.util.Set; @@ -19,8 +18,7 @@ public class Production { } public void addChoice(ResourceType... options) { - EnumSet<ResourceType> optionSet = EnumSet.noneOf(ResourceType.class); - optionSet.addAll(Arrays.asList(options)); + EnumSet<ResourceType> optionSet = EnumSet.copyOf(Arrays.asList(options)); alternativeResources.add(optionSet); } @@ -57,20 +55,18 @@ public class Production { if (resources.isEmpty()) { return true; } - for (Entry<ResourceType, Integer> entry : resources.getQuantities().entrySet()) { - ResourceType type = entry.getKey(); - int count = entry.getValue(); - if (count <= 0) { + for (ResourceType type : ResourceType.values()) { + if (resources.getQuantity(type) <= 0) { continue; } Set<ResourceType> candidate = findFirstAlternativeContaining(alternatives, type); if (candidate == null) { return false; // no alternative produces the resource of this entry } - entry.setValue(count - 1); + resources.remove(type, 1); alternatives.remove(candidate); boolean remainingAreContainedToo = containedInAlternatives(resources, alternatives); - entry.setValue(count); + resources.add(type, 1); alternatives.add(candidate); if (remainingAreContainedToo) { return true; diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/resources/Resources.java b/backend/src/main/java/org/luxons/sevenwonders/game/resources/Resources.java index f74ae994..05bd7672 100644 --- a/backend/src/main/java/org/luxons/sevenwonders/game/resources/Resources.java +++ b/backend/src/main/java/org/luxons/sevenwonders/game/resources/Resources.java @@ -1,9 +1,13 @@ package org.luxons.sevenwonders.game.resources; import java.util.EnumMap; +import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.NoSuchElementException; import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; public class Resources { @@ -13,16 +17,26 @@ public class Resources { quantities.merge(type, quantity, (x, y) -> x + y); } + public void remove(ResourceType type, int quantity) { + if (getQuantity(type) < quantity) { + throw new NoSuchElementException(String.format("Can't remove %d resources of type %s", quantity, type)); + } + quantities.computeIfPresent(type, (t, oldQty) -> oldQty - quantity); + } + public void addAll(Resources resources) { - resources.getQuantities().forEach(this::add); + resources.quantities.forEach(this::add); } public int getQuantity(ResourceType type) { return quantities.getOrDefault(type, 0); } - public Map<ResourceType, Integer> getQuantities() { - return quantities; + public List<ResourceType> asList() { + return quantities.entrySet() + .stream() + .flatMap(e -> Stream.generate(e::getKey).limit(e.getValue())) + .collect(Collectors.toList()); } public boolean contains(Resources resources) { @@ -33,6 +47,14 @@ public class Resources { return quantity.getValue() <= getQuantity(quantity.getKey()); } + /** + * Creates new {@link Resources} object containing these resources minus the given resources. + * + * @param resources + * the resources to subtract from these resources + * + * @return a new {@link Resources} object containing these resources minus the given resources. + */ public Resources minus(Resources resources) { Resources diff = new Resources(); quantities.forEach((type, count) -> { diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/resources/TradingRules.java b/backend/src/main/java/org/luxons/sevenwonders/game/resources/TradingRules.java index 19409844..e35e8e03 100644 --- a/backend/src/main/java/org/luxons/sevenwonders/game/resources/TradingRules.java +++ b/backend/src/main/java/org/luxons/sevenwonders/game/resources/TradingRules.java @@ -3,7 +3,6 @@ package org.luxons.sevenwonders.game.resources; import java.util.EnumMap; import java.util.List; import java.util.Map; -import java.util.Map.Entry; public class TradingRules { @@ -29,11 +28,11 @@ public class TradingRules { public int computeCost(BoughtResources boughtResources) { Resources resources = boughtResources.getResources(); + Provider provider = boughtResources.getProvider(); int total = 0; - for (Entry<ResourceType, Integer> entry : resources.getQuantities().entrySet()) { - ResourceType type = entry.getKey(); - int count = entry.getValue(); - total += getCost(type, boughtResources.getProvider()) * count; + for (ResourceType type : ResourceType.values()) { + int count = resources.getQuantity(type); + total += getCost(type, provider) * count; } return total; } diff --git a/backend/src/test/java/org/luxons/sevenwonders/game/resources/ResourcesTest.java b/backend/src/test/java/org/luxons/sevenwonders/game/resources/ResourcesTest.java index cd352c8b..a2bad8b9 100644 --- a/backend/src/test/java/org/luxons/sevenwonders/game/resources/ResourcesTest.java +++ b/backend/src/test/java/org/luxons/sevenwonders/game/resources/ResourcesTest.java @@ -1,6 +1,10 @@ package org.luxons.sevenwonders.game.resources; +import java.util.NoSuchElementException; + +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -8,6 +12,9 @@ import static org.junit.Assert.assertTrue; public class ResourcesTest { + @Rule + public ExpectedException thrown = ExpectedException.none(); + @Test public void init_shouldBeEmpty() { Resources resources = new Resources(); @@ -49,6 +56,31 @@ public class ResourcesTest { } @Test + public void remove_some() { + Resources resources = new Resources(); + resources.add(ResourceType.WOOD, 3); + resources.remove(ResourceType.WOOD, 2); + assertEquals(1, resources.getQuantity(ResourceType.WOOD)); + } + + @Test + public void remove_all() { + Resources resources = new Resources(); + resources.add(ResourceType.WOOD, 3); + resources.remove(ResourceType.WOOD, 3); + assertEquals(0, resources.getQuantity(ResourceType.WOOD)); + } + + @Test + public void remove_tooMany() { + Resources resources = new Resources(); + resources.add(ResourceType.WOOD, 2); + + thrown.expect(NoSuchElementException.class); + resources.remove(ResourceType.WOOD, 3); + } + + @Test public void addAll_empty() { Resources resources = new Resources(); resources.add(ResourceType.STONE, 1); |