From 8aa317a8b236896f2a0b2037a99feb6977ac0881 Mon Sep 17 00:00:00 2001 From: Joffrey Bion Date: Thu, 5 Jul 2018 19:11:15 +0200 Subject: Kotlin mig: game definitions --- .../java/org/luxons/sevenwonders/game/Settings.kt | 34 -------- .../sevenwonders/game/data/GameDefinition.java | 59 -------------- .../game/data/GameDefinitionLoader.java | 91 ---------------------- .../luxons/sevenwonders/game/data/GlobalRules.java | 17 ---- .../game/data/definitions/CardDefinition.java | 38 --------- .../game/data/definitions/DecksDefinition.java | 76 ------------------ .../game/data/definitions/Definition.java | 24 ------ .../game/data/definitions/EffectsDefinition.java | 66 ---------------- .../game/data/definitions/WonderDefinition.java | 27 ------- .../game/data/definitions/WonderSide.java | 6 -- .../data/definitions/WonderSideDefinition.java | 31 -------- .../data/definitions/WonderSidePickMethod.java | 36 --------- .../data/definitions/WonderStageDefinition.java | 18 ----- .../data/serializers/NumericEffectSerializer.java | 48 ------------ .../serializers/ProductionIncreaseSerializer.java | 55 ------------- .../data/serializers/ProductionSerializer.java | 78 ------------------- .../data/serializers/ResourceTypeSerializer.java | 31 -------- .../data/serializers/ResourceTypesSerializer.java | 37 --------- .../game/data/serializers/ResourcesSerializer.java | 40 ---------- .../serializers/ScienceProgressSerializer.java | 64 --------------- .../sevenwonders/game/resources/ResourceType.java | 8 ++ .../org/luxons/sevenwonders/game/Settings.kt | 34 ++++++++ .../sevenwonders/game/api/CustomizableSettings.kt | 2 +- .../sevenwonders/game/data/GameDefinition.kt | 30 +++++++ .../sevenwonders/game/data/GameDefinitionLoader.kt | 63 +++++++++++++++ .../luxons/sevenwonders/game/data/GlobalRules.kt | 6 ++ .../luxons/sevenwonders/game/data/WonderSide.kt | 6 ++ .../sevenwonders/game/data/WonderSidePickMethod.kt | 28 +++++++ .../game/data/definitions/CardDefinition.kt | 20 +++++ .../game/data/definitions/DecksDefinition.kt | 53 +++++++++++++ .../game/data/definitions/EffectsDefinition.kt | 53 +++++++++++++ .../game/data/definitions/WonderDefinition.kt | 21 +++++ .../game/data/definitions/WonderSideDefinition.kt | 14 ++++ .../game/data/definitions/WonderStageDefinition.kt | 13 ++++ .../data/serializers/NumericEffectSerializer.kt | 40 ++++++++++ .../serializers/ProductionIncreaseSerializer.kt | 51 ++++++++++++ .../game/data/serializers/ProductionSerializer.kt | 58 ++++++++++++++ .../data/serializers/ResourceTypeSerializer.kt | 29 +++++++ .../data/serializers/ResourceTypesSerializer.kt | 39 ++++++++++ .../game/data/serializers/ResourcesSerializer.kt | 34 ++++++++ .../data/serializers/ScienceProgressSerializer.kt | 57 ++++++++++++++ 41 files changed, 658 insertions(+), 877 deletions(-) delete mode 100644 game-engine/src/main/java/org/luxons/sevenwonders/game/Settings.kt delete mode 100644 game-engine/src/main/java/org/luxons/sevenwonders/game/data/GameDefinition.java delete mode 100644 game-engine/src/main/java/org/luxons/sevenwonders/game/data/GameDefinitionLoader.java delete mode 100644 game-engine/src/main/java/org/luxons/sevenwonders/game/data/GlobalRules.java delete mode 100644 game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/CardDefinition.java delete mode 100644 game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/DecksDefinition.java delete mode 100644 game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/Definition.java delete mode 100644 game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/EffectsDefinition.java delete mode 100644 game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderDefinition.java delete mode 100644 game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSide.java delete mode 100644 game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSideDefinition.java delete mode 100644 game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSidePickMethod.java delete mode 100644 game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderStageDefinition.java delete mode 100644 game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/NumericEffectSerializer.java delete mode 100644 game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializer.java delete mode 100644 game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ProductionSerializer.java delete mode 100644 game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypeSerializer.java delete mode 100644 game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializer.java delete mode 100644 game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.java delete mode 100644 game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializer.java create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/Settings.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/GameDefinition.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/GameDefinitionLoader.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/GlobalRules.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/WonderSide.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/WonderSidePickMethod.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/CardDefinition.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/DecksDefinition.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/EffectsDefinition.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/WonderDefinition.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/WonderSideDefinition.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/WonderStageDefinition.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/NumericEffectSerializer.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializer.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ProductionSerializer.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourceTypeSerializer.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializer.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.kt create mode 100644 game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializer.kt (limited to 'game-engine/src/main') diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/Settings.kt b/game-engine/src/main/java/org/luxons/sevenwonders/game/Settings.kt deleted file mode 100644 index 70dddccf..00000000 --- a/game-engine/src/main/java/org/luxons/sevenwonders/game/Settings.kt +++ /dev/null @@ -1,34 +0,0 @@ -package org.luxons.sevenwonders.game - -import org.luxons.sevenwonders.game.api.CustomizableSettings -import org.luxons.sevenwonders.game.data.definitions.WonderSide -import org.luxons.sevenwonders.game.data.definitions.WonderSidePickMethod -import java.util.Random - -class Settings @JvmOverloads constructor( - val nbPlayers: Int, - customSettings: CustomizableSettings = CustomizableSettings() -) { - val random: Random - val timeLimitInSeconds: Int = customSettings.timeLimitInSeconds - val initialGold: Int = customSettings.initialGold - val discardedCardGold: Int = customSettings.discardedCardGold - val defaultTradingCost: Int = customSettings.defaultTradingCost - val pointsPer3Gold: Int = customSettings.pointsPer3Gold - val lostPointsPerDefeat: Int = customSettings.lostPointsPerDefeat - val wonPointsPerVictoryPerAge: Map = customSettings.wonPointsPerVictoryPerAge - - private val wonderSidePickMethod: WonderSidePickMethod = customSettings.wonderSidePickMethod - private var lastPickedSide: WonderSide? = null - - init { - val seed = customSettings.randomSeedForTests - this.random = if (seed != null) Random(seed) else Random() - } - - fun pickWonderSide(): WonderSide { - val newSide = wonderSidePickMethod.pickSide(random, lastPickedSide) - lastPickedSide = newSide - return newSide - } -} diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/GameDefinition.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/data/GameDefinition.java deleted file mode 100644 index 0402a26d..00000000 --- a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/GameDefinition.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.luxons.sevenwonders.game.data; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.luxons.sevenwonders.game.Game; -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.api.CustomizableSettings; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.cards.Decks; -import org.luxons.sevenwonders.game.data.definitions.DecksDefinition; -import org.luxons.sevenwonders.game.data.definitions.WonderDefinition; -import org.luxons.sevenwonders.game.wonders.Wonder; - -public class GameDefinition { - - private final GlobalRules rules; - - private final WonderDefinition[] wonders; - - private final DecksDefinition decksDefinition; - - GameDefinition(GlobalRules rules, WonderDefinition[] wonders, DecksDefinition decksDefinition) { - this.rules = rules; - this.wonders = wonders; - this.decksDefinition = decksDefinition; - } - - public int getMinPlayers() { - return rules.getMinPlayers(); - } - - public int getMaxPlayers() { - return rules.getMaxPlayers(); - } - - public Game initGame(long id, CustomizableSettings customSettings, int nbPlayers) { - Settings settings = new Settings(nbPlayers, customSettings); - List boards = assignBoards(settings, nbPlayers); - Decks decks = decksDefinition.create(settings); - return new Game(id, settings, nbPlayers, boards, decks); - } - - private List assignBoards(Settings settings, int nbPlayers) { - List randomizedWonders = Arrays.asList(wonders); - Collections.shuffle(randomizedWonders, settings.getRandom()); - - List boards = new ArrayList<>(nbPlayers); - for (int i = 0; i < nbPlayers; i++) { - WonderDefinition def = randomizedWonders.get(i); - Wonder w = def.create(settings); - Board b = new Board(w, i, settings); - boards.add(b); - } - return boards; - } -} diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/GameDefinitionLoader.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/data/GameDefinitionLoader.java deleted file mode 100644 index a1bd7b8d..00000000 --- a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/GameDefinitionLoader.java +++ /dev/null @@ -1,91 +0,0 @@ -package org.luxons.sevenwonders.game.data; - -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.lang.reflect.Type; -import java.util.List; - -import org.luxons.sevenwonders.game.data.definitions.DecksDefinition; -import org.luxons.sevenwonders.game.data.definitions.WonderDefinition; -import org.luxons.sevenwonders.game.data.serializers.NumericEffectSerializer; -import org.luxons.sevenwonders.game.data.serializers.ProductionIncreaseSerializer; -import org.luxons.sevenwonders.game.data.serializers.ProductionSerializer; -import org.luxons.sevenwonders.game.data.serializers.ResourceTypeSerializer; -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.Production; -import org.luxons.sevenwonders.game.resources.ResourceType; -import org.luxons.sevenwonders.game.resources.Resources; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.reflect.TypeToken; - -public class GameDefinitionLoader { - - private static final String BASE_PACKAGE = GameDefinitionLoader.class.getPackage().getName(); - - private static final String BASE_PACKAGE_PATH = '/' + BASE_PACKAGE.replace('.', '/'); - - private static final String GLOBAL_RULES_FILE = "global_rules.json"; - - private static final String CARDS_FILE = "cards.json"; - - private static final String WONDERS_FILE = "wonders.json"; - - private final GameDefinition gameDefinition; - - public GameDefinitionLoader() { - gameDefinition = load(); - } - - public GameDefinition getGameDefinition() { - return gameDefinition; - } - - private static GameDefinition load() { - return new GameDefinition(loadGlobalRules(), loadWonders(), loadDecks()); - } - - private static GlobalRules loadGlobalRules() { - return readJsonFile(GLOBAL_RULES_FILE, GlobalRules.class); - } - - private static WonderDefinition[] loadWonders() { - return readJsonFile(WONDERS_FILE, WonderDefinition[].class); - } - - private static DecksDefinition loadDecks() { - return readJsonFile(CARDS_FILE, DecksDefinition.class); - } - - private static T readJsonFile(String filename, Class clazz) { - InputStream in = GameDefinitionLoader.class.getResourceAsStream(BASE_PACKAGE_PATH + '/' + filename); - Reader reader = new BufferedReader(new InputStreamReader(in)); - Gson gson = createGson(); - return gson.fromJson(reader, clazz); - } - - private static Gson createGson() { - Type resourceTypeList = new TypeToken>() {}.getType(); - return new GsonBuilder().disableHtmlEscaping() - .registerTypeAdapter(Resources.class, new ResourcesSerializer()) - .registerTypeAdapter(ResourceType.class, new ResourceTypeSerializer()) - .registerTypeAdapter(resourceTypeList, new ResourceTypesSerializer()) - .registerTypeAdapter(Production.class, new ProductionSerializer()) - .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()) - .create(); - } -} diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/GlobalRules.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/data/GlobalRules.java deleted file mode 100644 index 526bebad..00000000 --- a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/GlobalRules.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.luxons.sevenwonders.game.data; - -@SuppressWarnings("unused") // fields are set by Gson -class GlobalRules { - - private int minPlayers; - - private int maxPlayers; - - int getMinPlayers() { - return minPlayers; - } - - int getMaxPlayers() { - return maxPlayers; - } -} diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/CardDefinition.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/CardDefinition.java deleted file mode 100644 index 621bed2c..00000000 --- a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/CardDefinition.java +++ /dev/null @@ -1,38 +0,0 @@ -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; - -@SuppressWarnings("unused") // the fields are injected by Gson -public class CardDefinition implements Definition { - - private String name; - - private Color color; - - private Requirements requirements; - - private EffectsDefinition effect; - - private String chainParent; - - private List chainChildren; - - private Map countPerNbPlayer; - - private String image; - - @Override - public Card create(Settings settings) { - return new Card(name, color, requirements, effect.create(settings), chainParent, chainChildren, image); - } - - Map getCountPerNbPlayer() { - return countPerNbPlayer; - } -} diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/DecksDefinition.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/DecksDefinition.java deleted file mode 100644 index 6f97e55f..00000000 --- a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/DecksDefinition.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.luxons.sevenwonders.game.data.definitions; - -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.cards.CardBack; -import org.luxons.sevenwonders.game.cards.Decks; - -@SuppressWarnings("unused,MismatchedQueryAndUpdateOfCollection") // the fields are injected by Gson -public class DecksDefinition implements Definition { - - private List age1; - - private List age2; - - private List age3; - - private String age1Back; - - private String age2Back; - - private String age3Back; - - private List guildCards; - - @Override - public Decks create(Settings settings) { - Map> cardsPerAge = new HashMap<>(); - cardsPerAge.put(1, prepareStandardDeck(age1, settings, age1Back)); - cardsPerAge.put(2, prepareStandardDeck(age2, settings, age2Back)); - cardsPerAge.put(3, prepareAge3Deck(settings)); - return new Decks(cardsPerAge); - } - - private static List prepareStandardDeck(List defs, Settings settings, String backImage) { - CardBack back = new CardBack(backImage); - List cards = createDeck(defs, settings, back); - Collections.shuffle(cards, settings.getRandom()); - return cards; - } - - private List prepareAge3Deck(Settings settings) { - CardBack back = new CardBack(age3Back); - List age3deck = createDeck(age3, settings, back); - age3deck.addAll(createGuildCards(settings, back)); - Collections.shuffle(age3deck, settings.getRandom()); - return age3deck; - } - - private static List createDeck(List defs, Settings settings, CardBack back) { - List cards = new ArrayList<>(); - for (CardDefinition def : defs) { - for (int i = 0; i < def.getCountPerNbPlayer().get(settings.getNbPlayers()); i++) { - Card card = def.create(settings); - card.setBack(back); - cards.add(card); - } - } - return cards; - } - - private List createGuildCards(Settings settings, CardBack back) { - List guild = guildCards.stream() - .map((def) -> def.create(settings)) - .peek(c -> c.setBack(back)) - .collect(Collectors.toList()); - Collections.shuffle(guild, settings.getRandom()); - return guild.subList(0, settings.getNbPlayers() + 2); - } -} diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/Definition.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/Definition.java deleted file mode 100644 index 6c6b4b19..00000000 --- a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/Definition.java +++ /dev/null @@ -1,24 +0,0 @@ -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 - * the type of in-game object that can be generated from this definition - */ -public interface Definition { - - /** - * Creates a T object from the given settings. This method mustn't mutate this Definition as it may be called - * multiple times with different settings. - * - * @param settings - * the game settings to use to generate a game-specific object from this definition - * - * @return the new game-specific object created from this definition - */ - T create(Settings settings); -} diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/EffectsDefinition.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/EffectsDefinition.java deleted file mode 100644 index e35463d4..00000000 --- a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/EffectsDefinition.java +++ /dev/null @@ -1,66 +0,0 @@ -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; -import org.luxons.sevenwonders.game.effects.SpecialAbility; -import org.luxons.sevenwonders.game.effects.SpecialAbilityActivation; - -@SuppressWarnings("unused") // the fields are injected by Gson -public class EffectsDefinition implements Definition> { - - private GoldIncrease gold; - - private MilitaryReinforcements military; - - private ScienceProgress science; - - private Discount discount; - - private BonusPerBoardElement perBoardElement; - - private ProductionIncrease production; - - private RawPointsIncrease points; - - private SpecialAbility action; - - @Override - public List create(Settings settings) { - List 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); - } - if (action != null) { - effects.add(new SpecialAbilityActivation(action)); - } - return effects; - } -} diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderDefinition.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderDefinition.java deleted file mode 100644 index a972a517..00000000 --- a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderDefinition.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.luxons.sevenwonders.game.data.definitions; - -import java.util.Map; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.wonders.Wonder; - -@SuppressWarnings("unused,MismatchedQueryAndUpdateOfCollection") // the fields are injected by Gson -public class WonderDefinition implements Definition { - - private String name; - - private Map sides; - - @Override - public Wonder create(Settings settings) { - Wonder wonder = new Wonder(); - wonder.setName(name); - - WonderSideDefinition wonderSideDef = sides.get(settings.pickWonderSide()); - wonder.setInitialResource(wonderSideDef.getInitialResource()); - wonder.setStages(wonderSideDef.createStages(settings)); - wonder.setImage(wonderSideDef.getImage()); - return wonder; - } - -} diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSide.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSide.java deleted file mode 100644 index 34091350..00000000 --- a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSide.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.luxons.sevenwonders.game.data.definitions; - -public enum WonderSide { - A, - B -} diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSideDefinition.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSideDefinition.java deleted file mode 100644 index c84bba4e..00000000 --- a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSideDefinition.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.luxons.sevenwonders.game.data.definitions; - -import java.util.List; -import java.util.stream.Collectors; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.resources.ResourceType; -import org.luxons.sevenwonders.game.wonders.WonderStage; - -// the fields are injected by Gson -@SuppressWarnings("unused,MismatchedQueryAndUpdateOfCollection") -class WonderSideDefinition { - - private ResourceType initialResource; - - private List stages; - - private String image; - - ResourceType getInitialResource() { - return initialResource; - } - - List createStages(Settings settings) { - return stages.stream().map(def -> def.create(settings)).collect(Collectors.toList()); - } - - String getImage() { - return image; - } -} diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSidePickMethod.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSidePickMethod.java deleted file mode 100644 index 08aaad14..00000000 --- a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSidePickMethod.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.luxons.sevenwonders.game.data.definitions; - -import java.util.Random; - -public enum WonderSidePickMethod { - ALL_A { - @Override - public WonderSide pickSide(Random random, WonderSide lastPickedSide) { - return WonderSide.A; - } - }, - ALL_B { - @Override - public WonderSide pickSide(Random random, WonderSide lastPickedSide) { - return WonderSide.B; - } - }, - EACH_RANDOM { - @Override - public WonderSide pickSide(Random random, WonderSide lastPickedSide) { - return random.nextBoolean() ? WonderSide.A : WonderSide.B; - } - }, - SAME_RANDOM_FOR_ALL { - @Override - public WonderSide pickSide(Random random, WonderSide lastPickedSide) { - if (lastPickedSide == null) { - return random.nextBoolean() ? WonderSide.A : WonderSide.B; - } else { - return lastPickedSide; - } - } - }; - - public abstract WonderSide pickSide(Random random, WonderSide lastPickedSide); -} diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderStageDefinition.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderStageDefinition.java deleted file mode 100644 index 230484ee..00000000 --- a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderStageDefinition.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.luxons.sevenwonders.game.data.definitions; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.cards.Requirements; -import org.luxons.sevenwonders.game.wonders.WonderStage; - -@SuppressWarnings("unused") // the fields are injected by Gson -public class WonderStageDefinition implements Definition { - - private Requirements requirements; - - private EffectsDefinition effects; - - @Override - public WonderStage create(Settings settings) { - return new WonderStage(requirements, effects.create(settings)); - } -} diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/NumericEffectSerializer.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/NumericEffectSerializer.java deleted file mode 100644 index c0a75d80..00000000 --- a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/NumericEffectSerializer.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.luxons.sevenwonders.game.data.serializers; - -import java.lang.reflect.Type; - -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; - -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; - -public class NumericEffectSerializer implements JsonSerializer, JsonDeserializer { - - @Override - public JsonElement serialize(Effect effect, Type typeOfSrc, JsonSerializationContext context) { - int value; - 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(); - } else { - throw new IllegalArgumentException("Unknown numeric effect " + typeOfSrc.getTypeName()); - } - 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()); - } -} diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializer.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializer.java deleted file mode 100644 index c3eb1386..00000000 --- a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializer.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.luxons.sevenwonders.game.data.serializers; - -import java.lang.reflect.Type; - -import org.luxons.sevenwonders.game.effects.ProductionIncrease; -import org.luxons.sevenwonders.game.resources.Production; - -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; - -public class ProductionIncreaseSerializer implements JsonSerializer, - JsonDeserializer { - - @Override - public JsonElement serialize(ProductionIncrease productionIncrease, Type typeOfSrc, - JsonSerializationContext context) { - Production production = productionIncrease.getProduction(); - JsonElement json = context.serialize(production); - if (!json.isJsonNull() && !productionIncrease.isSellable()) { - return new JsonPrimitive(wrapInBrackets(json.getAsString())); - } - return json; - } - - private String wrapInBrackets(String str) { - return '(' + str + ')'; - } - - @Override - public ProductionIncrease deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { - ProductionIncrease productionIncrease = new ProductionIncrease(); - - String resourcesStr = json.getAsString(); - boolean isSellable = !resourcesStr.startsWith("("); - if (!isSellable) { - resourcesStr = unwrapBrackets(resourcesStr); - json = new JsonPrimitive(resourcesStr); - } - productionIncrease.setSellable(isSellable); - - Production production = context.deserialize(json, Production.class); - productionIncrease.setProduction(production); - return productionIncrease; - } - - private static String unwrapBrackets(String str) { - return str.substring(1, str.length() - 1); - } -} diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ProductionSerializer.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ProductionSerializer.java deleted file mode 100644 index 178134bb..00000000 --- a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ProductionSerializer.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.luxons.sevenwonders.game.data.serializers; - -import java.lang.reflect.Type; -import java.util.Set; -import java.util.stream.Collectors; - -import org.luxons.sevenwonders.game.resources.Production; -import org.luxons.sevenwonders.game.resources.ResourceType; -import org.luxons.sevenwonders.game.resources.Resources; - -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; - -public class ProductionSerializer implements JsonSerializer, JsonDeserializer { - - @Override - public JsonElement serialize(Production production, Type typeOfSrc, JsonSerializationContext context) { - Resources fixedResources = production.getFixedResources(); - Set> choices = production.getAlternativeResources(); - if (fixedResources.isEmpty()) { - return serializeAsChoice(choices, context); - } else if (choices.isEmpty()) { - return serializeAsResources(fixedResources, context); - } else { - throw new IllegalArgumentException("Cannot serialize a production with mixed fixed resources and choices"); - } - } - - private static JsonElement serializeAsChoice(Set> choices, JsonSerializationContext context) { - if (choices.isEmpty()) { - return JsonNull.INSTANCE; - } - if (choices.size() > 1) { - throw new IllegalArgumentException("Cannot serialize a production with more than one choice"); - } - String str = choices.stream() - .flatMap(Set::stream) - .map(ResourceType::getSymbol) - .map(Object::toString) - .collect(Collectors.joining("/")); - return context.serialize(str); - } - - private static JsonElement serializeAsResources(Resources fixedResources, JsonSerializationContext context) { - return context.serialize(fixedResources); - } - - @Override - public Production deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { - String resourcesStr = json.getAsString(); - Production production = new Production(); - if (resourcesStr.contains("/")) { - production.addChoice(createChoice(resourcesStr)); - } else { - Resources fixedResources = context.deserialize(json, Resources.class); - production.addAll(fixedResources); - } - return production; - } - - private ResourceType[] createChoice(String choiceStr) { - String[] symbols = choiceStr.split("/"); - ResourceType[] choice = new ResourceType[symbols.length]; - for (int i = 0; i < symbols.length; i++) { - if (symbols[i].length() != 1) { - throw new IllegalArgumentException("Choice elements must be resource types, got " + symbols[i]); - } - choice[i] = ResourceType.fromSymbol(symbols[i].charAt(0)); - } - return choice; - } -} diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypeSerializer.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypeSerializer.java deleted file mode 100644 index d2a49180..00000000 --- a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypeSerializer.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.luxons.sevenwonders.game.data.serializers; - -import java.lang.reflect.Type; - -import org.luxons.sevenwonders.game.resources.ResourceType; - -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; - -public class ResourceTypeSerializer implements JsonSerializer, JsonDeserializer { - - @Override - public JsonElement serialize(ResourceType type, Type typeOfSrc, JsonSerializationContext context) { - return new JsonPrimitive(type.getSymbol()); - } - - @Override - public ResourceType deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { - String str = json.getAsString(); - if (str.isEmpty()) { - throw new IllegalArgumentException("Empty string is not a valid resource type"); - } - return ResourceType.fromSymbol(str.charAt(0)); - } -} diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializer.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializer.java deleted file mode 100644 index 89d3e723..00000000 --- a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializer.java +++ /dev/null @@ -1,37 +0,0 @@ -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 org.luxons.sevenwonders.game.resources.ResourceType; - -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; - -public class ResourceTypesSerializer implements JsonSerializer>, - JsonDeserializer> { - - @Override - public JsonElement serialize(List 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 deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { - String s = json.getAsString(); - List resources = new ArrayList<>(); - for (char c : s.toCharArray()) { - resources.add(ResourceType.fromSymbol(c)); - } - return resources; - } -} diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.java deleted file mode 100644 index 9c27b2a1..00000000 --- a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.luxons.sevenwonders.game.data.serializers; - -import java.lang.reflect.Type; -import java.util.stream.Collectors; - -import org.luxons.sevenwonders.game.resources.ResourceType; -import org.luxons.sevenwonders.game.resources.Resources; - -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; - -public class ResourcesSerializer implements JsonSerializer, JsonDeserializer { - - @Override - public JsonElement serialize(Resources resources, Type typeOfSrc, JsonSerializationContext context) { - String s = resources.asList() - .stream() - .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 { - String s = json.getAsString(); - Resources resources = new Resources(); - for (char c : s.toCharArray()) { - resources.add(ResourceType.fromSymbol(c), 1); - } - return resources; - } -} diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializer.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializer.java deleted file mode 100644 index cecad405..00000000 --- a/game-engine/src/main/java/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializer.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.luxons.sevenwonders.game.data.serializers; - -import java.lang.reflect.Type; - -import org.luxons.sevenwonders.game.boards.Science; -import org.luxons.sevenwonders.game.boards.ScienceType; -import org.luxons.sevenwonders.game.effects.ScienceProgress; - -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; - -public class ScienceProgressSerializer implements JsonSerializer, JsonDeserializer { - - @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(deserializeScienceType(json, context), 1); - } - scienceProgress.setScience(science); - return scienceProgress; - } - - private ScienceType deserializeScienceType(JsonElement json, JsonDeserializationContext context) { - ScienceType type = context.deserialize(json, ScienceType.class); - if (type == null) { - throw new IllegalArgumentException("Invalid science type " + json.getAsString()); - } - return type; - } -} diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/resources/ResourceType.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/resources/ResourceType.java index baad8451..644437df 100644 --- a/game-engine/src/main/java/org/luxons/sevenwonders/game/resources/ResourceType.java +++ b/game-engine/src/main/java/org/luxons/sevenwonders/game/resources/ResourceType.java @@ -26,6 +26,14 @@ public enum ResourceType { this.symbol = symbol; } + public static ResourceType fromSymbol(String symbol) { + if (symbol.length() != 1) { + throw new IllegalArgumentException("The given symbol must be a valid single-char resource type, got " + + symbol); + } + return fromSymbol(symbol.charAt(0)); + } + public static ResourceType fromSymbol(Character symbol) { ResourceType type = typesPerSymbol.get(symbol); if (type == null) { diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/Settings.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/Settings.kt new file mode 100644 index 00000000..fac3979e --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/Settings.kt @@ -0,0 +1,34 @@ +package org.luxons.sevenwonders.game + +import org.luxons.sevenwonders.game.api.CustomizableSettings +import org.luxons.sevenwonders.game.data.WonderSide +import org.luxons.sevenwonders.game.data.WonderSidePickMethod +import java.util.Random + +class Settings @JvmOverloads constructor( + val nbPlayers: Int, + customSettings: CustomizableSettings = CustomizableSettings() +) { + val random: Random + val timeLimitInSeconds: Int = customSettings.timeLimitInSeconds + val initialGold: Int = customSettings.initialGold + val discardedCardGold: Int = customSettings.discardedCardGold + val defaultTradingCost: Int = customSettings.defaultTradingCost + val pointsPer3Gold: Int = customSettings.pointsPer3Gold + val lostPointsPerDefeat: Int = customSettings.lostPointsPerDefeat + val wonPointsPerVictoryPerAge: Map = customSettings.wonPointsPerVictoryPerAge + + private val wonderSidePickMethod: WonderSidePickMethod = customSettings.wonderSidePickMethod + private var lastPickedSide: WonderSide? = null + + init { + val seed = customSettings.randomSeedForTests + this.random = if (seed != null) Random(seed) else Random() + } + + fun pickWonderSide(): WonderSide { + val newSide = wonderSidePickMethod.pickSide(random, lastPickedSide) + lastPickedSide = newSide + return newSide + } +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/api/CustomizableSettings.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/api/CustomizableSettings.kt index 354aecb6..e4efb9e3 100644 --- a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/api/CustomizableSettings.kt +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/api/CustomizableSettings.kt @@ -1,6 +1,6 @@ package org.luxons.sevenwonders.game.api -import org.luxons.sevenwonders.game.data.definitions.WonderSidePickMethod +import org.luxons.sevenwonders.game.data.WonderSidePickMethod data class CustomizableSettings( val randomSeedForTests: Long? = null, diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/GameDefinition.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/GameDefinition.kt new file mode 100644 index 00000000..b7a859eb --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/GameDefinition.kt @@ -0,0 +1,30 @@ +package org.luxons.sevenwonders.game.data + +import org.luxons.sevenwonders.game.Game +import org.luxons.sevenwonders.game.Settings +import org.luxons.sevenwonders.game.api.CustomizableSettings +import org.luxons.sevenwonders.game.boards.Board +import org.luxons.sevenwonders.game.data.definitions.DecksDefinition +import org.luxons.sevenwonders.game.data.definitions.WonderDefinition + +class GameDefinition internal constructor( + rules: GlobalRules, + private val wonders: Array, + private val decksDefinition: DecksDefinition +) { + val minPlayers: Int = rules.minPlayers + val maxPlayers: Int = rules.maxPlayers + + fun initGame(id: Long, customSettings: CustomizableSettings, nbPlayers: Int): Game { + val settings = Settings(nbPlayers, customSettings) + val boards = assignBoards(settings, nbPlayers) + val decks = decksDefinition.prepareDecks(settings) + return Game(id, settings, nbPlayers, boards, decks) + } + + private fun assignBoards(settings: Settings, nbPlayers: Int): List { + val randomizedWonders = wonders.toMutableList() + randomizedWonders.shuffle(settings.random) + return randomizedWonders.take(nbPlayers).mapIndexed { i, wDef -> Board(wDef.create(settings), i, settings) } + } +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/GameDefinitionLoader.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/GameDefinitionLoader.kt new file mode 100644 index 00000000..22ecc488 --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/GameDefinitionLoader.kt @@ -0,0 +1,63 @@ +package org.luxons.sevenwonders.game.data + +import com.github.salomonbrys.kotson.registerTypeAdapter +import com.github.salomonbrys.kotson.typeToken +import com.google.gson.Gson +import com.google.gson.GsonBuilder +import com.google.gson.JsonNull +import com.google.gson.JsonPrimitive +import org.luxons.sevenwonders.game.data.definitions.DecksDefinition +import org.luxons.sevenwonders.game.data.definitions.WonderDefinition +import org.luxons.sevenwonders.game.data.serializers.NumericEffectSerializer +import org.luxons.sevenwonders.game.data.serializers.ProductionIncreaseSerializer +import org.luxons.sevenwonders.game.data.serializers.ProductionSerializer +import org.luxons.sevenwonders.game.data.serializers.ResourceTypeSerializer +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.Production +import org.luxons.sevenwonders.game.resources.ResourceType +import org.luxons.sevenwonders.game.resources.Resources + +class GameDefinitionLoader { + + val gameDefinition: GameDefinition by lazy { load() } + + private fun load(): GameDefinition { + val gson: Gson = createGson() + val rules = loadJson("global_rules.json", GlobalRules::class.java, gson) + val wonders = loadJson("wonders.json", Array::class.java, gson) + val decksDefinition = loadJson("cards.json", DecksDefinition::class.java, gson) + return GameDefinition(rules, wonders, decksDefinition) + } + + private fun loadJson(filename: String, clazz: Class, gson: Gson): T { + val packageAsPath = GameDefinitionLoader::class.java.`package`.name.replace('.', '/') + val resourcePath = "/$packageAsPath/$filename" + val resource = GameDefinitionLoader::class.java.getResource(resourcePath) + val json = resource.readText() + return gson.fromJson(json, clazz) + } + + private fun createGson(): Gson { + return GsonBuilder().disableHtmlEscaping() + .registerTypeAdapter(ResourcesSerializer()) + .registerTypeAdapter(ResourceTypeSerializer()) + .registerTypeAdapter>(ResourceTypesSerializer()) + .registerTypeAdapter(ProductionSerializer()) + .registerTypeAdapter(ProductionIncreaseSerializer()) + .registerTypeAdapter(NumericEffectSerializer()) + .registerTypeAdapter(NumericEffectSerializer()) + .registerTypeAdapter(NumericEffectSerializer()) + .registerTypeAdapter(ScienceProgressSerializer()) + .create() + } + + private inline fun GsonBuilder.registerTypeAdapter(typeAdapter: Any): GsonBuilder + = this.registerTypeAdapter(typeToken(), typeAdapter) +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/GlobalRules.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/GlobalRules.kt new file mode 100644 index 00000000..f472cc2a --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/GlobalRules.kt @@ -0,0 +1,6 @@ +package org.luxons.sevenwonders.game.data + +internal data class GlobalRules( + val minPlayers: Int, + val maxPlayers: Int +) diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/WonderSide.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/WonderSide.kt new file mode 100644 index 00000000..4a818fc4 --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/WonderSide.kt @@ -0,0 +1,6 @@ +package org.luxons.sevenwonders.game.data + +enum class WonderSide { + A, + B +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/WonderSidePickMethod.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/WonderSidePickMethod.kt new file mode 100644 index 00000000..29fe2126 --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/WonderSidePickMethod.kt @@ -0,0 +1,28 @@ +package org.luxons.sevenwonders.game.data + +import java.util.Random + +enum class WonderSidePickMethod { + ALL_A { + override fun pickSide(random: Random, lastPickedSide: WonderSide?): WonderSide { + return WonderSide.A + } + }, + ALL_B { + override fun pickSide(random: Random, lastPickedSide: WonderSide?): WonderSide { + return WonderSide.B + } + }, + EACH_RANDOM { + override fun pickSide(random: Random, lastPickedSide: WonderSide?): WonderSide { + return if (random.nextBoolean()) WonderSide.A else WonderSide.B + } + }, + SAME_RANDOM_FOR_ALL { + override fun pickSide(random: Random, lastPickedSide: WonderSide?): WonderSide { + return lastPickedSide ?: if (random.nextBoolean()) WonderSide.A else WonderSide.B + } + }; + + abstract fun pickSide(random: Random, lastPickedSide: WonderSide?): WonderSide +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/CardDefinition.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/CardDefinition.kt new file mode 100644 index 00000000..2827564b --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/CardDefinition.kt @@ -0,0 +1,20 @@ +package org.luxons.sevenwonders.game.data.definitions + +import org.luxons.sevenwonders.game.cards.Card +import org.luxons.sevenwonders.game.cards.Color +import org.luxons.sevenwonders.game.cards.Requirements + +internal class CardDefinition( + private val name: String, + private val color: Color, + private val requirements: Requirements? = null, + private val effect: EffectsDefinition, + private val chainParent: String? = null, + private val chainChildren: List = emptyList(), + private val image: String? = null, + private val countPerNbPlayer: Map +) { + fun create(nbPlayers: Int): List = List( countPerNbPlayer[nbPlayers]!!) { create() } + + fun create(): Card = Card(name, color, requirements, effect.create(), chainParent, chainChildren, image) +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/DecksDefinition.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/DecksDefinition.kt new file mode 100644 index 00000000..a09f0642 --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/DecksDefinition.kt @@ -0,0 +1,53 @@ +package org.luxons.sevenwonders.game.data.definitions + +import org.luxons.sevenwonders.game.Settings +import org.luxons.sevenwonders.game.cards.Card +import org.luxons.sevenwonders.game.cards.CardBack +import org.luxons.sevenwonders.game.cards.Decks + +internal class DecksDefinition( + private val age1: List, + private val age2: List, + private val age3: List, + private val age1Back: String, + private val age2Back: String, + private val age3Back: String, + private val guildCards: List +) { + fun prepareDecks(settings: Settings): Decks { + val cardsPerAge = mapOf( + 1 to prepareStandardDeck(age1, settings, age1Back), + 2 to prepareStandardDeck(age2, settings, age2Back), + 3 to prepareAge3Deck(settings) + ) + return Decks(cardsPerAge) + } + + private fun prepareStandardDeck(defs: List, settings: Settings, backImage: String): List { + val back = CardBack(backImage) + val cards = createDeck(defs, settings, back).toMutableList() + cards.shuffle(settings.random) + return cards + } + + private fun prepareAge3Deck(settings: Settings): List { + val back = CardBack(age3Back) + val age3deck = createDeck(age3, settings, back).toMutableList() + age3deck.addAll(createGuildCards(settings, back)) + age3deck.shuffle(settings.random) + return age3deck + } + + private fun createDeck(defs: List, settings: Settings, back: CardBack): List { + return defs.flatMap { it.create(settings.nbPlayers) }.onEach { it.back = back } + } + + private fun createGuildCards(settings: Settings, back: CardBack): List { + val guild = guildCards + .map { it.create() } + .map { c -> c.back = back; c } + .toMutableList() + guild.shuffle(settings.random) + return guild.subList(0, settings.nbPlayers + 2) + } +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/EffectsDefinition.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/EffectsDefinition.kt new file mode 100644 index 00000000..978ec4a6 --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/EffectsDefinition.kt @@ -0,0 +1,53 @@ +package org.luxons.sevenwonders.game.data.definitions + +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 +import org.luxons.sevenwonders.game.effects.SpecialAbility +import org.luxons.sevenwonders.game.effects.SpecialAbilityActivation +import java.util.ArrayList + +internal data class EffectsDefinition( + private val gold: GoldIncrease? = null, + private val military: MilitaryReinforcements? = 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 action: SpecialAbility? = null +) { + fun create(): List { + val effects = 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) + } + if (action != null) { + effects.add(SpecialAbilityActivation(action)) + } + return effects + } +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/WonderDefinition.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/WonderDefinition.kt new file mode 100644 index 00000000..558f16e8 --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/WonderDefinition.kt @@ -0,0 +1,21 @@ +package org.luxons.sevenwonders.game.data.definitions + +import org.luxons.sevenwonders.game.Settings +import org.luxons.sevenwonders.game.data.WonderSide +import org.luxons.sevenwonders.game.wonders.Wonder + +internal data class WonderDefinition( + private val name: String, + private val sides: Map +) { + fun create(settings: Settings): Wonder { + val wonder = Wonder() + wonder.name = name + + val wonderSideDef = sides[settings.pickWonderSide()]!! + wonder.initialResource = wonderSideDef.initialResource + wonder.stages = wonderSideDef.createStages() + wonder.image = wonderSideDef.image + return wonder + } +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/WonderSideDefinition.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/WonderSideDefinition.kt new file mode 100644 index 00000000..247432e3 --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/WonderSideDefinition.kt @@ -0,0 +1,14 @@ +package org.luxons.sevenwonders.game.data.definitions + +import org.luxons.sevenwonders.game.resources.ResourceType +import org.luxons.sevenwonders.game.wonders.WonderStage + +internal class WonderSideDefinition( + val initialResource: ResourceType, + private val stages: List, + val image: String +) { + fun createStages(): List { + return stages.map { def -> def.create() } + } +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/WonderStageDefinition.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/WonderStageDefinition.kt new file mode 100644 index 00000000..3d2872d0 --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/definitions/WonderStageDefinition.kt @@ -0,0 +1,13 @@ +package org.luxons.sevenwonders.game.data.definitions + +import org.luxons.sevenwonders.game.cards.Requirements +import org.luxons.sevenwonders.game.wonders.WonderStage + +internal class WonderStageDefinition( + private val requirements: Requirements, + private val effects: EffectsDefinition +) { + fun create(): WonderStage { + return WonderStage(requirements, effects.create()) + } +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/NumericEffectSerializer.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/NumericEffectSerializer.kt new file mode 100644 index 00000000..510a511c --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/NumericEffectSerializer.kt @@ -0,0 +1,40 @@ +package org.luxons.sevenwonders.game.data.serializers + +import java.lang.reflect.Type + +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 + +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 + +class NumericEffectSerializer : JsonSerializer, JsonDeserializer { + + 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/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializer.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializer.kt new file mode 100644 index 00000000..578f816b --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializer.kt @@ -0,0 +1,51 @@ +package org.luxons.sevenwonders.game.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.game.effects.ProductionIncrease +import org.luxons.sevenwonders.game.resources.Production +import java.lang.reflect.Type + +class ProductionIncreaseSerializer : JsonSerializer, JsonDeserializer { + + 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 json = json + val productionIncrease = ProductionIncrease() + + var resourcesStr = json.asString + val isSellable = !resourcesStr.startsWith("(") + if (!isSellable) { + resourcesStr = unwrapBrackets(resourcesStr) + json = JsonPrimitive(resourcesStr) + } + productionIncrease.isSellable = isSellable + + val production = context.deserialize(json, Production::class.java) + productionIncrease.production = production + return productionIncrease + } + + private fun unwrapBrackets(str: String): String { + return str.substring(1, str.length - 1) + } +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ProductionSerializer.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ProductionSerializer.kt new file mode 100644 index 00000000..538fdbb4 --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ProductionSerializer.kt @@ -0,0 +1,58 @@ +package org.luxons.sevenwonders.game.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 org.luxons.sevenwonders.game.resources.Production +import org.luxons.sevenwonders.game.resources.ResourceType +import org.luxons.sevenwonders.game.resources.Resources +import java.lang.reflect.Type + +class ProductionSerializer : JsonSerializer, JsonDeserializer { + + override fun serialize(production: Production, typeOfSrc: Type, context: JsonSerializationContext): JsonElement { + val fixedResources = production.fixedResources + val choices = production.alternativeResources + return when { + fixedResources.isEmpty -> serializeAsChoice(choices, context) + choices.isEmpty() -> serializeAsResources(fixedResources, context) + else -> throw IllegalArgumentException("Cannot serialize a production with mixed fixed resources and choices") + } + } + + private fun serializeAsChoice(choices: Set>, 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.flatMap { it }.map { it.symbol }.joinToString("/") + return context.serialize(str) + } + + private fun serializeAsResources(fixedResources: Resources, context: JsonSerializationContext): JsonElement { + return context.serialize(fixedResources) + } + + @Throws(JsonParseException::class) + override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Production { + val resourcesStr = json.asString + val production = Production() + if (resourcesStr.contains("/")) { + production.addChoice(*createChoice(resourcesStr)) + } else { + val fixedResources = context.deserialize(json, Resources::class.java) + production.addAll(fixedResources) + } + return production + } + + private fun createChoice(choiceStr: String): Array { + return choiceStr.split("/").map { ResourceType.fromSymbol(it) }.toTypedArray() + } +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourceTypeSerializer.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourceTypeSerializer.kt new file mode 100644 index 00000000..1de9334a --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourceTypeSerializer.kt @@ -0,0 +1,29 @@ +package org.luxons.sevenwonders.game.data.serializers + +import java.lang.reflect.Type + +import org.luxons.sevenwonders.game.resources.ResourceType + +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 + +internal class ResourceTypeSerializer : JsonSerializer, JsonDeserializer { + + override fun serialize(type: ResourceType, typeOfSrc: Type, context: JsonSerializationContext): JsonElement { + return JsonPrimitive(type.symbol!!) + } + + @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 type") + } + return ResourceType.fromSymbol(str[0]) + } +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializer.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializer.kt new file mode 100644 index 00000000..9ba21043 --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializer.kt @@ -0,0 +1,39 @@ +package org.luxons.sevenwonders.game.data.serializers + +import java.lang.reflect.Type + +import org.luxons.sevenwonders.game.resources.ResourceType + +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 + +internal class ResourceTypesSerializer : JsonSerializer>, JsonDeserializer> { + + override fun serialize( + resources: List, + typeOfSrc: Type, + context: JsonSerializationContext + ): JsonElement { + val s = resources.map { it.symbol }.joinToString("") + return JsonPrimitive(s) + } + + @Throws(JsonParseException::class) + override fun deserialize( + json: JsonElement, + typeOfT: Type, + context: JsonDeserializationContext + ): List { + val s = json.asString + val resources = ArrayList() + for (c in s.toCharArray()) { + resources.add(ResourceType.fromSymbol(c)) + } + return resources + } +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.kt new file mode 100644 index 00000000..2baf7a35 --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.kt @@ -0,0 +1,34 @@ +package org.luxons.sevenwonders.game.data.serializers + +import java.lang.reflect.Type +import java.util.stream.Collectors + +import org.luxons.sevenwonders.game.resources.ResourceType +import org.luxons.sevenwonders.game.resources.Resources + +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 + +internal class ResourcesSerializer : JsonSerializer, JsonDeserializer { + + override fun serialize(resources: Resources, typeOfSrc: Type, context: JsonSerializationContext): JsonElement { + val s = resources.asList().map { it.symbol }.joinToString("") + return if (s.isEmpty()) JsonNull.INSTANCE else JsonPrimitive(s) + } + + @Throws(JsonParseException::class) + override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Resources { + val s = json.asString + val resources = Resources() + for (c in s.toCharArray()) { + resources.add(ResourceType.fromSymbol(c), 1) + } + return resources + } +} diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializer.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializer.kt new file mode 100644 index 00000000..ed383d63 --- /dev/null +++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializer.kt @@ -0,0 +1,57 @@ +package org.luxons.sevenwonders.game.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 org.luxons.sevenwonders.game.boards.Science +import org.luxons.sevenwonders.game.boards.ScienceType +import org.luxons.sevenwonders.game.effects.ScienceProgress +import java.lang.reflect.Type + +internal class ScienceProgressSerializer : JsonSerializer, JsonDeserializer { + + override fun serialize( + scienceProgress: ScienceProgress, + typeOfSrc: Type, + context: JsonSerializationContext + ): JsonElement { + val science = scienceProgress.science + + if (science.size() > 1) { + throw UnsupportedOperationException("Cannot serialize science containing more than one element") + } + + for (type in ScienceType.values()) { + val quantity = science.getQuantity(type) + if (quantity == 1) { + return context.serialize(type) + } + } + + return if (science.jokers == 1) JsonPrimitive("any") else JsonNull.INSTANCE + } + + @Throws(JsonParseException::class) + override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): ScienceProgress { + val s = json.asString + val scienceProgress = ScienceProgress() + val science = Science() + if ("any" == s) { + science.addJoker(1) + } else { + science.add(deserializeScienceType(json, context), 1) + } + scienceProgress.science = science + return scienceProgress + } + + private fun deserializeScienceType(json: JsonElement, context: JsonDeserializationContext): ScienceType { + return context.deserialize(json, ScienceType::class.java) + ?: throw IllegalArgumentException("Invalid science type " + json.asString) + } +} -- cgit