diff options
19 files changed, 587 insertions, 289 deletions
diff --git a/src/main/java/org/luxons/sevenwonders/game/Settings.java b/src/main/java/org/luxons/sevenwonders/game/Settings.java index 4d06c3e8..30e779df 100644 --- a/src/main/java/org/luxons/sevenwonders/game/Settings.java +++ b/src/main/java/org/luxons/sevenwonders/game/Settings.java @@ -1,5 +1,7 @@ package org.luxons.sevenwonders.game; +import java.util.Random; + import org.luxons.sevenwonders.game.wonders.WonderSide; public class Settings { @@ -12,6 +14,10 @@ public class Settings { private WonderSide wonderSide = WonderSide.A; + private Integer nbGuildCards = null; + + private long randomSeedForTests = 0; + public int getNbPlayers() { return nbPlayers; } @@ -43,4 +49,24 @@ public class Settings { public void setWonderSide(WonderSide wonderSide) { this.wonderSide = wonderSide; } + + public int getNbGuildCards() { + return nbGuildCards == null ? nbPlayers + 2 : nbGuildCards; + } + + public void setNbGuildCards(int nbGuildCards) { + this.nbGuildCards = nbGuildCards; + } + + public long getRandomSeedForTests() { + return randomSeedForTests; + } + + public void setRandomSeedForTests(long randomSeedForTests) { + this.randomSeedForTests = randomSeedForTests; + } + + public Random getRandom() { + return new Random(randomSeedForTests); + } } diff --git a/src/main/java/org/luxons/sevenwonders/game/cards/Color.java b/src/main/java/org/luxons/sevenwonders/game/cards/Color.java index 87d5b5b1..5b4e4473 100644 --- a/src/main/java/org/luxons/sevenwonders/game/cards/Color.java +++ b/src/main/java/org/luxons/sevenwonders/game/cards/Color.java @@ -1,5 +1,5 @@ package org.luxons.sevenwonders.game.cards; public enum Color { - BROWN, GREY, YELLOW, BLUE, GREEN, RED, PURPLE; + BROWN, GREY, YELLOW, BLUE, GREEN, RED, PURPLE } diff --git a/src/main/java/org/luxons/sevenwonders/game/data/Decks.java b/src/main/java/org/luxons/sevenwonders/game/data/Decks.java new file mode 100644 index 00000000..ea12ee8f --- /dev/null +++ b/src/main/java/org/luxons/sevenwonders/game/data/Decks.java @@ -0,0 +1,57 @@ +package org.luxons.sevenwonders.game.data; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.luxons.sevenwonders.game.Settings; +import org.luxons.sevenwonders.game.cards.Card; +import org.luxons.sevenwonders.game.data.definitions.CardDefinition; +import org.luxons.sevenwonders.game.data.definitions.DecksDefinition; + +public class Decks { + + private Map<Integer, List<Card>> cardsPerAge = new HashMap<>(); + + public Decks(DecksDefinition decksDefinition, Settings settings) { + cardsPerAge.put(1, prepareStandardDeck(decksDefinition.getAge1(), settings)); + cardsPerAge.put(2, prepareStandardDeck(decksDefinition.getAge2(), settings)); + cardsPerAge.put(3, prepareAge3Deck(decksDefinition, settings)); + } + + public List<Card> getCards(int age) { + return cardsPerAge.getOrDefault(age, Collections.emptyList()); + } + + private static List<Card> prepareStandardDeck(List<CardDefinition> defs, Settings settings) { + List<Card> cards = createDeck(defs, settings); + Collections.shuffle(cards, settings.getRandom()); + return cards; + } + + private static List<Card> prepareAge3Deck(DecksDefinition decksDefinition, Settings settings) { + List<Card> age3deck = createDeck(decksDefinition.getAge3(), settings); + age3deck.addAll(createGuildCards(decksDefinition.getGuildCards(), settings)); + Collections.shuffle(age3deck, settings.getRandom()); + return age3deck; + } + + private static List<Card> createDeck(List<CardDefinition> defs, Settings settings) { + List<Card> cards = new ArrayList<>(); + for (CardDefinition def : defs) { + for (int i = 0; i < def.getCountPerNbPlayer().get(settings.getNbPlayers()); i++) { + cards.add(def.create(settings)); + } + } + return cards; + } + + private static List<Card> createGuildCards(List<CardDefinition> defs, Settings settings) { + List<Card> guild = defs.stream().map((def) -> def.create(settings)).collect(Collectors.toList()); + Collections.shuffle(guild, settings.getRandom()); + return guild.subList(0, settings.getNbPlayers()); + } +} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/DecksDefinition.java b/src/main/java/org/luxons/sevenwonders/game/data/DecksDefinition.java deleted file mode 100644 index 914217a8..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/data/DecksDefinition.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.luxons.sevenwonders.game.data; - -import java.util.List; - -public class DecksDefinition { - - private List<CardDefinition> age1; - - private List<CardDefinition> age2; - - private List<CardDefinition> age3; - - private List<CardDefinition> guild; - - public List<CardDefinition> getAge1() { - return age1; - } - - public List<CardDefinition> getAge2() { - return age2; - } - - public List<CardDefinition> getAge3() { - return age3; - } - - public List<CardDefinition> getGuild() { - return guild; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/EffectParser.java b/src/main/java/org/luxons/sevenwonders/game/data/EffectParser.java deleted file mode 100644 index 62fe3d13..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/data/EffectParser.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.luxons.sevenwonders.game.data; - -import org.luxons.sevenwonders.game.effects.Effect; - -public class EffectParser { - - static Effect parse(String effectStr) { - // TODO - return null; - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/GameData.java b/src/main/java/org/luxons/sevenwonders/game/data/GameData.java index 20a353cd..9abf69c4 100644 --- a/src/main/java/org/luxons/sevenwonders/game/data/GameData.java +++ b/src/main/java/org/luxons/sevenwonders/game/data/GameData.java @@ -1,33 +1,19 @@ package org.luxons.sevenwonders.game.data; import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import org.luxons.sevenwonders.game.cards.Card; import org.luxons.sevenwonders.game.wonders.Wonder; public class GameData { - private int nbAges = 3; - private int minPlayers = 3; private int maxPlayers = 7; private List<Wonder> wonders = new ArrayList<>(); - private Map<Integer, List<Card>> cardsPerAge = new HashMap<>(); - - public int getNbAges() { - return nbAges; - } - - public void setNbAges(int nbAges) { - this.nbAges = nbAges; - } + private Decks decks; public int getMinPlayers() { return minPlayers; @@ -53,17 +39,11 @@ public class GameData { this.wonders = wonders; } - public List<Card> getCards(int age) { - return cardsPerAge.getOrDefault(age, Collections.emptyList()); - } - - public void setCards(int age, List<Card> cards) { - cardsPerAge.put(age, cards); + public Decks getDecks() { + return decks; } - @Override - public String toString() { - return "GameData{" + "nbAges=" + nbAges + ", minPlayers=" + minPlayers + ", maxPlayers=" + maxPlayers - + ", wonders=" + wonders + ", cardsPerAge=" + cardsPerAge + '}'; + public void setDecks(Decks decks) { + this.decks = decks; } } diff --git a/src/main/java/org/luxons/sevenwonders/game/data/GameDataLoader.java b/src/main/java/org/luxons/sevenwonders/game/data/GameDataLoader.java index 7702a9f6..bd154071 100644 --- a/src/main/java/org/luxons/sevenwonders/game/data/GameDataLoader.java +++ b/src/main/java/org/luxons/sevenwonders/game/data/GameDataLoader.java @@ -4,15 +4,27 @@ import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; +import java.lang.reflect.Type; import java.util.ArrayList; -import java.util.Collections; +import java.util.Comparator; import java.util.List; -import java.util.stream.Collectors; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.cards.Card; +import org.luxons.sevenwonders.game.data.definitions.CardDefinition; +import org.luxons.sevenwonders.game.data.definitions.DecksDefinition; +import org.luxons.sevenwonders.game.data.serializers.NumericEffectSerializer; +import org.luxons.sevenwonders.game.data.serializers.ProductionIncreaseSerializer; +import org.luxons.sevenwonders.game.data.serializers.ResourceTypesSerializer; +import org.luxons.sevenwonders.game.data.serializers.ResourcesSerializer; +import org.luxons.sevenwonders.game.data.serializers.ScienceProgressSerializer; +import org.luxons.sevenwonders.game.effects.GoldIncrease; +import org.luxons.sevenwonders.game.effects.MilitaryReinforcements; +import org.luxons.sevenwonders.game.effects.ProductionIncrease; +import org.luxons.sevenwonders.game.effects.RawPointsIncrease; +import org.luxons.sevenwonders.game.effects.ScienceProgress; import org.luxons.sevenwonders.game.resources.ResourceType; import org.luxons.sevenwonders.game.resources.Resources; import org.luxons.sevenwonders.game.wonders.Wonder; @@ -23,22 +35,18 @@ public class GameDataLoader { private static final String BASE_PACKAGE_PATH = '/' + BASE_PACKAGE.replace('.', '/'); - private static final String wondersFile = "wonders.json"; + private static final String CARDS_FILE = "cards.json"; + + private static final String WONDERS_FILE = "wonders.json"; public static GameData load(Settings settings) { GameData data = new GameData(); - data.setWonders(loadWonders()); - - int nbPlayers = settings.getNbPlayers(); - DecksDefinition defs = loadDecks(); - data.setCards(1, createCards(defs.getAge1(), nbPlayers)); - data.setCards(2, createCards(defs.getAge2(), nbPlayers)); + List<Wonder> wonders = loadWonders(); + data.setWonders(wonders); - List<Card> age3 = createCards(defs.getAge3(), nbPlayers); - List<Card> guild = createGuildCards(defs.getGuild(), nbPlayers); - age3.addAll(guild); - data.setCards(3, age3); + DecksDefinition decksDefinition = loadDecks(); + data.setDecks(new Decks(decksDefinition, settings)); return data; } @@ -55,24 +63,8 @@ public class GameDataLoader { return wonders; } - private static List<Card> createCards(List<CardDefinition> defs, int nbPlayers) { - List<Card> cards = new ArrayList<>(); - for (CardDefinition def : defs) { - for (int i = 0; i < def.getCountPerNbPlayer().get(nbPlayers); i++) { - cards.add(def.createCard()); - } - } - return cards; - } - - private static List<Card> createGuildCards(List<CardDefinition> defs, int nbPlayers) { - List<Card> guild = defs.stream().map(CardDefinition::createCard).collect(Collectors.toList()); - Collections.shuffle(guild); - return guild.subList(0, nbPlayers + 2); - } - private static DecksDefinition loadDecks() { - return readJsonFile("cards.json", DecksDefinition.class); + return readJsonFile(CARDS_FILE, DecksDefinition.class); } private static <T> T readJsonFile(String filename, Class<T> clazz) { @@ -83,10 +75,42 @@ public class GameDataLoader { } private static Gson createGson() { + Type resourceTypeList = new TypeToken<List<ResourceType>>() {}.getType(); return new GsonBuilder().disableHtmlEscaping() - .serializeNulls() .registerTypeAdapter(Resources.class, new ResourcesSerializer()) - .setPrettyPrinting() + .registerTypeAdapter(resourceTypeList, new ResourceTypesSerializer()) + .registerTypeAdapter(ProductionIncrease.class, new ProductionIncreaseSerializer()) + .registerTypeAdapter(MilitaryReinforcements.class, new NumericEffectSerializer()) + .registerTypeAdapter(RawPointsIncrease.class, new NumericEffectSerializer()) + .registerTypeAdapter(GoldIncrease.class, new NumericEffectSerializer()) + .registerTypeAdapter(ScienceProgress.class, new ScienceProgressSerializer()) +// .setPrettyPrinting() .create(); } + + public static void main(String[] args) { + DecksDefinition decksDef = loadDecks(); + Comparator<CardDefinition> comparator = + Comparator.comparing(CardDefinition::getColor).thenComparing(CardDefinition::getName); + List<List<CardDefinition>> decks = new ArrayList<>(); + decks.add(decksDef.getAge1()); + decks.add(decksDef.getAge2()); + decks.add(decksDef.getAge3()); + decks.add(decksDef.getGuildCards()); + + for (List<CardDefinition> deck : decks) { + deck.sort(comparator); + for (CardDefinition cardDefinition : deck) { + cardDefinition.setImage(computeImageName(cardDefinition.getName())); + } + } + Gson gson = createGson(); + + System.out.println(gson.toJson(decksDef)); +// System.out.println(load(5)); + } + + private static String computeImageName(String name) { + return name.toLowerCase().replaceAll("\\s", "") + ".png"; + } } diff --git a/src/main/java/org/luxons/sevenwonders/game/data/CardDefinition.java b/src/main/java/org/luxons/sevenwonders/game/data/definitions/CardDefinition.java index 1254bb55..a23db2fc 100644 --- a/src/main/java/org/luxons/sevenwonders/game/data/CardDefinition.java +++ b/src/main/java/org/luxons/sevenwonders/game/data/definitions/CardDefinition.java @@ -1,19 +1,20 @@ -package org.luxons.sevenwonders.game.data; +package org.luxons.sevenwonders.game.data.definitions; import java.util.List; import java.util.Map; +import org.luxons.sevenwonders.game.Settings; import org.luxons.sevenwonders.game.cards.Card; import org.luxons.sevenwonders.game.cards.Color; import org.luxons.sevenwonders.game.cards.Requirements; -public class CardDefinition { +public class CardDefinition implements Definition<Card> { private String name; private Color color; - private String effect; + private EffectsDefinition effect; private Requirements requirements; @@ -23,14 +24,11 @@ public class CardDefinition { private Map<Integer, Integer> countPerNbPlayer; - public Card createCard() { - return new Card(name, color, requirements, EffectParser.parse(effect)); - } - - private Requirements createRequirements() { - Requirements req = new Requirements(); + private String image; - return req; + @Override + public Card create(Settings settings) { + return new Card(name, color, requirements, effect.create(settings)); } public String getName() { @@ -41,23 +39,15 @@ public class CardDefinition { return color; } - public String getEffect() { - return effect; - } - - public Requirements getRequirements() { - return requirements; - } - - public String getChainParent() { - return chainParent; + public Map<Integer, Integer> getCountPerNbPlayer() { + return countPerNbPlayer; } - public List<String> getChainChildren() { - return chainChildren; + public String getImage() { + return image; } - public Map<Integer, Integer> getCountPerNbPlayer() { - return countPerNbPlayer; + public void setImage(String image) { + this.image = image; } } diff --git a/src/main/java/org/luxons/sevenwonders/game/data/definitions/DecksDefinition.java b/src/main/java/org/luxons/sevenwonders/game/data/definitions/DecksDefinition.java new file mode 100644 index 00000000..bfe89d12 --- /dev/null +++ b/src/main/java/org/luxons/sevenwonders/game/data/definitions/DecksDefinition.java @@ -0,0 +1,38 @@ +package org.luxons.sevenwonders.game.data.definitions; + +import java.util.List; + +import org.luxons.sevenwonders.game.Settings; +import org.luxons.sevenwonders.game.data.Decks; + +public class DecksDefinition implements Definition<Decks> { + + private List<CardDefinition> age1; + + private List<CardDefinition> age2; + + private List<CardDefinition> age3; + + private List<CardDefinition> guildCards; + + public List<CardDefinition> getAge1() { + return age1; + } + + public List<CardDefinition> getAge2() { + return age2; + } + + public List<CardDefinition> getAge3() { + return age3; + } + + public List<CardDefinition> getGuildCards() { + return guildCards; + } + + @Override + public Decks create(Settings settings) { + return new Decks(this, settings); + } +} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/definitions/Definition.java b/src/main/java/org/luxons/sevenwonders/game/data/definitions/Definition.java new file mode 100644 index 00000000..15ecb255 --- /dev/null +++ b/src/main/java/org/luxons/sevenwonders/game/data/definitions/Definition.java @@ -0,0 +1,15 @@ +package org.luxons.sevenwonders.game.data.definitions; + +import org.luxons.sevenwonders.game.Settings; + +/** + * Represents a deserialized JSON definition of some data about the game. It is settings-agnostic. An instance of + * in-game data can be generated from this, given specific game settings. + * + * @param <T> + * the type of in-game object that can be generated from this definition + */ +public interface Definition<T> { + + T create(Settings settings); +} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/definitions/EffectsDefinition.java b/src/main/java/org/luxons/sevenwonders/game/data/definitions/EffectsDefinition.java new file mode 100644 index 00000000..f7fe5573 --- /dev/null +++ b/src/main/java/org/luxons/sevenwonders/game/data/definitions/EffectsDefinition.java @@ -0,0 +1,58 @@ +package org.luxons.sevenwonders.game.data.definitions; + +import java.util.ArrayList; +import java.util.List; + +import org.luxons.sevenwonders.game.Settings; +import org.luxons.sevenwonders.game.effects.BonusPerBoardElement; +import org.luxons.sevenwonders.game.effects.Discount; +import org.luxons.sevenwonders.game.effects.Effect; +import org.luxons.sevenwonders.game.effects.GoldIncrease; +import org.luxons.sevenwonders.game.effects.MilitaryReinforcements; +import org.luxons.sevenwonders.game.effects.ProductionIncrease; +import org.luxons.sevenwonders.game.effects.RawPointsIncrease; +import org.luxons.sevenwonders.game.effects.ScienceProgress; + +public class EffectsDefinition implements Definition<List<Effect>> { + + private GoldIncrease gold; + + private MilitaryReinforcements military; + + private ScienceProgress science; + + private Discount discount; + + private BonusPerBoardElement perBoardElement; + + private ProductionIncrease production; + + private RawPointsIncrease points; + + @Override + public List<Effect> create(Settings settings) { + List<Effect> effects = new ArrayList<>(); + if (gold != null) { + effects.add(gold); + } + if (military != null) { + effects.add(military); + } + if (science != null) { + effects.add(science); + } + if (discount != null) { + effects.add(discount); + } + if (perBoardElement != null) { + effects.add(perBoardElement); + } + if (production != null) { + effects.add(production); + } + if (points != null) { + effects.add(points); + } + return effects; + } +} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/serializers/NumericEffectSerializer.java b/src/main/java/org/luxons/sevenwonders/game/data/serializers/NumericEffectSerializer.java new file mode 100644 index 00000000..e8e5d163 --- /dev/null +++ b/src/main/java/org/luxons/sevenwonders/game/data/serializers/NumericEffectSerializer.java @@ -0,0 +1,45 @@ +package org.luxons.sevenwonders.game.data.serializers; + +import java.lang.reflect.Type; + +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.game.effects.Effect; +import org.luxons.sevenwonders.game.effects.GoldIncrease; +import org.luxons.sevenwonders.game.effects.MilitaryReinforcements; +import org.luxons.sevenwonders.game.effects.RawPointsIncrease; + +public class NumericEffectSerializer implements JsonSerializer<Effect>, JsonDeserializer<Effect> { + + @Override + public JsonElement serialize(Effect effect, Type typeOfSrc, JsonSerializationContext context) { + int value = 0; + if (MilitaryReinforcements.class.equals(typeOfSrc)) { + value = ((MilitaryReinforcements)effect).getCount(); + } else if (GoldIncrease.class.equals(typeOfSrc)) { + value = ((GoldIncrease)effect).getAmount(); + } else if (RawPointsIncrease.class.equals(typeOfSrc)) { + value = ((RawPointsIncrease)effect).getPoints(); + } + return new JsonPrimitive(value); + } + + @Override + public Effect deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws + JsonParseException { + int value = json.getAsInt(); + if (MilitaryReinforcements.class.equals(typeOfT)) { + return new MilitaryReinforcements(value); + } else if (GoldIncrease.class.equals(typeOfT)) { + return new GoldIncrease(value); + } else if (RawPointsIncrease.class.equals(typeOfT)) { + return new RawPointsIncrease(value); + } + throw new IllegalArgumentException("Unknown numeric effet " + typeOfT.getTypeName()); + } +}
\ No newline at end of file diff --git a/src/main/java/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializer.java b/src/main/java/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializer.java new file mode 100644 index 00000000..645958d3 --- /dev/null +++ b/src/main/java/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializer.java @@ -0,0 +1,79 @@ +package org.luxons.sevenwonders.game.data.serializers; + +import java.lang.reflect.Type; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +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 org.luxons.sevenwonders.game.effects.ProductionIncrease; +import org.luxons.sevenwonders.game.resources.Production; +import org.luxons.sevenwonders.game.resources.ResourceType; +import org.luxons.sevenwonders.game.resources.Resources; + +public class ProductionIncreaseSerializer implements JsonSerializer<ProductionIncrease>, + JsonDeserializer<ProductionIncrease> { + + @Override + public JsonElement serialize(ProductionIncrease productionIncrease, Type typeOfSrc, + JsonSerializationContext context) { + Production production = productionIncrease.getProduction(); + Resources fixedResources = production.getFixedResources(); + List<Set<ResourceType>> choices = production.getAlternativeResources(); + if (fixedResources.isEmpty()) { + return serializeAsChoice(choices, context); + } else { + return serializeAsResources(fixedResources, context); + } + } + + private JsonElement serializeAsResources(Resources fixedResources, JsonSerializationContext context) { + return context.serialize(fixedResources); + } + + private JsonElement serializeAsChoice(List<Set<ResourceType>> choices, JsonSerializationContext context) { + if (choices.isEmpty()) { + return JsonNull.INSTANCE; + } + if (choices.size() > 1) { + throw new UnsupportedOperationException("Cannot serialize a production with more than one choice"); + } + String str = choices.get(0).stream() + .map(ResourceType::getSymbol) + .map(Object::toString) + .collect(Collectors.joining("/")); + return new JsonPrimitive(str); + } + + @Override + public ProductionIncrease deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws + JsonParseException { + String s = json.getAsString(); + ProductionIncrease productionIncrease = new ProductionIncrease(); + Production production = new Production(); + if (s.contains("/")) { + production.addChoice(createChoice(s)); + } else { + Resources fixedResources = context.deserialize(json, Resources.class); + production.addAll(fixedResources); + } + productionIncrease.setProduction(production); + return productionIncrease; + } + + private ResourceType[] createChoice(String choiceStr) { + String[] symbols = choiceStr.split("/"); + ResourceType[] choice = new ResourceType[symbols.length]; + for (int i = 0; i < symbols.length; i++) { + choice[i] = ResourceType.fromSymbol(symbols[i].charAt(0)); + } + return choice; + } +} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializer.java b/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializer.java new file mode 100644 index 00000000..8aca5561 --- /dev/null +++ b/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializer.java @@ -0,0 +1,38 @@ +package org.luxons.sevenwonders.game.data.serializers; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +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.game.resources.ResourceType; + +public class ResourceTypesSerializer implements JsonSerializer<List<ResourceType>>, JsonDeserializer<List<ResourceType>> { + + @Override + public JsonElement serialize(List<ResourceType> resources, Type typeOfSrc, JsonSerializationContext context) { + String s = resources.stream() + .map(ResourceType::getSymbol) + .map(Object::toString) + .collect(Collectors.joining()); + return new JsonPrimitive(s); + } + + @Override + public List<ResourceType> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws + JsonParseException { + String s = json.getAsString(); + List<ResourceType> resources = new ArrayList<>(); + for (char c : s.toCharArray()) { + resources.add(ResourceType.fromSymbol(c)); + } + return resources; + } +} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/ResourcesSerializer.java b/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.java index ff4a8ee3..efeafd15 100644 --- a/src/main/java/org/luxons/sevenwonders/game/data/ResourcesSerializer.java +++ b/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.java @@ -1,4 +1,4 @@ -package org.luxons.sevenwonders.game.data; +package org.luxons.sevenwonders.game.data.serializers; import java.lang.reflect.Type; import java.util.stream.Collectors; @@ -7,6 +7,7 @@ import java.util.stream.Stream; 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; @@ -24,7 +25,7 @@ public class ResourcesSerializer implements JsonSerializer<Resources>, JsonDeser .flatMap(e -> Stream.generate(() -> e.getKey().getSymbol()).limit(e.getValue())) .map(Object::toString) .collect(Collectors.joining()); - return new JsonPrimitive(s); + return s.isEmpty() ? JsonNull.INSTANCE : new JsonPrimitive(s); } @Override diff --git a/src/main/java/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializer.java b/src/main/java/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializer.java new file mode 100644 index 00000000..0535b90a --- /dev/null +++ b/src/main/java/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializer.java @@ -0,0 +1,55 @@ +package org.luxons.sevenwonders.game.data.serializers; + +import java.lang.reflect.Type; + +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 org.luxons.sevenwonders.game.boards.Science; +import org.luxons.sevenwonders.game.boards.ScienceType; +import org.luxons.sevenwonders.game.effects.ScienceProgress; + +public class ScienceProgressSerializer implements JsonSerializer<ScienceProgress>, JsonDeserializer<ScienceProgress> { + + @Override + public JsonElement serialize(ScienceProgress scienceProgress, Type typeOfSrc, JsonSerializationContext context) { + Science science = scienceProgress.getScience(); + + if (science.size() > 1) { + throw new UnsupportedOperationException("Cannot serialize science containing more than one element"); + } + + for (ScienceType type : ScienceType.values()) { + int quantity = science.getQuantity(type); + if (quantity == 1) { + return context.serialize(type); + } + } + + if (science.getJokers() == 1) { + return new JsonPrimitive("any"); + } + + return JsonNull.INSTANCE; + } + + @Override + public ScienceProgress deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws + JsonParseException { + String s = json.getAsString(); + ScienceProgress scienceProgress = new ScienceProgress(); + Science science = new Science(); + if ("any".equals(s)) { + science.addJoker(1); + } else { + science.add(context.deserialize(json, ScienceType.class), 1); + } + scienceProgress.setScience(science); + return scienceProgress; + } +} diff --git a/src/main/java/org/luxons/sevenwonders/game/effects/ScienceProgress.java b/src/main/java/org/luxons/sevenwonders/game/effects/ScienceProgress.java index 8feba09d..3eee7a9b 100644 --- a/src/main/java/org/luxons/sevenwonders/game/effects/ScienceProgress.java +++ b/src/main/java/org/luxons/sevenwonders/game/effects/ScienceProgress.java @@ -7,6 +7,10 @@ public class ScienceProgress extends InstantEffect { private Science science; + public Science getScience() { + return science; + } + public void setScience(Science science) { this.science = science; } diff --git a/src/main/java/org/luxons/sevenwonders/game/resources/Production.java b/src/main/java/org/luxons/sevenwonders/game/resources/Production.java index f4d46b59..26f5a58e 100644 --- a/src/main/java/org/luxons/sevenwonders/game/resources/Production.java +++ b/src/main/java/org/luxons/sevenwonders/game/resources/Production.java @@ -32,6 +32,14 @@ public class Production { alternativeResources.addAll(production.alternativeResources); } + public Resources getFixedResources() { + return fixedResources; + } + + public List<Set<ResourceType>> getAlternativeResources() { + return alternativeResources; + } + public boolean contains(Resources resources) { if (fixedResources.contains(resources)) { return true; diff --git a/src/main/resources/org/luxons/sevenwonders/game/data/cards.json b/src/main/resources/org/luxons/sevenwonders/game/data/cards.json index 6eaf4fae..6e4d3918 100644 --- a/src/main/resources/org/luxons/sevenwonders/game/data/cards.json +++ b/src/main/resources/org/luxons/sevenwonders/game/data/cards.json @@ -4,13 +4,11 @@ "name": "Clay Pit", "color": "BROWN", "effect": { - "production": "C/O" + "production": "O/C" }, "requirements": { - "gold": 1, - "resources": "" + "gold": 1 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -28,10 +26,8 @@ "production": "C" }, "requirements": { - "gold": 0, - "resources": "" + "gold": 0 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -49,10 +45,8 @@ "production": "S/C" }, "requirements": { - "gold": 1, - "resources": "" + "gold": 1 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 0, @@ -70,10 +64,8 @@ "production": "W/O" }, "requirements": { - "gold": 1, - "resources": "" + "gold": 1 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 0, @@ -91,10 +83,8 @@ "production": "W" }, "requirements": { - "gold": 0, - "resources": "" + "gold": 0 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -109,13 +99,11 @@ "name": "Mine", "color": "BROWN", "effect": { - "production": "O/S" + "production": "S/O" }, "requirements": { - "gold": 1, - "resources": "" + "gold": 1 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 0, @@ -133,10 +121,8 @@ "production": "O" }, "requirements": { - "gold": 0, - "resources": "" + "gold": 0 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -154,10 +140,8 @@ "production": "S" }, "requirements": { - "gold": 0, - "resources": "" + "gold": 0 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -172,13 +156,11 @@ "name": "Timber Yard", "color": "BROWN", "effect": { - "production": "S/W" + "production": "W/S" }, "requirements": { - "gold": 1, - "resources": "" + "gold": 1 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -196,10 +178,8 @@ "production": "W/C" }, "requirements": { - "gold": 1, - "resources": "" + "gold": 1 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 0, @@ -217,10 +197,8 @@ "production": "G" }, "requirements": { - "gold": 0, - "resources": "" + "gold": 0 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -238,10 +216,8 @@ "production": "L" }, "requirements": { - "gold": 0, - "resources": "" + "gold": 0 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -259,10 +235,8 @@ "production": "P" }, "requirements": { - "gold": 0, - "resources": "" + "gold": 0 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -278,18 +252,16 @@ "color": "YELLOW", "effect": { "discount": { + "resourceTypes": "CSOW", "providers": [ "RIGHT_PLAYER" ], - "resourceTypes": "CSOW", "discountedPrice": 1 } }, "requirements": { - "gold": 0, - "resources": "" + "gold": 0 }, - "chainParent": null, "chainChildren": [ "Forum" ], @@ -307,19 +279,17 @@ "color": "YELLOW", "effect": { "discount": { + "resourceTypes": "LGP", "providers": [ "LEFT_PLAYER", "RIGHT_PLAYER" ], - "resourceTypes": "LGP", "discountedPrice": 1 } }, "requirements": { - "gold": 0, - "resources": "" + "gold": 0 }, - "chainParent": null, "chainChildren": [ "Caravansery" ], @@ -339,10 +309,8 @@ "gold": 5 }, "requirements": { - "gold": 0, - "resources": "" + "gold": 0 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 0, @@ -358,18 +326,16 @@ "color": "YELLOW", "effect": { "discount": { + "resourceTypes": "CSOW", "providers": [ "LEFT_PLAYER" ], - "resourceTypes": "CSOW", "discountedPrice": 1 } }, "requirements": { - "gold": 0, - "resources": "" + "gold": 0 }, - "chainParent": null, "chainChildren": [ "Forum" ], @@ -389,10 +355,8 @@ "points": 2 }, "requirements": { - "gold": 0, - "resources": "" + "gold": 0 }, - "chainParent": null, "chainChildren": [ "Temple" ], @@ -415,7 +379,6 @@ "gold": 0, "resources": "S" }, - "chainParent": null, "chainChildren": [ "Aquaduct" ], @@ -435,10 +398,8 @@ "points": 3 }, "requirements": { - "gold": 0, - "resources": "" + "gold": 0 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 0, @@ -456,10 +417,8 @@ "points": 2 }, "requirements": { - "gold": 0, - "resources": "" + "gold": 0 }, - "chainParent": null, "chainChildren": [ "Statue" ], @@ -482,7 +441,6 @@ "gold": 0, "resources": "L" }, - "chainParent": null, "chainChildren": [ "Stables", "Dispensary" @@ -506,7 +464,6 @@ "gold": 0, "resources": "P" }, - "chainParent": null, "chainChildren": [ "Courthouse", "Library" @@ -530,7 +487,6 @@ "gold": 0, "resources": "G" }, - "chainParent": null, "chainChildren": [ "Archery Range", "Laboratory" @@ -554,7 +510,6 @@ "gold": 0, "resources": "O" }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -575,7 +530,6 @@ "gold": 0, "resources": "C" }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -596,7 +550,6 @@ "gold": 0, "resources": "W" }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -616,10 +569,8 @@ "production": "CC" }, "requirements": { - "gold": 1, - "resources": "" + "gold": 1 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -637,10 +588,8 @@ "production": "OO" }, "requirements": { - "gold": 1, - "resources": "" + "gold": 1 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -658,10 +607,8 @@ "production": "SS" }, "requirements": { - "gold": 1, - "resources": "" + "gold": 1 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -679,10 +626,8 @@ "production": "WW" }, "requirements": { - "gold": 1, - "resources": "" + "gold": 1 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -700,10 +645,8 @@ "production": "G" }, "requirements": { - "gold": 0, - "resources": "" + "gold": 0 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -721,10 +664,8 @@ "production": "L" }, "requirements": { - "gold": 0, - "resources": "" + "gold": 0 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -742,10 +683,8 @@ "production": "P" }, "requirements": { - "gold": 0, - "resources": "" + "gold": 0 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -766,16 +705,17 @@ "LEFT", "RIGHT" ], + "gold": 0, + "points": 2, "type": "CARD", - "colors": ["GREY"], - "points": 2 + "colors": [ + "GREY" + ] } }, "requirements": { - "gold": 0, - "resources": "" + "gold": 0 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 0, @@ -790,7 +730,7 @@ "name": "Caravansery", "color": "YELLOW", "effect": { - "production": "C/S/O/W" + "production": "W/S/O/C" }, "requirements": { "gold": 0, @@ -813,7 +753,7 @@ "name": "Forum", "color": "YELLOW", "effect": { - "production": "L/G/P" + "production": "G/P/L" }, "requirements": { "gold": 0, @@ -842,18 +782,17 @@ "LEFT", "RIGHT" ], + "gold": 0, + "points": 1, "type": "CARD", "colors": [ "BROWN" - ], - "points": 1 + ] } }, "requirements": { - "gold": 0, - "resources": "" + "gold": 0 }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -1034,7 +973,6 @@ "gold": 0, "resources": "WP" }, - "chainParent": null, "chainChildren": [ "Academy", "Study" @@ -1100,7 +1038,6 @@ "gold": 0, "resources": "WOO" }, - "chainParent": null, "chainChildren": [ "Circus" ], @@ -1123,7 +1060,6 @@ "gold": 0, "resources": "SSS" }, - "chainParent": null, "chainChildren": [ "Fortifications" ], @@ -1146,9 +1082,9 @@ "boards": [ "SELF" ], - "type": "WONDER_LEVEL", "gold": 3, - "points": 1 + "points": 1, + "type": "WONDER_LEVEL" } }, "requirements": { @@ -1174,19 +1110,18 @@ "boards": [ "SELF" ], + "gold": 2, + "points": 2, "type": "CARD", "colors": [ "GREY" - ], - "gold": 2, - "points": 2 + ] } }, "requirements": { "gold": 0, "resources": "CCP" }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 0, @@ -1205,12 +1140,12 @@ "boards": [ "SELF" ], + "gold": 1, + "points": 1, "type": "CARD", "colors": [ "BROWN" - ], - "gold": 1, - "points": 1 + ] } }, "requirements": { @@ -1236,12 +1171,12 @@ "boards": [ "SELF" ], + "gold": 1, + "points": 1, "type": "CARD", "colors": [ "GREY" - ], - "gold": 1, - "points": 1 + ] } }, "requirements": { @@ -1290,7 +1225,6 @@ "gold": 0, "resources": "WSOCGPL" }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -1353,7 +1287,6 @@ "gold": 0, "resources": "SSOG" }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -1479,7 +1412,6 @@ "gold": 0, "resources": "WWOL" }, - "chainParent": null, "chainChildren": [], "countPerNbPlayer": { "3": 1, @@ -1565,17 +1497,16 @@ "SELF", "RIGHT" ], - "type": "WONDER_LEVEL", - "points": 1 + "gold": 0, + "points": 1, + "type": "WONDER_LEVEL" } }, "requirements": { "gold": 0, "resources": "SSCCG" }, - "chainParent": null, "chainChildren": [], - "countPerNbPlayer": null, "image": "buildersguild.png" }, { @@ -1587,20 +1518,19 @@ "LEFT", "RIGHT" ], + "gold": 0, + "points": 2, "type": "CARD", "colors": [ "GREY" - ], - "points": 2 + ] } }, "requirements": { "gold": 0, "resources": "SSOO" }, - "chainParent": null, "chainChildren": [], - "countPerNbPlayer": null, "image": "craftsmensguild.png" }, { @@ -1612,20 +1542,19 @@ "LEFT", "RIGHT" ], + "gold": 0, + "points": 1, "type": "CARD", "colors": [ "BLUE" - ], - "points": 1 + ] } }, "requirements": { "gold": 0, "resources": "WWWSL" }, - "chainParent": null, "chainChildren": [], - "countPerNbPlayer": null, "image": "magistratesguild.png" }, { @@ -1637,20 +1566,19 @@ "LEFT", "RIGHT" ], + "gold": 0, + "points": 1, "type": "CARD", "colors": [ "GREEN" - ], - "points": 1 + ] } }, "requirements": { "gold": 0, "resources": "CCCPL" }, - "chainParent": null, "chainChildren": [], - "countPerNbPlayer": null, "image": "philosophersguild.png" }, { @@ -1663,9 +1591,7 @@ "gold": 0, "resources": "WWOOP" }, - "chainParent": null, "chainChildren": [], - "countPerNbPlayer": null, "image": "scientistsguild.png" }, { @@ -1676,22 +1602,21 @@ "boards": [ "SELF" ], + "gold": 0, + "points": 1, "type": "CARD", "colors": [ "BROWN", "GREY", "BLUE" - ], - "points": 1 + ] } }, "requirements": { "gold": 0, "resources": "WWWGP" }, - "chainParent": null, "chainChildren": [], - "countPerNbPlayer": null, "image": "shipownersguild.png" }, { @@ -1703,20 +1628,19 @@ "LEFT", "RIGHT" ], + "gold": 0, + "points": 1, "type": "CARD", "colors": [ "RED" - ], - "points": 1 + ] } }, "requirements": { "gold": 0, "resources": "CCCG" }, - "chainParent": null, "chainChildren": [], - "countPerNbPlayer": null, "image": "spiesguild.png" }, { @@ -1728,17 +1652,16 @@ "LEFT", "RIGHT" ], - "type": "DEFEAT_TOKEN", - "points": 1 + "gold": 0, + "points": 1, + "type": "DEFEAT_TOKEN" } }, "requirements": { "gold": 0, "resources": "SOOL" }, - "chainParent": null, "chainChildren": [], - "countPerNbPlayer": null, "image": "strategistsguild.png" }, { @@ -1750,20 +1673,19 @@ "LEFT", "RIGHT" ], + "gold": 0, + "points": 1, "type": "CARD", "colors": [ "YELLOW" - ], - "points": 1 + ] } }, "requirements": { "gold": 0, "resources": "GPL" }, - "chainParent": null, "chainChildren": [], - "countPerNbPlayer": null, "image": "tradersguild.png" }, { @@ -1775,21 +1697,20 @@ "LEFT", "RIGHT" ], + "gold": 0, + "points": 1, "type": "CARD", "colors": [ "BROWN" - ], - "points": 1 + ] } }, "requirements": { "gold": 0, "resources": "WSOOC" }, - "chainParent": null, "chainChildren": [], - "countPerNbPlayer": null, "image": "workersguild.png" } ] -} +}
\ No newline at end of file |