diff options
author | Joffrey BION <joffrey.bion@gmail.com> | 2018-04-23 21:05:36 +0200 |
---|---|---|
committer | Joffrey BION <joffrey.bion@gmail.com> | 2018-04-23 21:07:15 +0200 |
commit | 8702554846fe3791d4c877fbfe8e868b37fe39af (patch) | |
tree | 181a5de598248b914b79685084e73e161b3b26e9 /backend/src/main | |
parent | Upgrade frontend build tools version (diff) | |
download | seven-wonders-8702554846fe3791d4c877fbfe8e868b37fe39af.tar.gz seven-wonders-8702554846fe3791d4c877fbfe8e868b37fe39af.tar.bz2 seven-wonders-8702554846fe3791d4c877fbfe8e868b37fe39af.zip |
Extract game engine as separate artifact
Diffstat (limited to 'backend/src/main')
75 files changed, 2 insertions, 6034 deletions
diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/Game.java b/backend/src/main/java/org/luxons/sevenwonders/game/Game.java deleted file mode 100644 index ed11913b..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/Game.java +++ /dev/null @@ -1,232 +0,0 @@ -package org.luxons.sevenwonders.game; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.luxons.sevenwonders.game.api.Action; -import org.luxons.sevenwonders.game.api.HandCard; -import org.luxons.sevenwonders.game.api.PlayerMove; -import org.luxons.sevenwonders.game.api.PlayerTurnInfo; -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.cards.Card; -import org.luxons.sevenwonders.game.cards.CardBack; -import org.luxons.sevenwonders.game.cards.Decks; -import org.luxons.sevenwonders.game.cards.Hands; -import org.luxons.sevenwonders.game.effects.SpecialAbility; -import org.luxons.sevenwonders.game.moves.InvalidMoveException; -import org.luxons.sevenwonders.game.moves.Move; -import org.luxons.sevenwonders.game.scoring.ScoreBoard; - -public class Game { - - private static final int LAST_AGE = 3; - - private final long id; - - private final Settings settings; - - private final int nbPlayers; - - private final Table table; - - private final Decks decks; - - private final List<Card> discardedCards; - - private final Map<Integer, Move> preparedMoves; - - private Map<Integer, PlayerTurnInfo> currentTurnInfo; - - private Hands hands; - - public Game(long id, Settings settings, int nbPlayers, List<Board> boards, Decks decks) { - this.id = id; - this.settings = settings; - this.nbPlayers = nbPlayers; - this.table = new Table(boards); - this.decks = decks; - this.discardedCards = new ArrayList<>(); - this.currentTurnInfo = new HashMap<>(); - this.preparedMoves = new HashMap<>(); - startNewAge(); - } - - public long getId() { - return id; - } - - public Settings getSettings() { - return settings; - } - - private void startNewAge() { - table.increaseCurrentAge(); - hands = decks.deal(table.getCurrentAge(), table.getNbPlayers()); - startNewTurn(); - } - - private void startNewTurn() { - currentTurnInfo.clear(); - for (int i = 0; i < nbPlayers; i++) { - currentTurnInfo.put(i, createPlayerTurnInfo(i)); - } - } - - private PlayerTurnInfo createPlayerTurnInfo(int playerIndex) { - PlayerTurnInfo pti = new PlayerTurnInfo(playerIndex, table); - List<HandCard> hand = hands.createHand(table, playerIndex); - pti.setHand(hand); - Action action = determineAction(hand, table.getBoard(playerIndex)); - pti.setAction(action); - pti.setMessage(action.getMessage()); - if (action == Action.PICK_NEIGHBOR_GUILD) { - pti.setNeighbourGuildCards(table.getNeighbourGuildCards(playerIndex)); - } - return pti; - } - - public Collection<PlayerTurnInfo> getCurrentTurnInfo() { - return currentTurnInfo.values(); - } - - private Action determineAction(List<HandCard> hand, Board board) { - if (endOfGameReached() && board.hasSpecial(SpecialAbility.COPY_GUILD)) { - return Action.PICK_NEIGHBOR_GUILD; - } else if (hand.size() == 1 && board.hasSpecial(SpecialAbility.PLAY_LAST_CARD)) { - return Action.PLAY_LAST; - } else if (hand.size() == 2 && board.hasSpecial(SpecialAbility.PLAY_LAST_CARD)) { - return Action.PLAY_2; - } else if (hand.isEmpty()) { - return Action.WAIT; - } else { - return Action.PLAY; - } - } - - public CardBack prepareMove(int playerIndex, PlayerMove playerMove) throws InvalidMoveException { - Card card = decks.getCard(playerMove.getCardName()); - Move move = playerMove.getType().resolve(playerIndex, card, playerMove); - validate(move); - preparedMoves.put(playerIndex, move); - return card.getBack(); - } - - private void validate(Move move) throws InvalidMoveException { - List<Card> hand = hands.get(move.getPlayerIndex()); - move.validate(table, hand); - } - - public boolean allPlayersPreparedTheirMove() { - long nbExpectedMoves = currentTurnInfo.values().stream().filter(pti -> pti.getAction() != Action.WAIT).count(); - return preparedMoves.size() == nbExpectedMoves; - } - - public Table playTurn() { - makeMoves(); - if (endOfAgeReached()) { - executeEndOfAgeEvents(); - if (!endOfGameReached()) { - startNewAge(); - } - } else { - rotateHandsIfRelevant(); - startNewTurn(); - } - return table; - } - - private void rotateHandsIfRelevant() { - // we don't rotate hands if some player can play his last card (with the special ability) - if (!hands.maxOneCardRemains()) { - hands.rotate(table.getHandRotationDirection()); - } - } - - private void makeMoves() { - List<Move> playedMoves = mapToList(preparedMoves); - - // all cards from this turn need to be placed before executing any effect - // because effects depending on played cards need to take the ones from the current turn into account too - placePreparedCards(playedMoves); - - // same goes for the discarded cards during the last turn, which should be available for special actions - if (hands.maxOneCardRemains()) { - discardLastCardsOfHands(); - } - - activatePlayedCards(playedMoves); - - table.setLastPlayedMoves(playedMoves); - preparedMoves.clear(); - } - - private static List<Move> mapToList(Map<Integer, Move> movesPerPlayer) { - List<Move> moves = new ArrayList<>(movesPerPlayer.size()); - for (int p = 0; p < movesPerPlayer.size(); p++) { - Move move = movesPerPlayer.get(p); - if (move == null) { - throw new MissingPreparedMoveException(p); - } - moves.add(move); - } - return moves; - } - - private void placePreparedCards(List<Move> playedMoves) { - playedMoves.forEach(move -> { - move.place(table, discardedCards, settings); - removeFromHand(move.getPlayerIndex(), move.getCard()); - }); - } - - private void discardLastCardsOfHands() { - for (int i = 0; i < nbPlayers; i++) { - Board board = table.getBoard(i); - if (!board.hasSpecial(SpecialAbility.PLAY_LAST_CARD)) { - discardHand(i); - } - } - } - - private void discardHand(int playerIndex) { - List<Card> hand = hands.get(playerIndex); - discardedCards.addAll(hand); - hand.clear(); - } - - private void removeFromHand(int playerIndex, Card card) { - hands.get(playerIndex).remove(card); - } - - private void activatePlayedCards(List<Move> playedMoves) { - playedMoves.forEach(move -> move.activate(table, discardedCards, settings)); - } - - private boolean endOfAgeReached() { - return hands.isEmpty(); - } - - private void executeEndOfAgeEvents() { - table.resolveMilitaryConflicts(); - } - - private boolean endOfGameReached() { - return endOfAgeReached() && table.getCurrentAge() == LAST_AGE; - } - - public ScoreBoard computeScore() { - ScoreBoard scoreBoard = new ScoreBoard(); - table.getBoards().stream().map(b -> b.computePoints(table)).forEach(scoreBoard::add); - return scoreBoard; - } - - private static class MissingPreparedMoveException extends IllegalStateException { - MissingPreparedMoveException(int playerIndex) { - super("Player " + playerIndex + " is not ready to play"); - } - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/Settings.java b/backend/src/main/java/org/luxons/sevenwonders/game/Settings.java deleted file mode 100644 index f05b0b01..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/Settings.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.luxons.sevenwonders.game; - -import java.util.Map; -import java.util.Random; - -import org.luxons.sevenwonders.game.api.CustomizableSettings; -import org.luxons.sevenwonders.game.data.definitions.WonderSide; -import org.luxons.sevenwonders.game.data.definitions.WonderSidePickMethod; - -public class Settings { - - private final Random random; - - private final int timeLimitInSeconds; - - private final int nbPlayers; - - private final int initialGold; - - private final int discardedCardGold; - - private final int defaultTradingCost; - - private final int pointsPer3Gold; - - private final WonderSidePickMethod wonderSidePickMethod; - - private WonderSide lastPickedSide = null; - - private final int lostPointsPerDefeat; - - private final Map<Integer, Integer> wonPointsPerVictoryPerAge; - - public Settings(int nbPlayers) { - this(nbPlayers, new CustomizableSettings()); - } - - public Settings(int nbPlayers, CustomizableSettings customSettings) { - long seed = customSettings.getRandomSeedForTests(); - this.random = seed > 0 ? new Random(seed) : new Random(); - this.timeLimitInSeconds = customSettings.getTimeLimitInSeconds(); - this.nbPlayers = nbPlayers; - this.initialGold = customSettings.getInitialGold(); - this.discardedCardGold = customSettings.getDiscardedCardGold(); - this.defaultTradingCost = customSettings.getDefaultTradingCost(); - this.pointsPer3Gold = customSettings.getPointsPer3Gold(); - this.wonderSidePickMethod = customSettings.getWonderSidePickMethod(); - this.lostPointsPerDefeat = customSettings.getLostPointsPerDefeat(); - this.wonPointsPerVictoryPerAge = customSettings.getWonPointsPerVictoryPerAge(); - } - - public Random getRandom() { - return random; - } - - public int getTimeLimitInSeconds() { - return timeLimitInSeconds; - } - - public int getNbPlayers() { - return nbPlayers; - } - - public int getInitialGold() { - return initialGold; - } - - public int getDiscardedCardGold() { - return discardedCardGold; - } - - public int getDefaultTradingCost() { - return defaultTradingCost; - } - - public int getPointsPer3Gold() { - return pointsPer3Gold; - } - - public WonderSide pickWonderSide() { - WonderSide newSide = wonderSidePickMethod.pickSide(getRandom(), lastPickedSide); - lastPickedSide = newSide; - return newSide; - } - - public int getLostPointsPerDefeat() { - return lostPointsPerDefeat; - } - - public Map<Integer, Integer> getWonPointsPerVictoryPerAge() { - return wonPointsPerVictoryPerAge; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/api/Action.java b/backend/src/main/java/org/luxons/sevenwonders/game/api/Action.java deleted file mode 100644 index 88e392f9..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/api/Action.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.luxons.sevenwonders.game.api; - -public enum Action { - PLAY("Pick the card you want to play or discard."), - PLAY_2("Pick the first card you want to play or discard. Note that you have the ability to play these 2 last cards." - + " You will choose how to play the last one during your next turn."), - PLAY_LAST("You have the special ability to play your last card. Choose how you want to play it."), - PICK_NEIGHBOR_GUILD("Choose a Guild card (purple) that you want to copy from one of your neighbours."), - WAIT("Please wait for other players to perform extra actions."); - - private final String message; - - Action(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/api/CustomizableSettings.java b/backend/src/main/java/org/luxons/sevenwonders/game/api/CustomizableSettings.java deleted file mode 100644 index 2cbf8727..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/api/CustomizableSettings.java +++ /dev/null @@ -1,128 +0,0 @@ -package org.luxons.sevenwonders.game.api; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -import org.luxons.sevenwonders.game.data.definitions.WonderSidePickMethod; - -public class CustomizableSettings { - - private long randomSeedForTests = -1; - - private int timeLimitInSeconds = 45; - - private WonderSidePickMethod wonderSidePickMethod = WonderSidePickMethod.EACH_RANDOM; - - private int initialGold = 3; - - private int discardedCardGold = 3; - - private int defaultTradingCost = 2; - - private int pointsPer3Gold = 1; - - private int lostPointsPerDefeat = 1; - - private Map<Integer, Integer> wonPointsPerVictoryPerAge = new HashMap<>(); - - public CustomizableSettings() { - wonPointsPerVictoryPerAge.put(1, 1); - wonPointsPerVictoryPerAge.put(2, 3); - wonPointsPerVictoryPerAge.put(3, 5); - } - - public long getRandomSeedForTests() { - return randomSeedForTests; - } - - public void setRandomSeedForTests(long randomSeedForTests) { - this.randomSeedForTests = randomSeedForTests; - } - - public int getTimeLimitInSeconds() { - return timeLimitInSeconds; - } - - public void setTimeLimitInSeconds(int timeLimitInSeconds) { - this.timeLimitInSeconds = timeLimitInSeconds; - } - - public int getInitialGold() { - return initialGold; - } - - public void setInitialGold(int initialGold) { - this.initialGold = initialGold; - } - - public int getDiscardedCardGold() { - return discardedCardGold; - } - - public void setDiscardedCardGold(int discardedCardGold) { - this.discardedCardGold = discardedCardGold; - } - - public int getDefaultTradingCost() { - return defaultTradingCost; - } - - public void setDefaultTradingCost(int defaultTradingCost) { - this.defaultTradingCost = defaultTradingCost; - } - - public int getPointsPer3Gold() { - return pointsPer3Gold; - } - - public void setPointsPer3Gold(int pointsPer3Gold) { - this.pointsPer3Gold = pointsPer3Gold; - } - - public WonderSidePickMethod getWonderSidePickMethod() { - return wonderSidePickMethod; - } - - public void setWonderSidePickMethod(WonderSidePickMethod wonderSidePickMethod) { - this.wonderSidePickMethod = wonderSidePickMethod; - } - - public int getLostPointsPerDefeat() { - return lostPointsPerDefeat; - } - - public void setLostPointsPerDefeat(int lostPointsPerDefeat) { - this.lostPointsPerDefeat = lostPointsPerDefeat; - } - - public Map<Integer, Integer> getWonPointsPerVictoryPerAge() { - return wonPointsPerVictoryPerAge; - } - - public void setWonPointsPerVictoryPerAge(Map<Integer, Integer> wonPointsPerVictoryPerAge) { - this.wonPointsPerVictoryPerAge = wonPointsPerVictoryPerAge; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - CustomizableSettings that = (CustomizableSettings) o; - return randomSeedForTests == that.randomSeedForTests && timeLimitInSeconds == that.timeLimitInSeconds - && initialGold == that.initialGold && discardedCardGold == that.discardedCardGold - && defaultTradingCost == that.defaultTradingCost && pointsPer3Gold == that.pointsPer3Gold - && lostPointsPerDefeat == that.lostPointsPerDefeat && wonderSidePickMethod == that.wonderSidePickMethod - && Objects.equals(wonPointsPerVictoryPerAge, that.wonPointsPerVictoryPerAge); - } - - @Override - public int hashCode() { - return Objects.hash(randomSeedForTests, timeLimitInSeconds, wonderSidePickMethod, initialGold, - discardedCardGold, defaultTradingCost, pointsPer3Gold, lostPointsPerDefeat, wonPointsPerVictoryPerAge); - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/api/HandCard.java b/backend/src/main/java/org/luxons/sevenwonders/game/api/HandCard.java deleted file mode 100644 index a97679c2..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/api/HandCard.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.luxons.sevenwonders.game.api; - -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.cards.Card; - -/** - * A card with contextual information relative to the hand it is sitting in. The extra information is especially useful - * because it frees the client from a painful business logic implementation. - */ -public class HandCard { - - private final Card card; - - private final boolean chainable; - - private final boolean free; - - private final boolean playable; - - public HandCard(Card card, Table table, int playerIndex) { - Board board = table.getBoard(playerIndex); - this.card = card; - this.chainable = card.isChainableOn(board); - this.free = card.isFreeFor(board); - this.playable = card.isPlayable(table, playerIndex); - } - - public Card getCard() { - return card; - } - - public boolean isChainable() { - return chainable; - } - - public boolean isFree() { - return free; - } - - public boolean isPlayable() { - return playable; - } - - @Override - public String toString() { - return "HandCard{" + "card=" + card + ", chainable=" + chainable + ", free=" + free + ", playable=" + playable - + '}'; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/api/PlayerMove.java b/backend/src/main/java/org/luxons/sevenwonders/game/api/PlayerMove.java deleted file mode 100644 index 179656cb..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/api/PlayerMove.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.luxons.sevenwonders.game.api; - -import java.util.ArrayList; -import java.util.List; -import javax.validation.constraints.NotNull; - -import org.luxons.sevenwonders.game.moves.MoveType; -import org.luxons.sevenwonders.game.resources.BoughtResources; - -public class PlayerMove { - - @NotNull - private MoveType type; - - @NotNull - private String cardName; - - private List<BoughtResources> boughtResources = new ArrayList<>(); - - public MoveType getType() { - return type; - } - - public void setType(MoveType type) { - this.type = type; - } - - public String getCardName() { - return cardName; - } - - public void setCardName(String cardName) { - this.cardName = cardName; - } - - public List<BoughtResources> getBoughtResources() { - return boughtResources; - } - - public void setBoughtResources(List<BoughtResources> boughtResources) { - this.boughtResources = boughtResources; - } - - @Override - public String toString() { - return type + " '" + cardName + '\''; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/api/PlayerTurnInfo.java b/backend/src/main/java/org/luxons/sevenwonders/game/api/PlayerTurnInfo.java deleted file mode 100644 index 3d92d40b..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/api/PlayerTurnInfo.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.luxons.sevenwonders.game.api; - -import java.util.List; - -import org.luxons.sevenwonders.game.cards.Card; - -public class PlayerTurnInfo { - - private final int playerIndex; - - private final Table table; - - private final int currentAge; - - private Action action; - - private List<HandCard> hand; - - private List<Card> neighbourGuildCards; - - private String message; - - public PlayerTurnInfo(int playerIndex, Table table) { - this.playerIndex = playerIndex; - this.table = table; - this.currentAge = table.getCurrentAge(); - } - - public int getPlayerIndex() { - return playerIndex; - } - - public Table getTable() { - return table; - } - - public int getCurrentAge() { - return currentAge; - } - - public List<HandCard> getHand() { - return hand; - } - - public void setHand(List<HandCard> hand) { - this.hand = hand; - } - - public List<Card> getNeighbourGuildCards() { - return neighbourGuildCards; - } - - public void setNeighbourGuildCards(List<Card> neighbourGuildCards) { - this.neighbourGuildCards = neighbourGuildCards; - } - - public Action getAction() { - return action; - } - - public void setAction(Action action) { - this.action = action; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - @Override - public String toString() { - return "PlayerTurnInfo{" + "playerIndex=" + playerIndex + ", action=" + action + ", hand=" + hand + '}'; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/api/Table.java b/backend/src/main/java/org/luxons/sevenwonders/game/api/Table.java deleted file mode 100644 index 82f9055a..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/api/Table.java +++ /dev/null @@ -1,106 +0,0 @@ -package org.luxons.sevenwonders.game.api; - -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.boards.RelativeBoardPosition; -import org.luxons.sevenwonders.game.cards.Card; -import org.luxons.sevenwonders.game.cards.Color; -import org.luxons.sevenwonders.game.cards.HandRotationDirection; -import org.luxons.sevenwonders.game.moves.Move; -import org.luxons.sevenwonders.game.resources.Provider; - -/** - * The table contains what is visible by all the players in the game: the boards and their played cards, and the - * players' information. - */ -public class Table { - - private final int nbPlayers; - - private final List<Board> boards; - - private int currentAge = 0; - - private List<Move> lastPlayedMoves; - - public Table(List<Board> boards) { - this.nbPlayers = boards.size(); - this.boards = boards; - } - - public int getNbPlayers() { - return nbPlayers; - } - - public List<Board> getBoards() { - return boards; - } - - public Board getBoard(int playerIndex) { - return boards.get(playerIndex); - } - - public Board getBoard(int playerIndex, RelativeBoardPosition position) { - return boards.get(position.getIndexFrom(playerIndex, nbPlayers)); - } - - public List<Move> getLastPlayedMoves() { - return lastPlayedMoves; - } - - public void setLastPlayedMoves(List<Move> lastPlayedMoves) { - this.lastPlayedMoves = lastPlayedMoves; - } - - public int getCurrentAge() { - return currentAge; - } - - public void increaseCurrentAge() { - this.currentAge++; - } - - public HandRotationDirection getHandRotationDirection() { - return HandRotationDirection.forAge(currentAge); - } - - public void resolveMilitaryConflicts() { - for (int i = 0; i < nbPlayers; i++) { - Board board1 = getBoard(i); - Board board2 = getBoard((i + 1) % nbPlayers); - resolveConflict(board1, board2, currentAge); - } - } - - private static void resolveConflict(Board board1, Board board2, int age) { - int shields1 = board1.getMilitary().getNbShields(); - int shields2 = board2.getMilitary().getNbShields(); - if (shields1 < shields2) { - board2.getMilitary().victory(age); - board1.getMilitary().defeat(); - } else if (shields1 > shields2) { - board1.getMilitary().victory(age); - board2.getMilitary().defeat(); - } - } - - public List<Card> getNeighbourGuildCards(int playerIndex) { - return getNeighbourBoards(playerIndex).stream() - .map(Board::getPlayedCards) - .flatMap(List::stream) - .filter(c -> c.getColor() == Color.PURPLE) - .collect(Collectors.toList()); - } - - private List<Board> getNeighbourBoards(int playerIndex) { - Provider[] providers = Provider.values(); - List<Board> boards = new ArrayList<>(providers.length); - for (Provider provider : providers) { - boards.add(getBoard(playerIndex, provider.getBoardPosition())); - } - return boards; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/boards/Board.java b/backend/src/main/java/org/luxons/sevenwonders/game/boards/Board.java deleted file mode 100644 index a59bbfae..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/boards/Board.java +++ /dev/null @@ -1,175 +0,0 @@ -package org.luxons.sevenwonders.game.boards; - -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.cards.Card; -import org.luxons.sevenwonders.game.cards.Color; -import org.luxons.sevenwonders.game.effects.SpecialAbility; -import org.luxons.sevenwonders.game.resources.Production; -import org.luxons.sevenwonders.game.resources.TradingRules; -import org.luxons.sevenwonders.game.scoring.PlayerScore; -import org.luxons.sevenwonders.game.scoring.ScoreCategory; -import org.luxons.sevenwonders.game.wonders.Wonder; - -public class Board { - - private final Wonder wonder; - - private final int playerIndex; - - private final List<Card> playedCards = new ArrayList<>(); - - private final Production production = new Production(); - - private final Production publicProduction = new Production(); - - private final Science science = new Science(); - - private final TradingRules tradingRules; - - private final Military military; - - private final Set<SpecialAbility> specialAbilities = EnumSet.noneOf(SpecialAbility.class); - - private Map<Integer, Boolean> consumedFreeCards = new HashMap<>(); - - private Card copiedGuild; - - private int gold; - - private int pointsPer3Gold; - - public Board(Wonder wonder, int playerIndex, Settings settings) { - this.wonder = wonder; - this.playerIndex = playerIndex; - this.gold = settings.getInitialGold(); - this.tradingRules = new TradingRules(settings.getDefaultTradingCost()); - this.military = new Military(settings.getLostPointsPerDefeat(), settings.getWonPointsPerVictoryPerAge()); - this.pointsPer3Gold = settings.getPointsPer3Gold(); - this.production.addFixedResource(wonder.getInitialResource(), 1); - this.publicProduction.addFixedResource(wonder.getInitialResource(), 1); - } - - public Wonder getWonder() { - return wonder; - } - - public List<Card> getPlayedCards() { - return playedCards; - } - - public void addCard(Card card) { - playedCards.add(card); - } - - int getNbCardsOfColor(List<Color> colorFilter) { - return (int) playedCards.stream().filter(c -> colorFilter.contains(c.getColor())).count(); - } - - public boolean isPlayed(String cardName) { - return getPlayedCards().stream().map(Card::getName).filter(name -> name.equals(cardName)).count() > 0; - } - - public Production getProduction() { - return production; - } - - public Production getPublicProduction() { - return publicProduction; - } - - public TradingRules getTradingRules() { - return tradingRules; - } - - public Science getScience() { - return science; - } - - public int getGold() { - return gold; - } - - public void setGold(int amount) { - this.gold = amount; - } - - public void addGold(int amount) { - this.gold += amount; - } - - public void removeGold(int amount) { - if (gold < amount) { - throw new InsufficientFundsException(gold, amount); - } - this.gold -= amount; - } - - public Military getMilitary() { - return military; - } - - public void addSpecial(SpecialAbility specialAbility) { - specialAbilities.add(specialAbility); - } - - public boolean hasSpecial(SpecialAbility specialAbility) { - return specialAbilities.contains(specialAbility); - } - - public boolean canPlayFreeCard(int age) { - return hasSpecial(SpecialAbility.ONE_FREE_PER_AGE) && !consumedFreeCards.getOrDefault(age, false); - } - - public void consumeFreeCard(int age) { - consumedFreeCards.put(age, true); - } - - public void setCopiedGuild(Card copiedGuild) { - if (copiedGuild.getColor() != Color.PURPLE) { - throw new IllegalArgumentException("The given card '" + copiedGuild + "' is not a Guild card"); - } - this.copiedGuild = copiedGuild; - } - - public Card getCopiedGuild() { - return copiedGuild; - } - - public PlayerScore computePoints(Table table) { - PlayerScore score = new PlayerScore(gold); - score.put(ScoreCategory.CIVIL, computePointsForCards(table, Color.BLUE)); - score.put(ScoreCategory.MILITARY, military.getTotalPoints()); - score.put(ScoreCategory.SCIENCE, science.computePoints()); - score.put(ScoreCategory.TRADE, computePointsForCards(table, Color.YELLOW)); - score.put(ScoreCategory.GUILD, computePointsForCards(table, Color.PURPLE)); - score.put(ScoreCategory.WONDER, wonder.computePoints(table, playerIndex)); - score.put(ScoreCategory.GOLD, computeGoldPoints()); - return score; - } - - private int computePointsForCards(Table table, Color color) { - return playedCards.stream() - .filter(c -> c.getColor() == color) - .flatMap(c -> c.getEffects().stream()) - .mapToInt(e -> e.computePoints(table, playerIndex)) - .sum(); - } - - private int computeGoldPoints() { - return gold / 3 * pointsPer3Gold; - } - - static class InsufficientFundsException extends RuntimeException { - InsufficientFundsException(int current, int required) { - super(String.format("Current balance is %d gold, but %d are required", current, required)); - } - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/boards/BoardElementType.java b/backend/src/main/java/org/luxons/sevenwonders/game/boards/BoardElementType.java deleted file mode 100644 index e50f4ea0..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/boards/BoardElementType.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.luxons.sevenwonders.game.boards; - -import java.util.List; - -import org.luxons.sevenwonders.game.cards.Color; - -public enum BoardElementType { - CARD { - @Override - public int getElementCount(Board board, List<Color> colors) { - return board.getNbCardsOfColor(colors); - } - }, - BUILT_WONDER_STAGES { - @Override - public int getElementCount(Board board, List<Color> colors) { - return board.getWonder().getNbBuiltStages(); - } - }, - DEFEAT_TOKEN { - @Override - public int getElementCount(Board board, List<Color> colors) { - return board.getMilitary().getNbDefeatTokens(); - } - }; - - public abstract int getElementCount(Board board, List<Color> colors); -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/boards/Military.java b/backend/src/main/java/org/luxons/sevenwonders/game/boards/Military.java deleted file mode 100644 index e5cc7033..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/boards/Military.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.luxons.sevenwonders.game.boards; - -import java.util.Map; - -public class Military { - - private final int lostPointsPerDefeat; - - private final Map<Integer, Integer> wonPointsPerVictoryPerAge; - - private int nbShields = 0; - - private int totalPoints = 0; - - private int nbDefeatTokens = 0; - - Military(int lostPointsPerDefeat, Map<Integer, Integer> wonPointsPerVictoryPerAge) { - this.lostPointsPerDefeat = lostPointsPerDefeat; - this.wonPointsPerVictoryPerAge = wonPointsPerVictoryPerAge; - } - - public int getNbShields() { - return nbShields; - } - - public void addShields(int nbShields) { - this.nbShields += nbShields; - } - - public int getTotalPoints() { - return totalPoints; - } - - public int getNbDefeatTokens() { - return nbDefeatTokens; - } - - public void victory(int age) { - Integer wonPoints = wonPointsPerVictoryPerAge.get(age); - if (wonPoints == null) { - throw new UnknownAgeException(age); - } - totalPoints += wonPoints; - } - - public void defeat() { - totalPoints -= lostPointsPerDefeat; - nbDefeatTokens++; - } - - static final class UnknownAgeException extends IllegalArgumentException { - UnknownAgeException(int unknownAge) { - super(String.valueOf(unknownAge)); - } - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/boards/RelativeBoardPosition.java b/backend/src/main/java/org/luxons/sevenwonders/game/boards/RelativeBoardPosition.java deleted file mode 100644 index 16b2f3a9..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/boards/RelativeBoardPosition.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.luxons.sevenwonders.game.boards; - -public enum RelativeBoardPosition { - LEFT { - @Override - public int getIndexFrom(int playerIndex, int nbPlayers) { - return wrapIndex(playerIndex - 1, nbPlayers); - } - }, - SELF { - @Override - public int getIndexFrom(int playerIndex, int nbPlayers) { - return playerIndex; - } - }, - RIGHT { - @Override - public int getIndexFrom(int playerIndex, int nbPlayers) { - return wrapIndex(playerIndex + 1, nbPlayers); - } - }; - - public abstract int getIndexFrom(int playerIndex, int nbPlayers); - - int wrapIndex(int index, int nbPlayers) { - return Math.floorMod(index, nbPlayers); - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/boards/Science.java b/backend/src/main/java/org/luxons/sevenwonders/game/boards/Science.java deleted file mode 100644 index 34928bcc..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/boards/Science.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.luxons.sevenwonders.game.boards; - -import java.util.Arrays; -import java.util.EnumMap; -import java.util.Map; - -public class Science { - - private Map<ScienceType, Integer> quantities = new EnumMap<>(ScienceType.class); - - private int jokers; - - public void add(ScienceType type, int quantity) { - quantities.merge(type, quantity, (x, y) -> x + y); - } - - public void addJoker(int quantity) { - jokers += quantity; - } - - public int getJokers() { - return jokers; - } - - public void addAll(Science science) { - science.quantities.forEach(this::add); - jokers += science.jokers; - } - - public int getQuantity(ScienceType type) { - return quantities.getOrDefault(type, 0); - } - - public int size() { - return quantities.values().stream().mapToInt(q -> q).sum() + jokers; - } - - public int computePoints() { - ScienceType[] types = ScienceType.values(); - Integer[] values = new Integer[types.length]; - for (int i = 0; i < types.length; i++) { - values[i] = quantities.getOrDefault(types[i], 0); - } - return computePoints(values, jokers); - } - - private static int computePoints(Integer[] values, int jokers) { - if (jokers == 0) { - return computePointsNoJoker(values); - } - int maxPoints = 0; - for (int i = 0; i < values.length; i++) { - values[i]++; - maxPoints = Math.max(maxPoints, computePoints(values, jokers - 1)); - values[i]--; - } - return maxPoints; - } - - private static int computePointsNoJoker(Integer[] values) { - int independentSquaresSum = Arrays.stream(values).mapToInt(i -> i * i).sum(); - int nbGroupsOfAll = Arrays.stream(values).mapToInt(i -> i).min().orElse(0); - return independentSquaresSum + nbGroupsOfAll * 7; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/boards/ScienceType.java b/backend/src/main/java/org/luxons/sevenwonders/game/boards/ScienceType.java deleted file mode 100644 index f1b14c6d..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/boards/ScienceType.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.luxons.sevenwonders.game.boards; - -public enum ScienceType { - COMPASS, - WHEEL, - TABLET -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/cards/Card.java b/backend/src/main/java/org/luxons/sevenwonders/game/cards/Card.java deleted file mode 100644 index 084d19a5..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/cards/Card.java +++ /dev/null @@ -1,128 +0,0 @@ -package org.luxons.sevenwonders.game.cards; - -import java.util.List; -import java.util.Objects; - -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.effects.Effect; -import org.luxons.sevenwonders.game.resources.BoughtResources; - -public class Card { - - private final String name; - - private final Color color; - - private final Requirements requirements; - - private final List<Effect> effects; - - private final String chainParent; - - private final List<String> chainChildren; - - private final String image; - - private CardBack back; - - public Card(String name, Color color, Requirements requirements, List<Effect> effects, String chainParent, - List<String> chainChildren, String image) { - this.name = name; - this.color = color; - this.requirements = requirements; - this.chainParent = chainParent; - this.effects = effects; - this.chainChildren = chainChildren; - this.image = image; - } - - public String getName() { - return name; - } - - public Color getColor() { - return color; - } - - public String getChainParent() { - return chainParent; - } - - public Requirements getRequirements() { - return requirements; - } - - public List<Effect> getEffects() { - return effects; - } - - public List<String> getChainChildren() { - return chainChildren; - } - - public String getImage() { - return image; - } - - public CardBack getBack() { - return back; - } - - public void setBack(CardBack back) { - this.back = back; - } - - private boolean isAllowedOnBoard(Board board) { - return !board.isPlayed(name); // cannot play twice the same card - } - - public boolean isChainableOn(Board board) { - return isAllowedOnBoard(board) && board.isPlayed(chainParent); - } - - public boolean isFreeFor(Board board) { - if (!isAllowedOnBoard(board)) { - return false; - } - return isChainableOn(board) || (requirements.areMetWithoutNeighboursBy(board) && requirements.getGold() == 0); - } - - public boolean isPlayable(Table table, int playerIndex) { - Board board = table.getBoard(playerIndex); - if (!isAllowedOnBoard(board)) { - return false; - } - return isChainableOn(board) || requirements.couldBeMetBy(table, playerIndex); - } - - public void applyTo(Table table, int playerIndex, List<BoughtResources> boughtResources) { - Board playerBoard = table.getBoard(playerIndex); - if (!isChainableOn(playerBoard)) { - requirements.pay(table, playerIndex, boughtResources); - } - effects.forEach(e -> e.apply(table, playerIndex)); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Card card = (Card) o; - return Objects.equals(name, card.name); - } - - @Override - public int hashCode() { - return Objects.hash(name); - } - - @Override - public String toString() { - return "Card{" + name + '}'; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/cards/CardBack.java b/backend/src/main/java/org/luxons/sevenwonders/game/cards/CardBack.java deleted file mode 100644 index f925b6c4..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/cards/CardBack.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.luxons.sevenwonders.game.cards; - -public class CardBack { - - private final String image; - - public CardBack(String image) { - this.image = image; - } - - public String getImage() { - return image; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/cards/Color.java b/backend/src/main/java/org/luxons/sevenwonders/game/cards/Color.java deleted file mode 100644 index 80d06c55..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/cards/Color.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.luxons.sevenwonders.game.cards; - -public enum Color { - BROWN, - GREY, - YELLOW, - BLUE, - GREEN, - RED, - PURPLE -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/cards/Decks.java b/backend/src/main/java/org/luxons/sevenwonders/game/cards/Decks.java deleted file mode 100644 index aa2b00bf..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/cards/Decks.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.luxons.sevenwonders.game.cards; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class Decks { - - private Map<Integer, List<Card>> cardsPerAge = new HashMap<>(); - - public Decks(Map<Integer, List<Card>> cardsPerAge) { - this.cardsPerAge = cardsPerAge; - } - - public Card getCard(String cardName) throws CardNotFoundException { - return cardsPerAge.values() - .stream() - .flatMap(List::stream) - .filter(c -> c.getName().equals(cardName)) - .findAny() - .orElseThrow(() -> new CardNotFoundException(cardName)); - } - - public Hands deal(int age, int nbPlayers) { - List<Card> deck = getDeck(age); - validateNbCards(deck, nbPlayers); - return deal(deck, nbPlayers); - } - - private List<Card> getDeck(int age) { - List<Card> deck = cardsPerAge.get(age); - if (deck == null) { - throw new IllegalArgumentException("No deck found for age " + age); - } - return deck; - } - - private void validateNbCards(List<Card> deck, int nbPlayers) { - if (nbPlayers == 0) { - throw new IllegalArgumentException("Cannot deal cards between 0 players"); - } - if (deck.size() % nbPlayers != 0) { - throw new IllegalArgumentException( - String.format("Cannot deal %d cards evenly between %d players", deck.size(), nbPlayers)); - } - } - - private Hands deal(List<Card> deck, int nbPlayers) { - Map<Integer, List<Card>> hands = new HashMap<>(nbPlayers); - for (int i = 0; i < nbPlayers; i++) { - hands.put(i, new ArrayList<>()); - } - for (int i = 0; i < deck.size(); i++) { - hands.get(i % nbPlayers).add(deck.get(i)); - } - return new Hands(hands, nbPlayers); - } - - class CardNotFoundException extends RuntimeException { - CardNotFoundException(String message) { - super(message); - } - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/cards/HandRotationDirection.java b/backend/src/main/java/org/luxons/sevenwonders/game/cards/HandRotationDirection.java deleted file mode 100644 index f3902fb5..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/cards/HandRotationDirection.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.luxons.sevenwonders.game.cards; - -public enum HandRotationDirection { - LEFT(-1), - RIGHT(1); - - private final int indexOffset; - - HandRotationDirection(int i) { - this.indexOffset = i; - } - - public int getIndexOffset() { - return indexOffset; - } - - public static HandRotationDirection forAge(int age) { - // clockwise (pass to the left) at age 1, and alternating - return age % 2 == 0 ? HandRotationDirection.RIGHT : HandRotationDirection.LEFT; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/cards/Hands.java b/backend/src/main/java/org/luxons/sevenwonders/game/cards/Hands.java deleted file mode 100644 index 4a8bc143..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/cards/Hands.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.luxons.sevenwonders.game.cards; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import org.luxons.sevenwonders.game.api.HandCard; -import org.luxons.sevenwonders.game.api.Table; - -public class Hands { - - private final int nbPlayers; - - private Map<Integer, List<Card>> hands; - - Hands(Map<Integer, List<Card>> hands, int nbPlayers) { - this.hands = hands; - this.nbPlayers = nbPlayers; - } - - public List<Card> get(int playerIndex) { - if (!hands.containsKey(playerIndex)) { - throw new PlayerIndexOutOfBoundsException(playerIndex); - } - return hands.get(playerIndex); - } - - public List<HandCard> createHand(Table table, int playerIndex) { - return hands.get(playerIndex) - .stream() - .map(c -> new HandCard(c, table, playerIndex)) - .collect(Collectors.toList()); - } - - public Hands rotate(HandRotationDirection direction) { - Map<Integer, List<Card>> newHands = new HashMap<>(hands.size()); - for (int i = 0; i < nbPlayers; i++) { - int newIndex = Math.floorMod(i + direction.getIndexOffset(), nbPlayers); - newHands.put(newIndex, hands.get(i)); - } - return new Hands(newHands, nbPlayers); - } - - public boolean isEmpty() { - return hands.values().stream().allMatch(List::isEmpty); - } - - public boolean maxOneCardRemains() { - return hands.values().stream().mapToInt(List::size).max().orElse(0) <= 1; - } - - public List<Card> gatherAndClear() { - List<Card> remainingCards = hands.values().stream().flatMap(List::stream).collect(Collectors.toList()); - hands.clear(); - return remainingCards; - } - - class PlayerIndexOutOfBoundsException extends ArrayIndexOutOfBoundsException { - PlayerIndexOutOfBoundsException(int index) { - super(index); - } - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/cards/Requirements.java b/backend/src/main/java/org/luxons/sevenwonders/game/cards/Requirements.java deleted file mode 100644 index 93683ff8..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/cards/Requirements.java +++ /dev/null @@ -1,131 +0,0 @@ -package org.luxons.sevenwonders.game.cards; - -import java.util.List; - -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.boards.RelativeBoardPosition; -import org.luxons.sevenwonders.game.resources.BestPriceCalculator; -import org.luxons.sevenwonders.game.resources.BoughtResources; -import org.luxons.sevenwonders.game.resources.Resources; - -public class Requirements { - - private int gold; - - private Resources resources = new Resources(); - - public int getGold() { - return gold; - } - - public void setGold(int gold) { - this.gold = gold; - } - - public Resources getResources() { - return resources; - } - - public void setResources(Resources resources) { - this.resources = resources; - } - - /** - * Returns whether the given board meets these requirements on its own. - * - * @param board - * the board to check - * - * @return true if the given board meets these requirements without any transaction with its neighbours - */ - boolean areMetWithoutNeighboursBy(Board board) { - return hasRequiredGold(board) && producesRequiredResources(board); - } - - /** - * Returns whether the given board meets these requirements, if the specified resources are bought from neighbours. - * - * @param board - * the board to check - * @param boughtResources - * the resources the player intends to buy - * - * @return true if the given board meets these requirements - */ - public boolean areMetWithHelpBy(Board board, List<BoughtResources> boughtResources) { - if (!hasRequiredGold(board, boughtResources)) { - return false; - } - if (producesRequiredResources(board)) { - return true; - } - return producesRequiredResourcesWithHelp(board, boughtResources); - } - - /** - * Returns whether the given player's board could meet these requirements, on its own or by buying resources to - * neighbours. - * - * @param table - * the current game table - * @param playerIndex - * the index of the player to check - * - * @return true if the given player's board could meet these requirements - */ - boolean couldBeMetBy(Table table, int playerIndex) { - Board board = table.getBoard(playerIndex); - if (!hasRequiredGold(board)) { - return false; - } - if (producesRequiredResources(board)) { - return true; - } - return BestPriceCalculator.bestPrice(resources, table, playerIndex) <= board.getGold() - gold; - } - - private boolean hasRequiredGold(Board board) { - return board.getGold() >= gold; - } - - private boolean hasRequiredGold(Board board, List<BoughtResources> boughtResources) { - int resourcesPrice = board.getTradingRules().computeCost(boughtResources); - return board.getGold() >= gold + resourcesPrice; - } - - private boolean producesRequiredResources(Board board) { - return board.getProduction().contains(resources); - } - - private boolean producesRequiredResourcesWithHelp(Board board, List<BoughtResources> boughtResources) { - Resources totalBoughtResources = getTotalResources(boughtResources); - Resources remainingResources = this.resources.minus(totalBoughtResources); - return board.getProduction().contains(remainingResources); - } - - private static Resources getTotalResources(List<BoughtResources> boughtResources) { - return boughtResources.stream().map(BoughtResources::getResources).reduce(new Resources(), (r1, r2) -> { - r1.addAll(r2); - return r1; - }); - } - - void pay(Table table, int playerIndex, List<BoughtResources> boughtResources) { - table.getBoard(playerIndex).removeGold(gold); - payBoughtResources(table, playerIndex, boughtResources); - } - - private void payBoughtResources(Table table, int playerIndex, List<BoughtResources> boughtResourcesList) { - boughtResourcesList.forEach(res -> payBoughtResources(table, playerIndex, res)); - } - - private void payBoughtResources(Table table, int playerIndex, BoughtResources boughtResources) { - Board board = table.getBoard(playerIndex); - int price = board.getTradingRules().computeCost(boughtResources); - board.removeGold(price); - RelativeBoardPosition providerPosition = boughtResources.getProvider().getBoardPosition(); - Board providerBoard = table.getBoard(playerIndex, providerPosition); - providerBoard.addGold(price); - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/data/GameDefinition.java b/backend/src/main/java/org/luxons/sevenwonders/game/data/GameDefinition.java deleted file mode 100644 index 7604ca6a..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/data/GameDefinition.java +++ /dev/null @@ -1,66 +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 { - - /** - * This value is heavily dependent on the JSON data. Any change must be carefully thought through. - */ - private static final int MIN_PLAYERS = 3; - - /** - * This value is heavily dependent on the JSON data. Any change must be carefully thought through. - */ - private static final int MAX_PLAYERS = 7; - - private WonderDefinition[] wonders; - - private DecksDefinition decksDefinition; - - GameDefinition(WonderDefinition[] wonders, DecksDefinition decksDefinition) { - this.wonders = wonders; - this.decksDefinition = decksDefinition; - } - - public int getMinPlayers() { - return MIN_PLAYERS; - } - - public int getMaxPlayers() { - return MAX_PLAYERS; - } - - public Game initGame(long id, CustomizableSettings customSettings, int nbPlayers) { - Settings settings = new Settings(nbPlayers, customSettings); - List<Board> boards = assignBoards(settings, nbPlayers); - Decks decks = decksDefinition.create(settings); - return new Game(id, settings, nbPlayers, boards, decks); - } - - private List<Board> assignBoards(Settings settings, int nbPlayers) { - List<WonderDefinition> randomizedWonders = Arrays.asList(wonders); - Collections.shuffle(randomizedWonders, settings.getRandom()); - - List<Board> 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/backend/src/main/java/org/luxons/sevenwonders/game/data/GameDefinitionLoader.java b/backend/src/main/java/org/luxons/sevenwonders/game/data/GameDefinitionLoader.java deleted file mode 100644 index f0da6d63..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/data/GameDefinitionLoader.java +++ /dev/null @@ -1,87 +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 org.springframework.stereotype.Component; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.reflect.TypeToken; - -@Component -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 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(loadWonders(), loadDecks()); - } - - private static WonderDefinition[] loadWonders() { - return readJsonFile(WONDERS_FILE, WonderDefinition[].class); - } - - private static DecksDefinition loadDecks() { - return readJsonFile(CARDS_FILE, DecksDefinition.class); - } - - private static <T> T readJsonFile(String filename, Class<T> 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<List<ResourceType>>() {}.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/backend/src/main/java/org/luxons/sevenwonders/game/data/definitions/CardDefinition.java b/backend/src/main/java/org/luxons/sevenwonders/game/data/definitions/CardDefinition.java deleted file mode 100644 index 621bed2c..00000000 --- a/backend/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<Card> { - - private String name; - - private Color color; - - private Requirements requirements; - - private EffectsDefinition effect; - - private String chainParent; - - private List<String> chainChildren; - - private Map<Integer, Integer> countPerNbPlayer; - - private String image; - - @Override - public Card create(Settings settings) { - return new Card(name, color, requirements, effect.create(settings), chainParent, chainChildren, image); - } - - Map<Integer, Integer> getCountPerNbPlayer() { - return countPerNbPlayer; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/data/definitions/DecksDefinition.java b/backend/src/main/java/org/luxons/sevenwonders/game/data/definitions/DecksDefinition.java deleted file mode 100644 index 6f97e55f..00000000 --- a/backend/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<Decks> { - - private List<CardDefinition> age1; - - private List<CardDefinition> age2; - - private List<CardDefinition> age3; - - private String age1Back; - - private String age2Back; - - private String age3Back; - - private List<CardDefinition> guildCards; - - @Override - public Decks create(Settings settings) { - Map<Integer, List<Card>> 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<Card> prepareStandardDeck(List<CardDefinition> defs, Settings settings, String backImage) { - CardBack back = new CardBack(backImage); - List<Card> cards = createDeck(defs, settings, back); - Collections.shuffle(cards, settings.getRandom()); - return cards; - } - - private List<Card> prepareAge3Deck(Settings settings) { - CardBack back = new CardBack(age3Back); - List<Card> age3deck = createDeck(age3, settings, back); - age3deck.addAll(createGuildCards(settings, back)); - Collections.shuffle(age3deck, settings.getRandom()); - return age3deck; - } - - private static List<Card> createDeck(List<CardDefinition> defs, Settings settings, CardBack back) { - List<Card> 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<Card> createGuildCards(Settings settings, CardBack back) { - List<Card> 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/backend/src/main/java/org/luxons/sevenwonders/game/data/definitions/Definition.java b/backend/src/main/java/org/luxons/sevenwonders/game/data/definitions/Definition.java deleted file mode 100644 index 6c6b4b19..00000000 --- a/backend/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 <T> - * the type of in-game object that can be generated from this definition - */ -public interface Definition<T> { - - /** - * 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/backend/src/main/java/org/luxons/sevenwonders/game/data/definitions/EffectsDefinition.java b/backend/src/main/java/org/luxons/sevenwonders/game/data/definitions/EffectsDefinition.java deleted file mode 100644 index e35463d4..00000000 --- a/backend/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<List<Effect>> { - - 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<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); - } - if (action != null) { - effects.add(new SpecialAbilityActivation(action)); - } - return effects; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderDefinition.java b/backend/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderDefinition.java deleted file mode 100644 index a972a517..00000000 --- a/backend/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<Wonder> { - - private String name; - - private Map<WonderSide, WonderSideDefinition> 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/backend/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSide.java b/backend/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSide.java deleted file mode 100644 index 34091350..00000000 --- a/backend/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/backend/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSideDefinition.java b/backend/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSideDefinition.java deleted file mode 100644 index c84bba4e..00000000 --- a/backend/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<WonderStageDefinition> stages; - - private String image; - - ResourceType getInitialResource() { - return initialResource; - } - - List<WonderStage> createStages(Settings settings) { - return stages.stream().map(def -> def.create(settings)).collect(Collectors.toList()); - } - - String getImage() { - return image; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSidePickMethod.java b/backend/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderSidePickMethod.java deleted file mode 100644 index 08aaad14..00000000 --- a/backend/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/backend/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderStageDefinition.java b/backend/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderStageDefinition.java deleted file mode 100644 index 887b414a..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/data/definitions/WonderStageDefinition.java +++ /dev/null @@ -1,21 +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<WonderStage> { - - private Requirements requirements; - - private EffectsDefinition effects; - - @Override - public WonderStage create(Settings settings) { - WonderStage stage = new WonderStage(); - stage.setRequirements(requirements); - stage.setEffects(effects.create(settings)); - return stage; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/data/serializers/NumericEffectSerializer.java b/backend/src/main/java/org/luxons/sevenwonders/game/data/serializers/NumericEffectSerializer.java deleted file mode 100644 index c0a75d80..00000000 --- a/backend/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<Effect>, JsonDeserializer<Effect> { - - @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/backend/src/main/java/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializer.java b/backend/src/main/java/org/luxons/sevenwonders/game/data/serializers/ProductionIncreaseSerializer.java deleted file mode 100644 index c3eb1386..00000000 --- a/backend/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<ProductionIncrease>, - JsonDeserializer<ProductionIncrease> { - - @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/backend/src/main/java/org/luxons/sevenwonders/game/data/serializers/ProductionSerializer.java b/backend/src/main/java/org/luxons/sevenwonders/game/data/serializers/ProductionSerializer.java deleted file mode 100644 index 178134bb..00000000 --- a/backend/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<Production>, JsonDeserializer<Production> { - - @Override - public JsonElement serialize(Production production, Type typeOfSrc, JsonSerializationContext context) { - Resources fixedResources = production.getFixedResources(); - Set<Set<ResourceType>> 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<Set<ResourceType>> 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/backend/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypeSerializer.java b/backend/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypeSerializer.java deleted file mode 100644 index d2a49180..00000000 --- a/backend/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<ResourceType>, JsonDeserializer<ResourceType> { - - @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/backend/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializer.java b/backend/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourceTypesSerializer.java deleted file mode 100644 index 89d3e723..00000000 --- a/backend/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<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/backend/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.java b/backend/src/main/java/org/luxons/sevenwonders/game/data/serializers/ResourcesSerializer.java deleted file mode 100644 index 9c27b2a1..00000000 --- a/backend/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<Resources>, JsonDeserializer<Resources> { - - @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/backend/src/main/java/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializer.java b/backend/src/main/java/org/luxons/sevenwonders/game/data/serializers/ScienceProgressSerializer.java deleted file mode 100644 index cecad405..00000000 --- a/backend/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<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(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/backend/src/main/java/org/luxons/sevenwonders/game/effects/BonusPerBoardElement.java b/backend/src/main/java/org/luxons/sevenwonders/game/effects/BonusPerBoardElement.java deleted file mode 100644 index e9f9fe5f..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/effects/BonusPerBoardElement.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import java.util.List; - -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.boards.BoardElementType; -import org.luxons.sevenwonders.game.boards.RelativeBoardPosition; -import org.luxons.sevenwonders.game.cards.Color; - -public class BonusPerBoardElement implements Effect { - - private List<RelativeBoardPosition> boards; - - private int gold; - - private int points; - - private BoardElementType type; - - // only relevant if type=CARD - private List<Color> colors; - - public List<RelativeBoardPosition> getBoards() { - return boards; - } - - public void setBoards(List<RelativeBoardPosition> boards) { - this.boards = boards; - } - - public int getGold() { - return gold; - } - - public void setGold(int gold) { - this.gold = gold; - } - - public int getPoints() { - return points; - } - - public void setPoints(int points) { - this.points = points; - } - - public BoardElementType getType() { - return type; - } - - public void setType(BoardElementType type) { - this.type = type; - } - - public List<Color> getColors() { - return colors; - } - - public void setColors(List<Color> colors) { - this.colors = colors; - } - - @Override - public void apply(Table table, int playerIndex) { - int goldGain = gold * computeNbOfMatchingElementsIn(table, playerIndex); - Board board = table.getBoard(playerIndex); - board.addGold(goldGain); - } - - @Override - public int computePoints(Table table, int playerIndex) { - return points * computeNbOfMatchingElementsIn(table, playerIndex); - } - - private int computeNbOfMatchingElementsIn(Table table, int playerIndex) { - return boards.stream() - .map(pos -> table.getBoard(playerIndex, pos)) - .mapToInt(this::computeNbOfMatchingElementsIn) - .sum(); - } - - private int computeNbOfMatchingElementsIn(Board board) { - return type.getElementCount(board, colors); - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/effects/Discount.java b/backend/src/main/java/org/luxons/sevenwonders/game/effects/Discount.java deleted file mode 100644 index 976ebf35..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/effects/Discount.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import java.util.ArrayList; -import java.util.List; - -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.resources.Provider; -import org.luxons.sevenwonders.game.resources.ResourceType; -import org.luxons.sevenwonders.game.resources.TradingRules; - -public class Discount extends InstantOwnBoardEffect { - - private final List<ResourceType> resourceTypes = new ArrayList<>(); - - private final List<Provider> providers = new ArrayList<>(); - - private int discountedPrice = 1; - - public List<ResourceType> getResourceTypes() { - return resourceTypes; - } - - public List<Provider> getProviders() { - return providers; - } - - public int getDiscountedPrice() { - return discountedPrice; - } - - public void setDiscountedPrice(int discountedPrice) { - this.discountedPrice = discountedPrice; - } - - @Override - public void apply(Board board) { - TradingRules rules = board.getTradingRules(); - for (ResourceType type : resourceTypes) { - for (Provider provider : providers) { - rules.setCost(type, provider, discountedPrice); - } - } - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/effects/Effect.java b/backend/src/main/java/org/luxons/sevenwonders/game/effects/Effect.java deleted file mode 100644 index 692eaea0..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/effects/Effect.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import org.luxons.sevenwonders.game.api.Table; - -/** - * Represents an effect than can be applied to a player's board when playing a card or building his wonder. The effect - * may affect (or depend on) the adjacent boards. It can have an instantaneous effect on the board, or be postponed to - * the end of game where point calculations take place. - */ -public interface Effect { - - void apply(Table table, int playerIndex); - - int computePoints(Table table, int playerIndex); -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/effects/EndGameEffect.java b/backend/src/main/java/org/luxons/sevenwonders/game/effects/EndGameEffect.java deleted file mode 100644 index 1bae16a6..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/effects/EndGameEffect.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import org.luxons.sevenwonders.game.api.Table; - -public abstract class EndGameEffect implements Effect { - - @Override - public void apply(Table table, int playerIndex) { - // EndGameEffects don't do anything when applied to the board, they simply give more points in the end - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/effects/GoldIncrease.java b/backend/src/main/java/org/luxons/sevenwonders/game/effects/GoldIncrease.java deleted file mode 100644 index 4c1215d4..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/effects/GoldIncrease.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import java.util.Objects; - -import org.luxons.sevenwonders.game.boards.Board; - -public class GoldIncrease extends InstantOwnBoardEffect { - - private final int amount; - - public GoldIncrease(int amount) { - this.amount = amount; - } - - public int getAmount() { - return amount; - } - - @Override - public void apply(Board board) { - board.addGold(amount); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - GoldIncrease that = (GoldIncrease) o; - return amount == that.amount; - } - - @Override - public int hashCode() { - return Objects.hash(amount); - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/effects/InstantOwnBoardEffect.java b/backend/src/main/java/org/luxons/sevenwonders/game/effects/InstantOwnBoardEffect.java deleted file mode 100644 index 8f4340cf..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/effects/InstantOwnBoardEffect.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; - -public abstract class InstantOwnBoardEffect implements Effect { - - @Override - public void apply(Table table, int playerIndex) { - apply(table.getBoard(playerIndex)); - } - - protected abstract void apply(Board board); - - @Override - public int computePoints(Table table, int playerIndex) { - // InstantEffects are only important when applied to the board, they don't give extra points in the end - return 0; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/effects/MilitaryReinforcements.java b/backend/src/main/java/org/luxons/sevenwonders/game/effects/MilitaryReinforcements.java deleted file mode 100644 index 7da112f5..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/effects/MilitaryReinforcements.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import java.util.Objects; - -import org.luxons.sevenwonders.game.boards.Board; - -public class MilitaryReinforcements extends InstantOwnBoardEffect { - - private final int count; - - public MilitaryReinforcements(int count) { - this.count = count; - } - - public int getCount() { - return count; - } - - @Override - public void apply(Board board) { - board.getMilitary().addShields(count); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - MilitaryReinforcements that = (MilitaryReinforcements) o; - return count == that.count; - } - - @Override - public int hashCode() { - return Objects.hash(count); - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/effects/ProductionIncrease.java b/backend/src/main/java/org/luxons/sevenwonders/game/effects/ProductionIncrease.java deleted file mode 100644 index 514c65db..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/effects/ProductionIncrease.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import java.util.Objects; - -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.resources.Production; - -public class ProductionIncrease extends InstantOwnBoardEffect { - - private Production production = new Production(); - - private boolean sellable = true; - - public Production getProduction() { - return production; - } - - public void setProduction(Production production) { - this.production = production; - } - - public boolean isSellable() { - return sellable; - } - - public void setSellable(boolean sellable) { - this.sellable = sellable; - } - - @Override - public void apply(Board board) { - board.getProduction().addAll(production); - if (sellable) { - board.getPublicProduction().addAll(production); - } - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ProductionIncrease that = (ProductionIncrease) o; - return Objects.equals(production, that.production); - } - - @Override - public int hashCode() { - return Objects.hash(production); - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/effects/RawPointsIncrease.java b/backend/src/main/java/org/luxons/sevenwonders/game/effects/RawPointsIncrease.java deleted file mode 100644 index 9a5d66ed..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/effects/RawPointsIncrease.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import java.util.Objects; - -import org.luxons.sevenwonders.game.api.Table; - -public class RawPointsIncrease extends EndGameEffect { - - private final int points; - - public RawPointsIncrease(int points) { - this.points = points; - } - - public int getPoints() { - return points; - } - - @Override - public int computePoints(Table table, int playerIndex) { - return points; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - RawPointsIncrease that = (RawPointsIncrease) o; - return points == that.points; - } - - @Override - public int hashCode() { - return Objects.hash(points); - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/effects/ScienceProgress.java b/backend/src/main/java/org/luxons/sevenwonders/game/effects/ScienceProgress.java deleted file mode 100644 index 4e6764ee..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/effects/ScienceProgress.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.boards.Science; - -public class ScienceProgress extends InstantOwnBoardEffect { - - private Science science; - - public Science getScience() { - return science; - } - - public void setScience(Science science) { - this.science = science; - } - - @Override - public void apply(Board board) { - board.getScience().addAll(science); - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/effects/SpecialAbility.java b/backend/src/main/java/org/luxons/sevenwonders/game/effects/SpecialAbility.java deleted file mode 100644 index cdf67f20..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/effects/SpecialAbility.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.cards.Card; - -public enum SpecialAbility { - - /** - * The player can play the last card of each age instead of discarding it. This card can be played by paying its - * cost, discarded to gain 3 coins or used in the construction of his or her Wonder. - */ - PLAY_LAST_CARD, - - /** - * Once per age, a player can construct a building from his or her hand for free. - */ - ONE_FREE_PER_AGE, - - /** - * The player can look at all cards discarded since the beginning of the game, pick one and build it for free. - */ - PLAY_DISCARDED, - - /** - * The player can, at the end of the game, "copy" a Guild of his or her choice (purple card), built by one of his or - * her two neighboring cities. - */ - COPY_GUILD { - @Override - public int computePoints(Table table, int playerIndex) { - Card copiedGuild = table.getBoard(playerIndex).getCopiedGuild(); - if (copiedGuild == null) { - throw new IllegalStateException("The copied Guild has not been chosen, cannot compute points"); - } - return copiedGuild.getEffects().stream().mapToInt(e -> e.computePoints(table, playerIndex)).sum(); - } - }; - - protected void apply(Board board) { - board.addSpecial(this); - } - - public int computePoints(Table table, int playerIndex) { - return 0; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/effects/SpecialAbilityActivation.java b/backend/src/main/java/org/luxons/sevenwonders/game/effects/SpecialAbilityActivation.java deleted file mode 100644 index a5953c2f..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/effects/SpecialAbilityActivation.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.luxons.sevenwonders.game.effects; - -import org.luxons.sevenwonders.game.api.Table; - -public class SpecialAbilityActivation implements Effect { - - private final SpecialAbility specialAbility; - - public SpecialAbilityActivation(SpecialAbility specialAbility) { - this.specialAbility = specialAbility; - } - - public SpecialAbility getSpecialAbility() { - return specialAbility; - } - - @Override - public void apply(Table table, int playerIndex) { - specialAbility.apply(table.getBoard(playerIndex)); - } - - @Override - public int computePoints(Table table, int playerIndex) { - return specialAbility.computePoints(table, playerIndex); - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/moves/BuildWonderMove.java b/backend/src/main/java/org/luxons/sevenwonders/game/moves/BuildWonderMove.java deleted file mode 100644 index f1cb50b3..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/moves/BuildWonderMove.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.luxons.sevenwonders.game.moves; - -import java.util.List; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.api.PlayerMove; -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.cards.Card; - -public class BuildWonderMove extends CardFromHandMove { - - BuildWonderMove(int playerIndex, Card card, PlayerMove move) { - super(playerIndex, card, move); - } - - @Override - public void validate(Table table, List<Card> playerHand) throws InvalidMoveException { - super.validate(table, playerHand); - Board board = table.getBoard(getPlayerIndex()); - if (!board.getWonder().isNextStageBuildable(table, getPlayerIndex(), getBoughtResources())) { - throw new InvalidMoveException( - String.format("Player %d cannot upgrade his wonder with the given resources", getPlayerIndex())); - } - } - - @Override - public void place(Table table, List<Card> discardedCards, Settings settings) { - Board board = table.getBoard(getPlayerIndex()); - board.getWonder().buildLevel(getCard().getBack()); - } - - @Override - public void activate(Table table, List<Card> discardedCards, Settings settings) { - int playerIndex = getPlayerIndex(); - Board board = table.getBoard(playerIndex); - board.getWonder().activateLastBuiltStage(table, playerIndex, getBoughtResources()); - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/moves/CardFromHandMove.java b/backend/src/main/java/org/luxons/sevenwonders/game/moves/CardFromHandMove.java deleted file mode 100644 index 1794966d..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/moves/CardFromHandMove.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.luxons.sevenwonders.game.moves; - -import java.util.List; - -import org.luxons.sevenwonders.game.api.PlayerMove; -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.cards.Card; - -public abstract class CardFromHandMove extends Move { - - CardFromHandMove(int playerIndex, Card card, PlayerMove move) { - super(playerIndex, card, move); - } - - @Override - public void validate(Table table, List<Card> playerHand) throws InvalidMoveException { - if (!playerHand.contains(getCard())) { - throw new InvalidMoveException( - String.format("Player %d does not have the card '%s' in his hand", getPlayerIndex(), - getCard().getName())); - } - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/moves/CopyGuildMove.java b/backend/src/main/java/org/luxons/sevenwonders/game/moves/CopyGuildMove.java deleted file mode 100644 index a93670c5..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/moves/CopyGuildMove.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.luxons.sevenwonders.game.moves; - -import java.util.List; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.api.PlayerMove; -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.boards.RelativeBoardPosition; -import org.luxons.sevenwonders.game.cards.Card; -import org.luxons.sevenwonders.game.cards.Color; -import org.luxons.sevenwonders.game.effects.SpecialAbility; - -public class CopyGuildMove extends Move { - - CopyGuildMove(int playerIndex, Card card, PlayerMove move) { - super(playerIndex, card, move); - } - - @Override - public void validate(Table table, List<Card> playerHand) throws InvalidMoveException { - Board board = table.getBoard(getPlayerIndex()); - if (!board.hasSpecial(SpecialAbility.COPY_GUILD)) { - throw new InvalidMoveException( - String.format("Player %d does not have the ability to copy guild cards", getPlayerIndex())); - } - if (getCard().getColor() != Color.PURPLE) { - throw new InvalidMoveException( - String.format("Player %d cannot copy card %s because it is not a guild card", getPlayerIndex(), - getCard().getName())); - } - boolean leftNeighbourHasIt = neighbourHasTheCard(table, RelativeBoardPosition.LEFT); - boolean rightNeighbourHasIt = neighbourHasTheCard(table, RelativeBoardPosition.RIGHT); - if (!leftNeighbourHasIt && !rightNeighbourHasIt) { - throw new InvalidMoveException( - String.format("Player %d cannot copy card %s because none of his neighbour has it", - getPlayerIndex(), getCard().getName())); - } - } - - private boolean neighbourHasTheCard(Table table, RelativeBoardPosition position) { - Board neighbourBoard = table.getBoard(getPlayerIndex(), position); - return neighbourBoard.getPlayedCards().contains(getCard()); - } - - @Override - public void place(Table table, List<Card> discardedCards, Settings settings) { - // nothing special to do here - } - - @Override - public void activate(Table table, List<Card> discardedCards, Settings settings) { - Board board = table.getBoard(getPlayerIndex()); - board.setCopiedGuild(getCard()); - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/moves/DiscardMove.java b/backend/src/main/java/org/luxons/sevenwonders/game/moves/DiscardMove.java deleted file mode 100644 index 076a593c..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/moves/DiscardMove.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.luxons.sevenwonders.game.moves; - -import java.util.List; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.api.PlayerMove; -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.cards.Card; - -public class DiscardMove extends CardFromHandMove { - - DiscardMove(int playerIndex, Card card, PlayerMove move) { - super(playerIndex, card, move); - } - - @Override - public void place(Table table, List<Card> discardedCards, Settings settings) { - discardedCards.add(getCard()); - } - - @Override - public void activate(Table table, List<Card> discardedCards, Settings settings) { - Board board = table.getBoard(getPlayerIndex()); - board.addGold(settings.getDiscardedCardGold()); - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/moves/InvalidMoveException.java b/backend/src/main/java/org/luxons/sevenwonders/game/moves/InvalidMoveException.java deleted file mode 100644 index 58190274..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/moves/InvalidMoveException.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.luxons.sevenwonders.game.moves; - -public class InvalidMoveException extends IllegalArgumentException { - - public InvalidMoveException(String message) { - super(message); - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/moves/Move.java b/backend/src/main/java/org/luxons/sevenwonders/game/moves/Move.java deleted file mode 100644 index 40c61eea..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/moves/Move.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.luxons.sevenwonders.game.moves; - -import java.util.ArrayList; -import java.util.List; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.api.PlayerMove; -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.cards.Card; -import org.luxons.sevenwonders.game.resources.BoughtResources; - -public abstract class Move { - - private int playerIndex; - - private Card card; - - private MoveType type; - - private List<BoughtResources> boughtResources = new ArrayList<>(); - - Move(int playerIndex, Card card, PlayerMove move) { - this.playerIndex = playerIndex; - this.card = card; - this.type = move.getType(); - this.boughtResources = move.getBoughtResources(); - } - - public int getPlayerIndex() { - return playerIndex; - } - - public Card getCard() { - return card; - } - - public MoveType getType() { - return type; - } - - public List<BoughtResources> getBoughtResources() { - return boughtResources; - } - - public abstract void validate(Table table, List<Card> playerHand) throws InvalidMoveException; - - public abstract void place(Table table, List<Card> discardedCards, Settings settings); - - public abstract void activate(Table table, List<Card> discardedCards, Settings settings); -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/moves/MoveType.java b/backend/src/main/java/org/luxons/sevenwonders/game/moves/MoveType.java deleted file mode 100644 index bf64344d..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/moves/MoveType.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.luxons.sevenwonders.game.moves; - -import org.luxons.sevenwonders.game.api.PlayerMove; -import org.luxons.sevenwonders.game.cards.Card; - -public enum MoveType { - PLAY { - @Override - public Move resolve(int playerIndex, Card card, PlayerMove move) { - return new PlayCardMove(playerIndex, card, move); - } - }, - PLAY_FREE { - @Override - public Move resolve(int playerIndex, Card card, PlayerMove move) { - return new PlayFreeCardMove(playerIndex, card, move); - } - }, - UPGRADE_WONDER { - @Override - public Move resolve(int playerIndex, Card card, PlayerMove move) { - return new BuildWonderMove(playerIndex, card, move); - } - }, - DISCARD { - @Override - public Move resolve(int playerIndex, Card card, PlayerMove move) { - return new DiscardMove(playerIndex, card, move); - } - }, - COPY_GUILD { - @Override - public Move resolve(int playerIndex, Card card, PlayerMove move) { - return new CopyGuildMove(playerIndex, card, move); - } - }; - - public abstract Move resolve(int playerIndex, Card card, PlayerMove move); -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/moves/PlayCardMove.java b/backend/src/main/java/org/luxons/sevenwonders/game/moves/PlayCardMove.java deleted file mode 100644 index 82052981..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/moves/PlayCardMove.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.luxons.sevenwonders.game.moves; - -import java.util.List; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.api.PlayerMove; -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.cards.Card; - -public class PlayCardMove extends CardFromHandMove { - - PlayCardMove(int playerIndex, Card card, PlayerMove move) { - super(playerIndex, card, move); - } - - @Override - public void validate(Table table, List<Card> playerHand) throws InvalidMoveException { - super.validate(table, playerHand); - Board board = table.getBoard(getPlayerIndex()); - if (!getCard().isChainableOn(board) && !getCard().getRequirements() - .areMetWithHelpBy(board, getBoughtResources())) { - throw new InvalidMoveException( - String.format("Player %d cannot play the card %s with the given resources", getPlayerIndex(), - getCard().getName())); - } - } - - @Override - public void place(Table table, List<Card> discardedCards, Settings settings) { - Board board = table.getBoard(getPlayerIndex()); - board.addCard(getCard()); - } - - @Override - public void activate(Table table, List<Card> discardedCards, Settings settings) { - getCard().applyTo(table, getPlayerIndex(), getBoughtResources()); - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/moves/PlayFreeCardMove.java b/backend/src/main/java/org/luxons/sevenwonders/game/moves/PlayFreeCardMove.java deleted file mode 100644 index 4e8eefa5..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/moves/PlayFreeCardMove.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.luxons.sevenwonders.game.moves; - -import java.util.List; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.api.PlayerMove; -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.cards.Card; - -public class PlayFreeCardMove extends CardFromHandMove { - - PlayFreeCardMove(int playerIndex, Card card, PlayerMove move) { - super(playerIndex, card, move); - } - - @Override - public void validate(Table table, List<Card> playerHand) throws InvalidMoveException { - super.validate(table, playerHand); - Board board = table.getBoard(getPlayerIndex()); - if (!board.canPlayFreeCard(table.getCurrentAge())) { - throw new InvalidMoveException( - String.format("Player %d cannot play the card %s for free", getPlayerIndex(), getCard().getName())); - } - } - - @Override - public void place(Table table, List<Card> discardedCards, Settings settings) { - Board board = table.getBoard(getPlayerIndex()); - board.addCard(getCard()); - } - - @Override - public void activate(Table table, List<Card> discardedCards, Settings settings) { - // only apply effects, without paying the cost - getCard().getEffects().forEach(e -> e.apply(table, getPlayerIndex())); - Board board = table.getBoard(getPlayerIndex()); - board.consumeFreeCard(table.getCurrentAge()); - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/resources/BestPriceCalculator.java b/backend/src/main/java/org/luxons/sevenwonders/game/resources/BestPriceCalculator.java deleted file mode 100644 index 8fed41d1..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/resources/BestPriceCalculator.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.luxons.sevenwonders.game.resources; - -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.List; -import java.util.Set; - -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; - -public class BestPriceCalculator { - - private final Resources resources; - - private final List<ResourcePool> pools; - - private BestPriceCalculator(Resources resources, Table table, int playerIndex) { - this.resources = resources; - this.pools = createResourcePools(table, playerIndex); - } - - private static List<ResourcePool> createResourcePools(Table table, int playerIndex) { - Provider[] providers = Provider.values(); - List<ResourcePool> pools = new ArrayList<>(providers.length + 1); - - Board board = table.getBoard(playerIndex); - TradingRules rules = board.getTradingRules(); - pools.add(new ResourcePool(board.getProduction(), null, rules)); - - for (Provider provider : providers) { - Board providerBoard = table.getBoard(playerIndex, provider.getBoardPosition()); - ResourcePool pool = new ResourcePool(providerBoard.getPublicProduction(), provider, rules); - pools.add(pool); - } - return pools; - } - - public static int bestPrice(Resources resources, Table table, int playerIndex) { - Board board = table.getBoard(playerIndex); - Resources leftToPay = resources.minus(board.getProduction().getFixedResources()); - return new BestPriceCalculator(leftToPay, table, playerIndex).bestPrice(); - } - - private int bestPrice() { - if (resources.isEmpty()) { - return 0; - } - int currentMinPrice = Integer.MAX_VALUE; - for (ResourceType type : ResourceType.values()) { - if (resources.getQuantity(type) > 0) { - int minPriceUsingOwnResource = bestPriceWithout(type); - currentMinPrice = Math.min(currentMinPrice, minPriceUsingOwnResource); - } - } - return currentMinPrice; - } - - private int bestPriceWithout(ResourceType type) { - resources.remove(type, 1); - int currentMinPrice = Integer.MAX_VALUE; - for (ResourcePool pool : pools) { - int resCostInPool = pool.getCost(type); - for (Set<ResourceType> choice : pool.getChoices()) { - if (choice.contains(type)) { - Set<ResourceType> temp = EnumSet.copyOf(choice); - choice.clear(); - currentMinPrice = Math.min(currentMinPrice, bestPrice() + resCostInPool); - choice.addAll(temp); - } - } - } - resources.add(type, 1); - return currentMinPrice; - } - - private static class ResourcePool { - - private final Set<Set<ResourceType>> choices; - - private final Provider provider; - - private final TradingRules rules; - - private ResourcePool(Production production, Provider provider, TradingRules rules) { - this.choices = production.asChoices(); - this.provider = provider; - this.rules = rules; - } - - Set<Set<ResourceType>> getChoices() { - return choices; - } - - int getCost(ResourceType type) { - if (provider == null) { - return 0; - } - return rules.getCost(type, provider); - } - } -} - diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/resources/BoughtResources.java b/backend/src/main/java/org/luxons/sevenwonders/game/resources/BoughtResources.java deleted file mode 100644 index ec261c8c..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/resources/BoughtResources.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.luxons.sevenwonders.game.resources; - -public class BoughtResources { - - private Provider provider; - - private Resources resources; - - public Provider getProvider() { - return provider; - } - - public void setProvider(Provider provider) { - this.provider = provider; - } - - public Resources getResources() { - return resources; - } - - public void setResources(Resources resources) { - this.resources = resources; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/resources/Production.java b/backend/src/main/java/org/luxons/sevenwonders/game/resources/Production.java deleted file mode 100644 index 7fa83e51..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/resources/Production.java +++ /dev/null @@ -1,106 +0,0 @@ -package org.luxons.sevenwonders.game.resources; - -import java.util.Arrays; -import java.util.EnumSet; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; - -public class Production { - - private final Resources fixedResources = new Resources(); - - private final Set<Set<ResourceType>> alternativeResources = new HashSet<>(); - - public void addFixedResource(ResourceType type, int quantity) { - fixedResources.add(type, quantity); - } - - public void addChoice(ResourceType... options) { - EnumSet<ResourceType> optionSet = EnumSet.copyOf(Arrays.asList(options)); - alternativeResources.add(optionSet); - } - - public void addAll(Resources resources) { - fixedResources.addAll(resources); - } - - public void addAll(Production production) { - fixedResources.addAll(production.getFixedResources()); - alternativeResources.addAll(production.getAlternativeResources()); - } - - public Resources getFixedResources() { - return fixedResources; - } - - public Set<Set<ResourceType>> getAlternativeResources() { - return alternativeResources; - } - - Set<Set<ResourceType>> asChoices() { - Set<Set<ResourceType>> result = new HashSet<>(fixedResources.size() + alternativeResources.size()); - fixedResources.asList().stream().map(EnumSet::of).forEach(result::add); - result.addAll(alternativeResources); - return result; - } - - public boolean contains(Resources resources) { - if (fixedResources.contains(resources)) { - return true; - } - Resources remaining = resources.minus(fixedResources); - return containedInAlternatives(remaining); - } - - private boolean containedInAlternatives(Resources resources) { - return containedInAlternatives(resources, alternativeResources); - } - - private static boolean containedInAlternatives(Resources resources, Set<Set<ResourceType>> alternatives) { - if (resources.isEmpty()) { - return true; - } - for (ResourceType type : ResourceType.values()) { - if (resources.getQuantity(type) <= 0) { - continue; - } - Set<ResourceType> candidate = findFirstAlternativeContaining(alternatives, type); - if (candidate == null) { - return false; // no alternative produces the resource of this entry - } - resources.remove(type, 1); - alternatives.remove(candidate); - boolean remainingAreContainedToo = containedInAlternatives(resources, alternatives); - resources.add(type, 1); - alternatives.add(candidate); - if (remainingAreContainedToo) { - return true; - } - } - return false; - } - - private static Set<ResourceType> findFirstAlternativeContaining(Set<Set<ResourceType>> alternatives, - ResourceType type) { - return alternatives.stream().filter(a -> a.contains(type)).findAny().orElse(null); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Production that = (Production) o; - return Objects.equals(fixedResources, that.fixedResources) && Objects.equals(alternativeResources, - that.alternativeResources); - } - - @Override - public int hashCode() { - return Objects.hash(fixedResources, alternativeResources); - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/resources/Provider.java b/backend/src/main/java/org/luxons/sevenwonders/game/resources/Provider.java deleted file mode 100644 index 9c4aa3f9..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/resources/Provider.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.luxons.sevenwonders.game.resources; - -import org.luxons.sevenwonders.game.boards.RelativeBoardPosition; - -public enum Provider { - LEFT_PLAYER(RelativeBoardPosition.LEFT), - RIGHT_PLAYER(RelativeBoardPosition.RIGHT); - - private final RelativeBoardPosition boardPosition; - - Provider(RelativeBoardPosition boardPosition) { - this.boardPosition = boardPosition; - } - - public RelativeBoardPosition getBoardPosition() { - return boardPosition; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/resources/ResourceType.java b/backend/src/main/java/org/luxons/sevenwonders/game/resources/ResourceType.java deleted file mode 100644 index baad8451..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/resources/ResourceType.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.luxons.sevenwonders.game.resources; - -import java.util.HashMap; -import java.util.Map; - -public enum ResourceType { - WOOD('W'), - STONE('S'), - ORE('O'), - CLAY('C'), - GLASS('G'), - PAPYRUS('P'), - LOOM('L'); - - private static final Map<Character, ResourceType> typesPerSymbol = new HashMap<>(7); - - static { - for (ResourceType type : values()) { - typesPerSymbol.put(type.symbol, type); - } - } - - private final Character symbol; - - ResourceType(Character symbol) { - this.symbol = symbol; - } - - public static ResourceType fromSymbol(Character symbol) { - ResourceType type = typesPerSymbol.get(symbol); - if (type == null) { - throw new IllegalArgumentException(String.format("Unknown resource type symbol '%s'", symbol)); - } - return type; - } - - public Character getSymbol() { - return symbol; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/resources/Resources.java b/backend/src/main/java/org/luxons/sevenwonders/game/resources/Resources.java deleted file mode 100644 index 04278fea..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/resources/Resources.java +++ /dev/null @@ -1,91 +0,0 @@ -package org.luxons.sevenwonders.game.resources; - -import java.util.EnumMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.NoSuchElementException; -import java.util.Objects; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public class Resources { - - private final Map<ResourceType, Integer> quantities = new EnumMap<>(ResourceType.class); - - public void add(ResourceType type, int quantity) { - quantities.merge(type, quantity, (x, y) -> x + y); - } - - public void remove(ResourceType type, int quantity) { - if (getQuantity(type) < quantity) { - throw new NoSuchElementException(String.format("Can't remove %d resources of type %s", quantity, type)); - } - quantities.computeIfPresent(type, (t, oldQty) -> oldQty - quantity); - } - - public void addAll(Resources resources) { - resources.quantities.forEach(this::add); - } - - public int getQuantity(ResourceType type) { - return quantities.getOrDefault(type, 0); - } - - public List<ResourceType> asList() { - return quantities.entrySet() - .stream() - .flatMap(e -> Stream.generate(e::getKey).limit(e.getValue())) - .collect(Collectors.toList()); - } - - public boolean contains(Resources resources) { - return resources.quantities.entrySet().stream().allMatch(this::hasAtLeast); - } - - private boolean hasAtLeast(Entry<ResourceType, Integer> quantity) { - return quantity.getValue() <= getQuantity(quantity.getKey()); - } - - /** - * Creates new {@link Resources} object containing these resources minus the given resources. - * - * @param resources - * the resources to subtract from these resources - * - * @return a new {@link Resources} object containing these resources minus the given resources. - */ - public Resources minus(Resources resources) { - Resources diff = new Resources(); - quantities.forEach((type, count) -> { - int remainder = count - resources.getQuantity(type); - diff.quantities.put(type, Math.max(0, remainder)); - }); - return diff; - } - - public boolean isEmpty() { - return size() == 0; - } - - public int size() { - return quantities.values().stream().reduce(0, Integer::sum); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Resources resources = (Resources) o; - return Objects.equals(quantities, resources.quantities); - } - - @Override - public int hashCode() { - return Objects.hash(quantities); - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/resources/TradingRules.java b/backend/src/main/java/org/luxons/sevenwonders/game/resources/TradingRules.java deleted file mode 100644 index 8cd1d9bc..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/resources/TradingRules.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.luxons.sevenwonders.game.resources; - -import java.util.EnumMap; -import java.util.List; -import java.util.Map; - -public class TradingRules { - - private final Map<ResourceType, Map<Provider, Integer>> costs = new EnumMap<>(ResourceType.class); - - private final int defaultCost; - - public TradingRules(int defaultCost) { - this.defaultCost = defaultCost; - } - - public Map<ResourceType, Map<Provider, Integer>> getCosts() { - return costs; - } - - int getCost(ResourceType type, Provider provider) { - return costs.computeIfAbsent(type, t -> new EnumMap<>(Provider.class)).getOrDefault(provider, defaultCost); - } - - public void setCost(ResourceType type, Provider provider, int cost) { - costs.computeIfAbsent(type, t -> new EnumMap<>(Provider.class)).put(provider, cost); - } - - public int computeCost(List<BoughtResources> boughtResources) { - return boughtResources.stream().mapToInt(this::computeCost).sum(); - } - - public int computeCost(BoughtResources boughtResources) { - Resources resources = boughtResources.getResources(); - Provider provider = boughtResources.getProvider(); - int total = 0; - for (ResourceType type : ResourceType.values()) { - int count = resources.getQuantity(type); - total += getCost(type, provider) * count; - } - return total; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/scoring/PlayerScore.java b/backend/src/main/java/org/luxons/sevenwonders/game/scoring/PlayerScore.java deleted file mode 100644 index f4a0d832..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/scoring/PlayerScore.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.luxons.sevenwonders.game.scoring; - -import java.util.HashMap; -import java.util.Map; - -public class PlayerScore { - - private final int boardGold; - - private final Map<ScoreCategory, Integer> scoresByCategory = new HashMap<>(); - - private int totalPoints = 0; - - public PlayerScore(int boardGold) { - this.boardGold = boardGold; - } - - public Integer put(ScoreCategory category, Integer points) { - totalPoints += points; - return scoresByCategory.put(category, points); - } - - public int getPoints(ScoreCategory category) { - return scoresByCategory.get(category); - } - - public Map<ScoreCategory, Integer> getPointsPerCategory() { - return scoresByCategory; - } - - public int getTotalPoints() { - return totalPoints; - } - - public int getBoardGold() { - return boardGold; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/scoring/ScoreBoard.java b/backend/src/main/java/org/luxons/sevenwonders/game/scoring/ScoreBoard.java deleted file mode 100644 index e7cdaedd..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/scoring/ScoreBoard.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.luxons.sevenwonders.game.scoring; - -import java.util.Comparator; -import java.util.PriorityQueue; - -public class ScoreBoard { - - private static final Comparator<PlayerScore> comparator = Comparator.comparing(PlayerScore::getTotalPoints) - .thenComparing(PlayerScore::getBoardGold); - - private PriorityQueue<PlayerScore> scores; - - public ScoreBoard() { - scores = new PriorityQueue<>(comparator); - } - - public void add(PlayerScore score) { - scores.add(score); - } - - public PriorityQueue<PlayerScore> getScores() { - return scores; - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/scoring/ScoreCategory.java b/backend/src/main/java/org/luxons/sevenwonders/game/scoring/ScoreCategory.java deleted file mode 100644 index a6a9537d..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/scoring/ScoreCategory.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.luxons.sevenwonders.game.scoring; - -public enum ScoreCategory { - CIVIL, - SCIENCE, - MILITARY, - TRADE, - GUILD, - WONDER, - GOLD -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/wonders/Wonder.java b/backend/src/main/java/org/luxons/sevenwonders/game/wonders/Wonder.java deleted file mode 100644 index 73fff305..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/wonders/Wonder.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.luxons.sevenwonders.game.wonders; - -import java.util.Arrays; -import java.util.List; - -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.cards.CardBack; -import org.luxons.sevenwonders.game.resources.BoughtResources; -import org.luxons.sevenwonders.game.resources.ResourceType; - -public class Wonder { - - private String name; - - private ResourceType initialResource; - - private List<WonderStage> stages; - - private String image; - - public Wonder() { - } - - public Wonder(String name, ResourceType initialResource, WonderStage... stages) { - this.name = name; - this.initialResource = initialResource; - this.stages = Arrays.asList(stages); - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public ResourceType getInitialResource() { - return initialResource; - } - - public void setInitialResource(ResourceType initialResource) { - this.initialResource = initialResource; - } - - public List<WonderStage> getStages() { - return stages; - } - - public void setStages(List<WonderStage> stages) { - this.stages = stages; - } - - public int getNbBuiltStages() { - return (int) stages.stream().filter(WonderStage::isBuilt).count(); - } - - public String getImage() { - return image; - } - - public void setImage(String image) { - this.image = image; - } - - public boolean isNextStageBuildable(Table table, int playerIndex, List<BoughtResources> boughtResources) { - int nextLevel = getNbBuiltStages(); - if (nextLevel == stages.size()) { - return false; - } - return getNextStage().isBuildable(table, playerIndex, boughtResources); - } - - public void buildLevel(CardBack cardBack) { - getNextStage().build(cardBack); - } - - private WonderStage getNextStage() { - int nextLevel = getNbBuiltStages(); - if (nextLevel == stages.size()) { - throw new IllegalStateException("This wonder has already reached its maximum level"); - } - return stages.get(nextLevel); - } - - public void activateLastBuiltStage(Table table, int playerIndex, List<BoughtResources> boughtResources) { - getLastBuiltStage().activate(table, playerIndex, boughtResources); - } - - private WonderStage getLastBuiltStage() { - int lastLevel = getNbBuiltStages() - 1; - return stages.get(lastLevel); - } - - public int computePoints(Table table, int playerIndex) { - return stages.stream() - .filter(WonderStage::isBuilt) - .flatMap(c -> c.getEffects().stream()) - .mapToInt(e -> e.computePoints(table, playerIndex)) - .sum(); - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/game/wonders/WonderStage.java b/backend/src/main/java/org/luxons/sevenwonders/game/wonders/WonderStage.java deleted file mode 100644 index 5f6765ee..00000000 --- a/backend/src/main/java/org/luxons/sevenwonders/game/wonders/WonderStage.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.luxons.sevenwonders.game.wonders; - -import java.util.List; - -import org.luxons.sevenwonders.game.api.Table; -import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.cards.CardBack; -import org.luxons.sevenwonders.game.cards.Requirements; -import org.luxons.sevenwonders.game.effects.Effect; -import org.luxons.sevenwonders.game.resources.BoughtResources; - -public class WonderStage { - - private Requirements requirements; - - private List<Effect> effects; - - private CardBack cardBack; - - public Requirements getRequirements() { - return requirements; - } - - public void setRequirements(Requirements requirements) { - this.requirements = requirements; - } - - public List<Effect> getEffects() { - return effects; - } - - public void setEffects(List<Effect> effects) { - this.effects = effects; - } - - public CardBack getCardBack() { - return cardBack; - } - - public boolean isBuilt() { - return cardBack != null; - } - - public boolean isBuildable(Table table, int playerIndex, List<BoughtResources> boughtResources) { - Board board = table.getBoard(playerIndex); - return requirements.areMetWithHelpBy(board, boughtResources); - } - - void build(CardBack cardBack) { - this.cardBack = cardBack; - } - - void activate(Table table, int playerIndex, List<BoughtResources> boughtResources) { - effects.forEach(e -> e.apply(table, playerIndex)); - } -} diff --git a/backend/src/main/java/org/luxons/sevenwonders/repositories/LobbyRepository.java b/backend/src/main/java/org/luxons/sevenwonders/repositories/LobbyRepository.java index eb573479..b1b11c82 100644 --- a/backend/src/main/java/org/luxons/sevenwonders/repositories/LobbyRepository.java +++ b/backend/src/main/java/org/luxons/sevenwonders/repositories/LobbyRepository.java @@ -20,8 +20,8 @@ public class LobbyRepository { private long lastGameId = 0; @Autowired - public LobbyRepository(GameDefinitionLoader gameDefinitionLoader) { - this.gameDefinitionLoader = gameDefinitionLoader; + public LobbyRepository() { + this.gameDefinitionLoader = new GameDefinitionLoader(); } public Collection<Lobby> list() { diff --git a/backend/src/main/resources/org/luxons/sevenwonders/game/data/cards.json b/backend/src/main/resources/org/luxons/sevenwonders/game/data/cards.json deleted file mode 100644 index 83777d9e..00000000 --- a/backend/src/main/resources/org/luxons/sevenwonders/game/data/cards.json +++ /dev/null @@ -1,1719 +0,0 @@ -{ - "age1Back": "age1.png", - "age2Back": "age2.png", - "age3Back": "age3.png", - "age1": [ - { - "name": "Clay Pit", - "color": "BROWN", - "effect": { - "production": "O/C" - }, - "requirements": { - "gold": 1 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 1, - "7": 1 - }, - "image": "claypit.png" - }, - { - "name": "Clay Pool", - "color": "BROWN", - "effect": { - "production": "C" - }, - "requirements": { - "gold": 0 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "claypool.png" - }, - { - "name": "Excavation", - "color": "BROWN", - "effect": { - "production": "S/C" - }, - "requirements": { - "gold": 1 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 0, - "4": 1, - "5": 1, - "6": 1, - "7": 1 - }, - "image": "excavation.png" - }, - { - "name": "Forest Cave", - "color": "BROWN", - "effect": { - "production": "W/O" - }, - "requirements": { - "gold": 1 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 0, - "4": 0, - "5": 1, - "6": 1, - "7": 1 - }, - "image": "forestcave.png" - }, - { - "name": "Lumber Yard", - "color": "BROWN", - "effect": { - "production": "W" - }, - "requirements": { - "gold": 0 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 2, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "lumberyard.png" - }, - { - "name": "Mine", - "color": "BROWN", - "effect": { - "production": "S/O" - }, - "requirements": { - "gold": 1 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 0, - "4": 0, - "5": 0, - "6": 1, - "7": 1 - }, - "image": "mine.png" - }, - { - "name": "Ore Vein", - "color": "BROWN", - "effect": { - "production": "O" - }, - "requirements": { - "gold": 0 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 2, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "orevein.png" - }, - { - "name": "Stone Pit", - "color": "BROWN", - "effect": { - "production": "S" - }, - "requirements": { - "gold": 0 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "stonepit.png" - }, - { - "name": "Timber Yard", - "color": "BROWN", - "effect": { - "production": "W/S" - }, - "requirements": { - "gold": 1 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 1, - "7": 1 - }, - "image": "timberyard.png" - }, - { - "name": "Tree Farm", - "color": "BROWN", - "effect": { - "production": "W/C" - }, - "requirements": { - "gold": 1 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 0, - "4": 0, - "5": 0, - "6": 1, - "7": 1 - }, - "image": "treefarm.png" - }, - { - "name": "Glassworks", - "color": "GREY", - "effect": { - "production": "G" - }, - "requirements": { - "gold": 0 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 2, - "7": 2 - }, - "image": "glassworks.png" - }, - { - "name": "Loom", - "color": "GREY", - "effect": { - "production": "L" - }, - "requirements": { - "gold": 0 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 2, - "7": 2 - }, - "image": "loom.png" - }, - { - "name": "Press", - "color": "GREY", - "effect": { - "production": "P" - }, - "requirements": { - "gold": 0 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 2, - "7": 2 - }, - "image": "press.png" - }, - { - "name": "East Trading Post", - "color": "YELLOW", - "effect": { - "discount": { - "resourceTypes": "CSOW", - "providers": [ - "RIGHT_PLAYER" - ], - "discountedPrice": 1 - } - }, - "requirements": { - "gold": 0 - }, - "chainChildren": [ - "Forum" - ], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 1, - "7": 2 - }, - "image": "easttradingpost.png" - }, - { - "name": "Marketplace", - "color": "YELLOW", - "effect": { - "discount": { - "resourceTypes": "LGP", - "providers": [ - "LEFT_PLAYER", - "RIGHT_PLAYER" - ], - "discountedPrice": 1 - } - }, - "requirements": { - "gold": 0 - }, - "chainChildren": [ - "Caravansery" - ], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 2, - "7": 2 - }, - "image": "marketplace.png" - }, - { - "name": "Tavern", - "color": "YELLOW", - "effect": { - "gold": 5 - }, - "requirements": { - "gold": 0 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 0, - "4": 1, - "5": 2, - "6": 2, - "7": 3 - }, - "image": "tavern.png" - }, - { - "name": "West Trading Post", - "color": "YELLOW", - "effect": { - "discount": { - "resourceTypes": "CSOW", - "providers": [ - "LEFT_PLAYER" - ], - "discountedPrice": 1 - } - }, - "requirements": { - "gold": 0 - }, - "chainChildren": [ - "Forum" - ], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 1, - "7": 2 - }, - "image": "westtradingpost.png" - }, - { - "name": "Altar", - "color": "BLUE", - "effect": { - "points": 2 - }, - "requirements": { - "gold": 0 - }, - "chainChildren": [ - "Temple" - ], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "altar.png" - }, - { - "name": "Baths", - "color": "BLUE", - "effect": { - "points": 3 - }, - "requirements": { - "gold": 0, - "resources": "S" - }, - "chainChildren": [ - "Aquaduct" - ], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 1, - "7": 2 - }, - "image": "baths.png" - }, - { - "name": "Pawnshop", - "color": "BLUE", - "effect": { - "points": 3 - }, - "requirements": { - "gold": 0 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 0, - "4": 1, - "5": 1, - "6": 1, - "7": 2 - }, - "image": "pawnshop.png" - }, - { - "name": "Theater", - "color": "BLUE", - "effect": { - "points": 2 - }, - "requirements": { - "gold": 0 - }, - "chainChildren": [ - "Statue" - ], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 2, - "7": 2 - }, - "image": "theater.png" - }, - { - "name": "Apothecary", - "color": "GREEN", - "effect": { - "science": "COMPASS" - }, - "requirements": { - "gold": 0, - "resources": "L" - }, - "chainChildren": [ - "Stables", - "Dispensary" - ], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "apothecary.png" - }, - { - "name": "Scriptorium", - "color": "GREEN", - "effect": { - "science": "TABLET" - }, - "requirements": { - "gold": 0, - "resources": "P" - }, - "chainChildren": [ - "Courthouse", - "Library" - ], - "countPerNbPlayer": { - "3": 1, - "4": 2, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "scriptorium.png" - }, - { - "name": "Workshop", - "color": "GREEN", - "effect": { - "science": "WHEEL" - }, - "requirements": { - "gold": 0, - "resources": "G" - }, - "chainChildren": [ - "Archery Range", - "Laboratory" - ], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 1, - "7": 2 - }, - "image": "workshop.png" - }, - { - "name": "Barracks", - "color": "RED", - "effect": { - "military": 1 - }, - "requirements": { - "gold": 0, - "resources": "O" - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "barracks.png" - }, - { - "name": "Guard Tower", - "color": "RED", - "effect": { - "military": 1 - }, - "requirements": { - "gold": 0, - "resources": "C" - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 2, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "guardtower.png" - }, - { - "name": "Stockade", - "color": "RED", - "effect": { - "military": 1 - }, - "requirements": { - "gold": 0, - "resources": "W" - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 1, - "7": 2 - }, - "image": "stockade.png" - } - ], - "age2": [ - { - "name": "Brickyard", - "color": "BROWN", - "effect": { - "production": "CC" - }, - "requirements": { - "gold": 1 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 2, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "brickyard.png" - }, - { - "name": "Foundry", - "color": "BROWN", - "effect": { - "production": "OO" - }, - "requirements": { - "gold": 1 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 2, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "foundry.png" - }, - { - "name": "Quarry", - "color": "BROWN", - "effect": { - "production": "SS" - }, - "requirements": { - "gold": 1 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 2, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "quarry.png" - }, - { - "name": "Sawmill", - "color": "BROWN", - "effect": { - "production": "WW" - }, - "requirements": { - "gold": 1 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 2, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "sawmill.png" - }, - { - "name": "Glassworks", - "color": "GREY", - "effect": { - "production": "G" - }, - "requirements": { - "gold": 0 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "glassworks.png" - }, - { - "name": "Loom", - "color": "GREY", - "effect": { - "production": "L" - }, - "requirements": { - "gold": 0 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "loom.png" - }, - { - "name": "Press", - "color": "GREY", - "effect": { - "production": "P" - }, - "requirements": { - "gold": 0 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "press.png" - }, - { - "name": "Bazar", - "color": "YELLOW", - "effect": { - "perBoardElement": { - "boards": [ - "SELF", - "LEFT", - "RIGHT" - ], - "gold": 0, - "points": 2, - "type": "CARD", - "colors": [ - "GREY" - ] - } - }, - "requirements": { - "gold": 0 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 0, - "4": 1, - "5": 1, - "6": 1, - "7": 2 - }, - "image": "bazar.png" - }, - { - "name": "Caravansery", - "color": "YELLOW", - "effect": { - "production": "(W/S/O/C)" - }, - "requirements": { - "gold": 0, - "resources": "WW" - }, - "chainParent": "Marketplace", - "chainChildren": [ - "Lighthouse" - ], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 2, - "6": 3, - "7": 3 - }, - "image": "caravansery.png" - }, - { - "name": "Forum", - "color": "YELLOW", - "effect": { - "production": "(G/P/L)" - }, - "requirements": { - "gold": 0, - "resources": "CC" - }, - "chainParent": "East Trading Post", - "chainChildren": [ - "Haven" - ], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 2, - "7": 3 - }, - "image": "forum.png" - }, - { - "name": "Vineyard", - "color": "YELLOW", - "effect": { - "perBoardElement": { - "boards": [ - "SELF", - "LEFT", - "RIGHT" - ], - "gold": 0, - "points": 1, - "type": "CARD", - "colors": [ - "BROWN" - ] - } - }, - "requirements": { - "gold": 0 - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 2, - "7": 2 - }, - "image": "vineyard.png" - }, - { - "name": "Aqueduct", - "color": "BLUE", - "effect": { - "points": 5 - }, - "requirements": { - "gold": 0, - "resources": "SSS" - }, - "chainParent": "Baths", - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 1, - "7": 2 - }, - "image": "aqueduct.png" - }, - { - "name": "Courthouse", - "color": "BLUE", - "effect": { - "points": 4 - }, - "requirements": { - "gold": 0, - "resources": "CCL" - }, - "chainParent": "Scriptorium", - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "courthouse.png" - }, - { - "name": "Statue", - "color": "BLUE", - "effect": { - "points": 4 - }, - "requirements": { - "gold": 0, - "resources": "WOO" - }, - "chainParent": "Theater", - "chainChildren": [ - "Gardens" - ], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 1, - "7": 2 - }, - "image": "statue.png" - }, - { - "name": "Temple", - "color": "BLUE", - "effect": { - "points": 3 - }, - "requirements": { - "gold": 0, - "resources": "WCG" - }, - "chainParent": "Altar", - "chainChildren": [ - "Pantheon" - ], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 2, - "7": 2 - }, - "image": "temple.png" - }, - { - "name": "Dispensary", - "color": "GREEN", - "effect": { - "science": "COMPASS" - }, - "requirements": { - "gold": 0, - "resources": "OOG" - }, - "chainParent": "Apothecary", - "chainChildren": [ - "Arena", - "Lodge" - ], - "countPerNbPlayer": { - "3": 1, - "4": 2, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "dispensary.png" - }, - { - "name": "Laboratory", - "color": "GREEN", - "effect": { - "science": "WHEEL" - }, - "requirements": { - "gold": 0, - "resources": "CCP" - }, - "chainParent": "Workshop", - "chainChildren": [ - "Siege Workshop", - "Observatory" - ], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "laboratory.png" - }, - { - "name": "Library", - "color": "GREEN", - "effect": { - "science": "TABLET" - }, - "requirements": { - "gold": 0, - "resources": "SSL" - }, - "chainParent": "Scriptorium", - "chainChildren": [ - "Senate", - "University" - ], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 2, - "7": 2 - }, - "image": "library.png" - }, - { - "name": "School", - "color": "GREEN", - "effect": { - "science": "TABLET" - }, - "requirements": { - "gold": 0, - "resources": "WP" - }, - "chainChildren": [ - "Academy", - "Study" - ], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 1, - "7": 2 - }, - "image": "school.png" - }, - { - "name": "Archery Range", - "color": "RED", - "effect": { - "military": 2 - }, - "requirements": { - "gold": 0, - "resources": "WWO" - }, - "chainParent": "Workshop", - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 2, - "7": 2 - }, - "image": "archeryrange.png" - }, - { - "name": "Stables", - "color": "RED", - "effect": { - "military": 2 - }, - "requirements": { - "gold": 0, - "resources": "WOC" - }, - "chainParent": "Apothecary", - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "stables.png" - }, - { - "name": "Training Ground", - "color": "RED", - "effect": { - "military": 2 - }, - "requirements": { - "gold": 0, - "resources": "WOO" - }, - "chainChildren": [ - "Circus" - ], - "countPerNbPlayer": { - "3": 0, - "4": 1, - "5": 1, - "6": 2, - "7": 3 - }, - "image": "trainingground.png" - }, - { - "name": "Walls", - "color": "RED", - "effect": { - "military": 2 - }, - "requirements": { - "gold": 0, - "resources": "SSS" - }, - "chainChildren": [ - "Fortifications" - ], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 1, - "7": 2 - }, - "image": "walls.png" - } - ], - "age3": [ - { - "name": "Arena", - "color": "YELLOW", - "effect": { - "perBoardElement": { - "boards": [ - "SELF" - ], - "gold": 3, - "points": 1, - "type": "WONDER_LEVEL" - } - }, - "requirements": { - "gold": 0, - "resources": "SSO" - }, - "chainParent": "Dispensary", - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 2, - "6": 2, - "7": 3 - }, - "image": "arena.png" - }, - { - "name": "Chamber of Commerce", - "color": "YELLOW", - "effect": { - "perBoardElement": { - "boards": [ - "SELF" - ], - "gold": 2, - "points": 2, - "type": "CARD", - "colors": [ - "GREY" - ] - } - }, - "requirements": { - "gold": 0, - "resources": "CCP" - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 0, - "4": 1, - "5": 1, - "6": 2, - "7": 2 - }, - "image": "chamberofcommerce.png" - }, - { - "name": "Haven", - "color": "YELLOW", - "effect": { - "perBoardElement": { - "boards": [ - "SELF" - ], - "gold": 1, - "points": 1, - "type": "CARD", - "colors": [ - "BROWN" - ] - } - }, - "requirements": { - "gold": 0, - "resources": "WOL" - }, - "chainParent": "Forum", - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 2, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "haven.png" - }, - { - "name": "Lighthouse", - "color": "YELLOW", - "effect": { - "perBoardElement": { - "boards": [ - "SELF" - ], - "gold": 1, - "points": 1, - "type": "CARD", - "colors": [ - "GREY" - ] - } - }, - "requirements": { - "gold": 0, - "resources": "SG" - }, - "chainParent": "Caravansery", - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 2, - "7": 2 - }, - "image": "lighthouse.png" - }, - { - "name": "Gardens", - "color": "BLUE", - "effect": { - "points": 5 - }, - "requirements": { - "gold": 0, - "resources": "WCC" - }, - "chainParent": "Statue", - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 2, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "gardens.png" - }, - { - "name": "Palace", - "color": "BLUE", - "effect": { - "points": 8 - }, - "requirements": { - "gold": 0, - "resources": "WSOCGPL" - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 1, - "7": 2 - }, - "image": "palace.png" - }, - { - "name": "Pantheon", - "color": "BLUE", - "effect": { - "points": 7 - }, - "requirements": { - "gold": 0, - "resources": "OCCGPL" - }, - "chainParent": "Temple", - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 2, - "7": 2 - }, - "image": "pantheon.png" - }, - { - "name": "Senate", - "color": "BLUE", - "effect": { - "points": 6 - }, - "requirements": { - "gold": 0, - "resources": "WWSO" - }, - "chainParent": "Library", - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "senate.png" - }, - { - "name": "Town Hall", - "color": "BLUE", - "effect": { - "points": 6 - }, - "requirements": { - "gold": 0, - "resources": "SSOG" - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 2, - "6": 3, - "7": 3 - }, - "image": "townhall.png" - }, - { - "name": "Academy", - "color": "GREEN", - "effect": { - "science": "COMPASS" - }, - "requirements": { - "gold": 0, - "resources": "SSSG" - }, - "chainParent": "School", - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 1, - "7": 2 - }, - "image": "academy.png" - }, - { - "name": "Lodge", - "color": "GREEN", - "effect": { - "science": "COMPASS" - }, - "requirements": { - "gold": 0, - "resources": "CCPL" - }, - "chainParent": "Dispensary", - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 2, - "7": 2 - }, - "image": "lodge.png" - }, - { - "name": "Observatory", - "color": "GREEN", - "effect": { - "science": "WHEEL" - }, - "requirements": { - "gold": 0, - "resources": "OOGL" - }, - "chainParent": "Laboratory", - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 1, - "7": 2 - }, - "image": "observatory.png" - }, - { - "name": "Study", - "color": "GREEN", - "effect": { - "science": "WHEEL" - }, - "requirements": { - "gold": 0, - "resources": "WPL" - }, - "chainParent": "School", - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "study.png" - }, - { - "name": "University", - "color": "GREEN", - "effect": { - "science": "TABLET" - }, - "requirements": { - "gold": 0, - "resources": "WWGP" - }, - "chainParent": "Library", - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 2, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "university.png" - }, - { - "name": "Arsenal", - "color": "RED", - "effect": { - "military": 3 - }, - "requirements": { - "gold": 0, - "resources": "WWOL" - }, - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 2, - "5": 2, - "6": 2, - "7": 3 - }, - "image": "arsenal.png" - }, - { - "name": "Circus", - "color": "RED", - "effect": { - "military": 3 - }, - "requirements": { - "gold": 0, - "resources": "SSSO" - }, - "chainParent": "Training Ground", - "chainChildren": [], - "countPerNbPlayer": { - "3": 0, - "4": 1, - "5": 2, - "6": 3, - "7": 3 - }, - "image": "circus.png" - }, - { - "name": "Fortifications", - "color": "RED", - "effect": { - "military": 3 - }, - "requirements": { - "gold": 0, - "resources": "SOOO" - }, - "chainParent": "Walls", - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 1, - "6": 1, - "7": 2 - }, - "image": "fortifications.png" - }, - { - "name": "Siege Workshop", - "color": "RED", - "effect": { - "military": 3 - }, - "requirements": { - "gold": 0, - "resources": "WCCC" - }, - "chainParent": "Laboratory", - "chainChildren": [], - "countPerNbPlayer": { - "3": 1, - "4": 1, - "5": 2, - "6": 2, - "7": 2 - }, - "image": "siegeworkshop.png" - } - ], - "guildCards": [ - { - "name": "Builders Guild", - "color": "PURPLE", - "effect": { - "perBoardElement": { - "boards": [ - "LEFT", - "SELF", - "RIGHT" - ], - "gold": 0, - "points": 1, - "type": "WONDER_LEVEL" - } - }, - "requirements": { - "gold": 0, - "resources": "SSCCG" - }, - "chainChildren": [], - "image": "buildersguild.png" - }, - { - "name": "Craftsmens Guild", - "color": "PURPLE", - "effect": { - "perBoardElement": { - "boards": [ - "LEFT", - "RIGHT" - ], - "gold": 0, - "points": 2, - "type": "CARD", - "colors": [ - "GREY" - ] - } - }, - "requirements": { - "gold": 0, - "resources": "SSOO" - }, - "chainChildren": [], - "image": "craftsmensguild.png" - }, - { - "name": "Magistrates Guild", - "color": "PURPLE", - "effect": { - "perBoardElement": { - "boards": [ - "LEFT", - "RIGHT" - ], - "gold": 0, - "points": 1, - "type": "CARD", - "colors": [ - "BLUE" - ] - } - }, - "requirements": { - "gold": 0, - "resources": "WWWSL" - }, - "chainChildren": [], - "image": "magistratesguild.png" - }, - { - "name": "Philosophers Guild", - "color": "PURPLE", - "effect": { - "perBoardElement": { - "boards": [ - "LEFT", - "RIGHT" - ], - "gold": 0, - "points": 1, - "type": "CARD", - "colors": [ - "GREEN" - ] - } - }, - "requirements": { - "gold": 0, - "resources": "CCCPL" - }, - "chainChildren": [], - "image": "philosophersguild.png" - }, - { - "name": "Scientists Guild", - "color": "PURPLE", - "effect": { - "science": "any" - }, - "requirements": { - "gold": 0, - "resources": "WWOOP" - }, - "chainChildren": [], - "image": "scientistsguild.png" - }, - { - "name": "Shipowners Guild", - "color": "PURPLE", - "effect": { - "perBoardElement": { - "boards": [ - "SELF" - ], - "gold": 0, - "points": 1, - "type": "CARD", - "colors": [ - "BROWN", - "GREY", - "PURPLE" - ] - } - }, - "requirements": { - "gold": 0, - "resources": "WWWGP" - }, - "chainChildren": [], - "image": "shipownersguild.png" - }, - { - "name": "Spies Guild", - "color": "PURPLE", - "effect": { - "perBoardElement": { - "boards": [ - "LEFT", - "RIGHT" - ], - "gold": 0, - "points": 1, - "type": "CARD", - "colors": [ - "RED" - ] - } - }, - "requirements": { - "gold": 0, - "resources": "CCCG" - }, - "chainChildren": [], - "image": "spiesguild.png" - }, - { - "name": "Strategists Guild", - "color": "PURPLE", - "effect": { - "perBoardElement": { - "boards": [ - "LEFT", - "RIGHT" - ], - "gold": 0, - "points": 1, - "type": "DEFEAT_TOKEN" - } - }, - "requirements": { - "gold": 0, - "resources": "SOOL" - }, - "chainChildren": [], - "image": "strategistsguild.png" - }, - { - "name": "Traders Guild", - "color": "PURPLE", - "effect": { - "perBoardElement": { - "boards": [ - "LEFT", - "RIGHT" - ], - "gold": 0, - "points": 1, - "type": "CARD", - "colors": [ - "YELLOW" - ] - } - }, - "requirements": { - "gold": 0, - "resources": "GPL" - }, - "chainChildren": [], - "image": "tradersguild.png" - }, - { - "name": "Workers Guild", - "color": "PURPLE", - "effect": { - "perBoardElement": { - "boards": [ - "LEFT", - "RIGHT" - ], - "gold": 0, - "points": 1, - "type": "CARD", - "colors": [ - "BROWN" - ] - } - }, - "requirements": { - "gold": 0, - "resources": "WSOOC" - }, - "chainChildren": [], - "image": "workersguild.png" - } - ] -}
\ No newline at end of file diff --git a/backend/src/main/resources/org/luxons/sevenwonders/game/data/wonders.json b/backend/src/main/resources/org/luxons/sevenwonders/game/data/wonders.json deleted file mode 100644 index 5beceadd..00000000 --- a/backend/src/main/resources/org/luxons/sevenwonders/game/data/wonders.json +++ /dev/null @@ -1,515 +0,0 @@ -[ - { - "name": "alexandria", - "sides": { - "A": { - "initialResource": "G", - "stages": [ - { - "requirements": { - "gold": 0, - "resources": "SS" - }, - "effects": { - "points": 3 - } - }, - { - "requirements": { - "gold": 0, - "resources": "OO" - }, - "effects": { - "production": "(W/S/O/C)" - } - }, - { - "requirements": { - "gold": 0, - "resources": "GG" - }, - "effects": { - "points": 7 - } - } - ], - "image": "alexandriaA.png" - }, - "B": { - "initialResource": "G", - "stages": [ - { - "requirements": { - "gold": 0, - "resources": "CC" - }, - "effects": { - "production": "(W/S/O/C)" - } - }, - { - "requirements": { - "gold": 0, - "resources": "WW" - }, - "effects": { - "production": "(G/P/L)" - } - }, - { - "requirements": { - "gold": 0, - "resources": "SSS" - }, - "effects": { - "points": 7 - } - } - ], - "image": "alexandriaB.png" - } - } - }, - { - "name": "babylon", - "sides": { - "A": { - "initialResource": "C", - "stages": [ - { - "requirements": { - "gold": 0, - "resources": "CC" - }, - "effects": { - "points": 3 - } - }, - { - "requirements": { - "gold": 0, - "resources": "WWW" - }, - "effects": { - "science": "any" - } - }, - { - "requirements": { - "gold": 0, - "resources": "CCCC" - }, - "effects": { - "points": 7 - } - } - ], - "image": "babylonA.png" - }, - "B": { - "initialResource": "C", - "stages": [ - { - "requirements": { - "gold": 0, - "resources": "CL" - }, - "effects": { - "points": 3 - } - }, - { - "requirements": { - "gold": 0, - "resources": "WWG" - }, - "effects": { - "action": "PLAY_LAST_CARD" - } - }, - { - "requirements": { - "gold": 0, - "resources": "CCCP" - }, - "effects": { - "science": "any" - } - } - ], - "image": "babylonB.png" - } - } - }, - { - "name": "ephesos", - "sides": { - "A": { - "initialResource": "P", - "stages": [ - { - "requirements": { - "gold": 0, - "resources": "SS" - }, - "effects": { - "points": 3 - } - }, - { - "requirements": { - "gold": 0, - "resources": "WW" - }, - "effects": { - "gold": 9 - } - }, - { - "requirements": { - "gold": 0, - "resources": "PP" - }, - "effects": { - "points": 7 - } - } - ], - "image": "ephesosA.png" - }, - "B": { - "initialResource": "P", - "stages": [ - { - "requirements": { - "gold": 0, - "resources": "SS" - }, - "effects": { - "gold": 4, - "points": 2 - } - }, - { - "requirements": { - "gold": 0, - "resources": "WW" - }, - "effects": { - "gold": 4, - "points": 3 - } - }, - { - "requirements": { - "gold": 0, - "resources": "GPL" - }, - "effects": { - "gold": 4, - "points": 5 - } - } - ], - "image": "ephesosB.png" - } - } - }, - { - "name": "gizah", - "sides": { - "A": { - "initialResource": "S", - "stages": [ - { - "requirements": { - "gold": 0, - "resources": "SS" - }, - "effects": { - "points": 3 - } - }, - { - "requirements": { - "gold": 0, - "resources": "WWW" - }, - "effects": { - "points": 5 - } - }, - { - "requirements": { - "gold": 0, - "resources": "SSSS" - }, - "effects": { - "points": 7 - } - } - ], - "image": "gizahA.png" - }, - "B": { - "initialResource": "S", - "stages": [ - { - "requirements": { - "gold": 0, - "resources": "WW" - }, - "effects": { - "points": 3 - } - }, - { - "requirements": { - "gold": 0, - "resources": "SSS" - }, - "effects": { - "points": 5 - } - }, - { - "requirements": { - "gold": 0, - "resources": "CCC" - }, - "effects": { - "points": 5 - } - }, - { - "requirements": { - "gold": 0, - "resources": "SSSSP" - }, - "effects": { - "points": 7 - } - } - ], - "image": "gizahB.png" - } - } - }, - { - "name": "halikarnassus", - "sides": { - "A": { - "initialResource": "L", - "stages": [ - { - "requirements": { - "gold": 0, - "resources": "CC" - }, - "effects": { - "points": 3 - } - }, - { - "requirements": { - "gold": 0, - "resources": "OOO" - }, - "effects": { - "action": "PLAY_DISCARDED" - } - }, - { - "requirements": { - "gold": 0, - "resources": "LL" - }, - "effects": { - "points": 7 - } - } - ], - "image": "halikarnassusA.png" - }, - "B": { - "initialResource": "L", - "stages": [ - { - "requirements": { - "gold": 0, - "resources": "OO" - }, - "effects": { - "points": 2, - "action": "PLAY_DISCARDED" - } - }, - { - "requirements": { - "gold": 0, - "resources": "CCC" - }, - "effects": { - "points": 1, - "action": "PLAY_DISCARDED" - } - }, - { - "requirements": { - "gold": 0, - "resources": "GPL" - }, - "effects": { - "action": "PLAY_DISCARDED" - } - } - ], - "image": "halikarnassusB.png" - } - } - }, - { - "name": "olympia", - "sides": { - "A": { - "initialResource": "W", - "stages": [ - { - "requirements": { - "gold": 0, - "resources": "WW" - }, - "effects": { - "points": 3 - } - }, - { - "requirements": { - "gold": 0, - "resources": "SS" - }, - "effects": { - "action": "ONE_FREE" - } - }, - { - "requirements": { - "gold": 0, - "resources": "OO" - }, - "effects": { - "points": 7 - } - } - ], - "image": "olympiaA.png" - }, - "B": { - "initialResource": "W", - "stages": [ - { - "requirements": { - "gold": 0, - "resources": "WW" - }, - "effects": { - "discount": { - "resourceTypes": "WSOC", - "providers": [ - "LEFT_PLAYER", - "RIGHT_PLAYER" - ], - "discountedPrice": 1 - } - } - }, - { - "requirements": { - "gold": 0, - "resources": "SS" - }, - "effects": { - "points": 5 - } - }, - { - "requirements": { - "gold": 0, - "resources": "OOL" - }, - "effects": { - "action": "COPY_GUILD" - } - } - ], - "image": "olympiaB.png" - } - } - }, - { - "name": "rhodos", - "sides": { - "A": { - "initialResource": "O", - "stages": [ - { - "requirements": { - "gold": 0, - "resources": "WW" - }, - "effects": { - "points": 3 - } - }, - { - "requirements": { - "gold": 0, - "resources": "CCC" - }, - "effects": { - "military": 2 - } - }, - { - "requirements": { - "gold": 0, - "resources": "OOOO" - }, - "effects": { - "points": 7 - } - } - ], - "image": "rhodosA.png" - }, - "B": { - "initialResource": "O", - "stages": [ - { - "requirements": { - "gold": 0, - "resources": "SSS" - }, - "effects": { - "gold": 3, - "military": 1, - "points": 3 - } - }, - { - "requirements": { - "gold": 0, - "resources": "OOOO" - }, - "effects": { - "gold": 4, - "military": 1, - "points": 4 - } - } - ], - "image": "rhodosB.png" - } - } - } -]
\ No newline at end of file |