summaryrefslogtreecommitdiff
path: root/game-engine
diff options
context:
space:
mode:
authorJoffrey Bion <joffrey.bion@amadeus.com>2018-07-09 15:22:53 +0200
committerJoffrey Bion <joffrey.bion@amadeus.com>2018-07-09 15:22:53 +0200
commitf92facc7ccfc9564f7481940c5b23b66a473982f (patch)
tree00ba42ee9cad92aa7d82336a85b891e02f784869 /game-engine
parentKotlin mig: Boards package (diff)
downloadseven-wonders-f92facc7ccfc9564f7481940c5b23b66a473982f.tar.gz
seven-wonders-f92facc7ccfc9564f7481940c5b23b66a473982f.tar.bz2
seven-wonders-f92facc7ccfc9564f7481940c5b23b66a473982f.zip
Kotlin mig: moves package
Diffstat (limited to 'game-engine')
-rw-r--r--game-engine/src/main/java/org/luxons/sevenwonders/game/moves/BuildWonderMove.java39
-rw-r--r--game-engine/src/main/java/org/luxons/sevenwonders/game/moves/CardFromHandMove.java23
-rw-r--r--game-engine/src/main/java/org/luxons/sevenwonders/game/moves/CopyGuildMove.java56
-rw-r--r--game-engine/src/main/java/org/luxons/sevenwonders/game/moves/DiscardMove.java27
-rw-r--r--game-engine/src/main/java/org/luxons/sevenwonders/game/moves/InvalidMoveException.java8
-rw-r--r--game-engine/src/main/java/org/luxons/sevenwonders/game/moves/Move.java49
-rw-r--r--game-engine/src/main/java/org/luxons/sevenwonders/game/moves/MoveType.java39
-rw-r--r--game-engine/src/main/java/org/luxons/sevenwonders/game/moves/PlayCardMove.java39
-rw-r--r--game-engine/src/main/java/org/luxons/sevenwonders/game/moves/PlayFreeCardMove.java40
-rw-r--r--game-engine/src/main/kotlin/org/luxons/sevenwonders/game/api/Action.kt2
-rw-r--r--game-engine/src/main/kotlin/org/luxons/sevenwonders/game/api/HandCard.kt2
-rw-r--r--game-engine/src/main/kotlin/org/luxons/sevenwonders/game/api/PlayerMove.kt2
-rw-r--r--game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/BuildWonderMove.kt25
-rw-r--r--game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/CardFromHandMove.kt16
-rw-r--r--game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/CopyGuildMove.kt41
-rw-r--r--game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/DiscardMove.kt20
-rw-r--r--game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/InvalidMoveException.kt3
-rw-r--r--game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/Move.kt21
-rw-r--r--game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/MoveType.kt24
-rw-r--r--game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/PlayCardMove.kt25
-rw-r--r--game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/PlayFreeCardMove.kt34
-rw-r--r--game-engine/src/test/java/org/luxons/sevenwonders/game/moves/BuildWonderMoveTest.java77
-rw-r--r--game-engine/src/test/java/org/luxons/sevenwonders/game/resources/BestPriceCalculatorTest.java129
-rw-r--r--game-engine/src/test/java/org/luxons/sevenwonders/game/resources/ProductionTest.java324
-rw-r--r--game-engine/src/test/java/org/luxons/sevenwonders/game/resources/ResourceTransactionsTest.java37
-rw-r--r--game-engine/src/test/java/org/luxons/sevenwonders/game/resources/ResourcesTest.java485
-rw-r--r--game-engine/src/test/java/org/luxons/sevenwonders/game/resources/TradingRulesTest.java111
-rw-r--r--game-engine/src/test/kotlin/org/luxons/sevenwonders/game/moves/BuildWonderMoveTest.kt76
-rw-r--r--game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/BestPriceCalculatorTest.kt129
-rw-r--r--game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/ProductionTest.kt323
-rw-r--r--game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/ResourceTransactionsTest.kt36
-rw-r--r--game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/ResourcesTest.kt482
-rw-r--r--game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/TradingRulesTest.kt127
33 files changed, 1384 insertions, 1487 deletions
diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/moves/BuildWonderMove.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/moves/BuildWonderMove.java
deleted file mode 100644
index f70d2626..00000000
--- a/game-engine/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(), getTransactions())) {
- 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, getTransactions());
- }
-}
diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/moves/CardFromHandMove.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/moves/CardFromHandMove.java
deleted file mode 100644
index 1794966d..00000000
--- a/game-engine/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/game-engine/src/main/java/org/luxons/sevenwonders/game/moves/CopyGuildMove.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/moves/CopyGuildMove.java
deleted file mode 100644
index a93670c5..00000000
--- a/game-engine/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/game-engine/src/main/java/org/luxons/sevenwonders/game/moves/DiscardMove.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/moves/DiscardMove.java
deleted file mode 100644
index 076a593c..00000000
--- a/game-engine/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/game-engine/src/main/java/org/luxons/sevenwonders/game/moves/InvalidMoveException.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/moves/InvalidMoveException.java
deleted file mode 100644
index 58190274..00000000
--- a/game-engine/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/game-engine/src/main/java/org/luxons/sevenwonders/game/moves/Move.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/moves/Move.java
deleted file mode 100644
index cfb12e67..00000000
--- a/game-engine/src/main/java/org/luxons/sevenwonders/game/moves/Move.java
+++ /dev/null
@@ -1,49 +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.cards.Card;
-import org.luxons.sevenwonders.game.resources.ResourceTransactions;
-
-public abstract class Move {
-
- private int playerIndex;
-
- private Card card;
-
- private MoveType type;
-
- private ResourceTransactions transactions;
-
- Move(int playerIndex, Card card, PlayerMove move) {
- this.playerIndex = playerIndex;
- this.card = card;
- this.type = move.getType();
- this.transactions = new ResourceTransactions(move.getTransactions());
- }
-
- public int getPlayerIndex() {
- return playerIndex;
- }
-
- public Card getCard() {
- return card;
- }
-
- public MoveType getType() {
- return type;
- }
-
- public ResourceTransactions getTransactions() {
- return transactions;
- }
-
- 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/game-engine/src/main/java/org/luxons/sevenwonders/game/moves/MoveType.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/moves/MoveType.java
deleted file mode 100644
index bf64344d..00000000
--- a/game-engine/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/game-engine/src/main/java/org/luxons/sevenwonders/game/moves/PlayCardMove.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/moves/PlayCardMove.java
deleted file mode 100644
index 18d6ba90..00000000
--- a/game-engine/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, getTransactions())) {
- 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(), getTransactions());
- }
-}
diff --git a/game-engine/src/main/java/org/luxons/sevenwonders/game/moves/PlayFreeCardMove.java b/game-engine/src/main/java/org/luxons/sevenwonders/game/moves/PlayFreeCardMove.java
deleted file mode 100644
index 4e8eefa5..00000000
--- a/game-engine/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/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/api/Action.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/api/Action.kt
index 37ab3e6f..6cfd3679 100644
--- a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/api/Action.kt
+++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/api/Action.kt
@@ -1,6 +1,6 @@
package org.luxons.sevenwonders.game.api
-enum class Action constructor(val message: String) {
+enum class Action(val message: String) {
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."),
diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/api/HandCard.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/api/HandCard.kt
index d487a9ac..1b11edef 100644
--- a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/api/HandCard.kt
+++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/api/HandCard.kt
@@ -9,9 +9,7 @@ import org.luxons.sevenwonders.game.cards.Card
class HandCard(val card: Card, table: Table, playerIndex: Int) {
val isChainable: Boolean
-
val isFree: Boolean
-
val isPlayable: Boolean = card.isPlayable(table, playerIndex)
init {
diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/api/PlayerMove.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/api/PlayerMove.kt
index 4d4ef7cc..95e6b13c 100644
--- a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/api/PlayerMove.kt
+++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/api/PlayerMove.kt
@@ -3,7 +3,7 @@ package org.luxons.sevenwonders.game.api
import org.luxons.sevenwonders.game.moves.MoveType
import org.luxons.sevenwonders.game.resources.ResourceTransaction
-data class PlayerMove @JvmOverloads constructor(
+data class PlayerMove(
val type: MoveType,
val cardName: String,
val transactions: Collection<ResourceTransaction> = emptyList()
diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/BuildWonderMove.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/BuildWonderMove.kt
new file mode 100644
index 00000000..bbd9ebab
--- /dev/null
+++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/BuildWonderMove.kt
@@ -0,0 +1,25 @@
+package org.luxons.sevenwonders.game.moves
+
+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
+
+class BuildWonderMove internal constructor(playerIndex: Int, card: Card, move: PlayerMove) :
+ CardFromHandMove(playerIndex, card, move) {
+
+ @Throws(InvalidMoveException::class)
+ override fun validate(table: Table, playerHand: List<Card>) {
+ super.validate(table, playerHand)
+ val board = table.getBoard(playerIndex)
+ if (!board.wonder.isNextStageBuildable(table, playerIndex, transactions)) {
+ throw InvalidMoveException("Player $playerIndex cannot upgrade his wonder with the given resources")
+ }
+ }
+
+ override fun place(table: Table, discardedCards: MutableList<Card>, settings: Settings) =
+ table.getBoard(playerIndex).wonder.buildLevel(card.back)
+
+ override fun activate(table: Table, discardedCards: List<Card>, settings: Settings) =
+ table.getBoard(playerIndex).wonder.activateLastBuiltStage(table, playerIndex, transactions)
+}
diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/CardFromHandMove.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/CardFromHandMove.kt
new file mode 100644
index 00000000..7b084d43
--- /dev/null
+++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/CardFromHandMove.kt
@@ -0,0 +1,16 @@
+package org.luxons.sevenwonders.game.moves
+
+import org.luxons.sevenwonders.game.api.PlayerMove
+import org.luxons.sevenwonders.game.api.Table
+import org.luxons.sevenwonders.game.cards.Card
+
+abstract class CardFromHandMove internal constructor(playerIndex: Int, card: Card, move: PlayerMove) :
+ Move(playerIndex, card, move) {
+
+ @Throws(InvalidMoveException::class)
+ override fun validate(table: Table, playerHand: List<Card>) {
+ if (!playerHand.contains(card)) {
+ throw InvalidMoveException("Player $playerIndex does not have the card '${card.name}' in his hand")
+ }
+ }
+}
diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/CopyGuildMove.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/CopyGuildMove.kt
new file mode 100644
index 00000000..5a017e53
--- /dev/null
+++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/CopyGuildMove.kt
@@ -0,0 +1,41 @@
+package org.luxons.sevenwonders.game.moves
+
+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.RelativeBoardPosition
+import org.luxons.sevenwonders.game.cards.Card
+import org.luxons.sevenwonders.game.cards.Color
+import org.luxons.sevenwonders.game.effects.SpecialAbility
+
+class CopyGuildMove internal constructor(playerIndex: Int, card: Card, move: PlayerMove) :
+ Move(playerIndex, card, move) {
+
+ @Throws(InvalidMoveException::class)
+ override fun validate(table: Table, playerHand: List<Card>) {
+ val board = table.getBoard(playerIndex)
+ if (!board.hasSpecial(SpecialAbility.COPY_GUILD)) {
+ throw InvalidMoveException("Player $playerIndex does not have the ability to copy guild cards")
+ }
+ if (card.color !== Color.PURPLE) {
+ throw InvalidMoveException("Player $playerIndex cannot copy card ${card.name} because it is not a guild card")
+ }
+ val leftNeighbourHasIt = neighbourHasTheCard(table, RelativeBoardPosition.LEFT)
+ val rightNeighbourHasIt = neighbourHasTheCard(table, RelativeBoardPosition.RIGHT)
+ if (!leftNeighbourHasIt && !rightNeighbourHasIt) {
+ throw InvalidMoveException("Player $playerIndex cannot copy card ${card.name} because none of his neighbour has it")
+ }
+ }
+
+ private fun neighbourHasTheCard(table: Table, position: RelativeBoardPosition): Boolean {
+ val neighbourBoard = table.getBoard(playerIndex, position)
+ return neighbourBoard.getPlayedCards().contains(card)
+ }
+
+ // nothing special to do here
+ override fun place(table: Table, discardedCards: MutableList<Card>, settings: Settings) = Unit
+
+ override fun activate(table: Table, discardedCards: List<Card>, settings: Settings) {
+ table.getBoard(playerIndex).copiedGuild = card
+ }
+}
diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/DiscardMove.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/DiscardMove.kt
new file mode 100644
index 00000000..cf1b69ba
--- /dev/null
+++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/DiscardMove.kt
@@ -0,0 +1,20 @@
+package org.luxons.sevenwonders.game.moves
+
+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
+
+class DiscardMove internal constructor(playerIndex: Int, card: Card, move: PlayerMove) :
+ CardFromHandMove(playerIndex, card, move) {
+
+ override fun place(table: Table, discardedCards: MutableList<Card>, settings: Settings) {
+ discardedCards.add(card)
+ }
+
+ override fun activate(table: Table, discardedCards: List<Card>, settings: Settings) {
+ val board = table.getBoard(playerIndex)
+ board.addGold(settings.discardedCardGold)
+ }
+}
diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/InvalidMoveException.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/InvalidMoveException.kt
new file mode 100644
index 00000000..d816355d
--- /dev/null
+++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/InvalidMoveException.kt
@@ -0,0 +1,3 @@
+package org.luxons.sevenwonders.game.moves
+
+class InvalidMoveException(message: String) : IllegalArgumentException(message)
diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/Move.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/Move.kt
new file mode 100644
index 00000000..885f267f
--- /dev/null
+++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/Move.kt
@@ -0,0 +1,21 @@
+package org.luxons.sevenwonders.game.moves
+
+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.ResourceTransactions
+
+abstract class Move internal constructor(val playerIndex: Int, val card: Card, move: PlayerMove) {
+
+ val type: MoveType = move.type
+
+ val transactions: ResourceTransactions = ResourceTransactions(move.transactions)
+
+ @Throws(InvalidMoveException::class)
+ abstract fun validate(table: Table, playerHand: List<Card>)
+
+ abstract fun place(table: Table, discardedCards: MutableList<Card>, settings: Settings)
+
+ abstract fun activate(table: Table, discardedCards: List<Card>, settings: Settings)
+}
diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/MoveType.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/MoveType.kt
new file mode 100644
index 00000000..ced0f3a1
--- /dev/null
+++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/MoveType.kt
@@ -0,0 +1,24 @@
+package org.luxons.sevenwonders.game.moves
+
+import org.luxons.sevenwonders.game.api.PlayerMove
+import org.luxons.sevenwonders.game.cards.Card
+
+enum class MoveType {
+ PLAY {
+ override fun resolve(playerIndex: Int, card: Card, move: PlayerMove) = PlayCardMove(playerIndex, card, move)
+ },
+ PLAY_FREE {
+ override fun resolve(playerIndex: Int, card: Card, move: PlayerMove) = PlayFreeCardMove(playerIndex, card, move)
+ },
+ UPGRADE_WONDER {
+ override fun resolve(playerIndex: Int, card: Card, move: PlayerMove) = BuildWonderMove(playerIndex, card, move)
+ },
+ DISCARD {
+ override fun resolve(playerIndex: Int, card: Card, move: PlayerMove) = DiscardMove(playerIndex, card, move)
+ },
+ COPY_GUILD {
+ override fun resolve(playerIndex: Int, card: Card, move: PlayerMove) = CopyGuildMove(playerIndex, card, move)
+ };
+
+ abstract fun resolve(playerIndex: Int, card: Card, move: PlayerMove): Move
+}
diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/PlayCardMove.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/PlayCardMove.kt
new file mode 100644
index 00000000..b87916b1
--- /dev/null
+++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/PlayCardMove.kt
@@ -0,0 +1,25 @@
+package org.luxons.sevenwonders.game.moves
+
+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
+
+class PlayCardMove internal constructor(playerIndex: Int, card: Card, move: PlayerMove) :
+ CardFromHandMove(playerIndex, card, move) {
+
+ @Throws(InvalidMoveException::class)
+ override fun validate(table: Table, playerHand: List<Card>) {
+ super.validate(table, playerHand)
+ val board = table.getBoard(playerIndex)
+ if (!card.isChainableOn(board) && !card.requirements.areMetWithHelpBy(board, transactions)) {
+ throw InvalidMoveException("Player $playerIndex cannot play the card ${card.name} with the given resources")
+ }
+ }
+
+ override fun place(table: Table, discardedCards: MutableList<Card>, settings: Settings) =
+ table.getBoard(playerIndex).addCard(card)
+
+ override fun activate(table: Table, discardedCards: List<Card>, settings: Settings) =
+ card.applyTo(table, playerIndex, transactions)
+}
diff --git a/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/PlayFreeCardMove.kt b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/PlayFreeCardMove.kt
new file mode 100644
index 00000000..125b34a6
--- /dev/null
+++ b/game-engine/src/main/kotlin/org/luxons/sevenwonders/game/moves/PlayFreeCardMove.kt
@@ -0,0 +1,34 @@
+package org.luxons.sevenwonders.game.moves
+
+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
+
+class PlayFreeCardMove internal constructor(playerIndex: Int, card: Card, move: PlayerMove) :
+ CardFromHandMove(playerIndex, card, move) {
+
+ @Throws(InvalidMoveException::class)
+ override fun validate(table: Table, playerHand: List<Card>) {
+ super.validate(table, playerHand)
+ val board = table.getBoard(playerIndex)
+ if (!board.canPlayFreeCard(table.currentAge)) {
+ throw InvalidMoveException(
+ String.format("Player %d cannot play the card %s for free", playerIndex, card.name)
+ )
+ }
+ }
+
+ override fun place(table: Table, discardedCards: MutableList<Card>, settings: Settings) {
+ val board = table.getBoard(playerIndex)
+ board.addCard(card)
+ }
+
+ override fun activate(table: Table, discardedCards: List<Card>, settings: Settings) {
+ // only apply effects, without paying the cost
+ card.effects.forEach { e -> e.apply(table, playerIndex) }
+ val board = table.getBoard(playerIndex)
+ board.consumeFreeCard(table.currentAge)
+ }
+}
diff --git a/game-engine/src/test/java/org/luxons/sevenwonders/game/moves/BuildWonderMoveTest.java b/game-engine/src/test/java/org/luxons/sevenwonders/game/moves/BuildWonderMoveTest.java
deleted file mode 100644
index 87e1d704..00000000
--- a/game-engine/src/test/java/org/luxons/sevenwonders/game/moves/BuildWonderMoveTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.luxons.sevenwonders.game.moves;
-
-import java.util.Collections;
-import java.util.List;
-
-import org.junit.Test;
-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.test.TestUtilsKt;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-public class BuildWonderMoveTest {
-
- @Test(expected = InvalidMoveException.class)
- public void validate_failsWhenCardNotInHand() {
- Table table = TestUtilsKt.testTable(3);
- List<Card> hand = TestUtilsKt.sampleCards(0, 7);
- Card anotherCard = TestUtilsKt.testCard("Card that is not in the hand");
- Move move = TestUtilsKt.createMove(0, anotherCard, MoveType.UPGRADE_WONDER);
-
- move.validate(table, hand);
- }
-
- @Test(expected = InvalidMoveException.class)
- public void validate_failsWhenWonderIsCompletelyBuilt() {
- Settings settings = TestUtilsKt.testSettings(3);
- Table table = TestUtilsKt.testTable(settings);
- List<Card> hand = TestUtilsKt.sampleCards(0, 7);
-
- fillPlayerWonderLevels(settings, table, hand);
-
- // should fail because the wonder is already full
- buildOneWonderLevel(settings, table, hand, 4);
- }
-
- private static void fillPlayerWonderLevels(Settings settings, Table table, List<Card> hand) {
- try {
- int nbLevels = table.getBoard(0).getWonder().getStages().size();
- for (int i = 0; i < nbLevels; i++) {
- buildOneWonderLevel(settings, table, hand, i);
- }
- } catch (InvalidMoveException e) {
- fail("Building wonder levels should not fail before being full");
- }
- }
-
- private static void buildOneWonderLevel(Settings settings, Table table, List<Card> hand, int cardIndex) {
- Card card = hand.get(cardIndex);
- Move move = TestUtilsKt.createMove(0, card, MoveType.UPGRADE_WONDER);
- move.validate(table, hand);
- move.place(table, Collections.emptyList(), settings);
- move.activate(table, Collections.emptyList(), settings);
- }
-
- @Test
- public void place_increasesWonderLevel() {
- Settings settings = TestUtilsKt.testSettings(3);
- Table table = TestUtilsKt.testTable(settings);
- List<Card> hand = TestUtilsKt.sampleCards(0, 7);
- Card cardToUse = hand.get(0);
- Move move = TestUtilsKt.createMove(0, cardToUse, MoveType.UPGRADE_WONDER);
- move.validate(table, hand); // should not fail
-
- int initialStage = table.getBoard(0).getWonder().getNbBuiltStages();
-
- move.place(table, Collections.emptyList(), settings);
-
- int newStage = table.getBoard(0).getWonder().getNbBuiltStages();
-
- // we need to see the level increase before activation so that other players
- assertEquals(initialStage + 1, newStage);
- }
-
-}
diff --git a/game-engine/src/test/java/org/luxons/sevenwonders/game/resources/BestPriceCalculatorTest.java b/game-engine/src/test/java/org/luxons/sevenwonders/game/resources/BestPriceCalculatorTest.java
deleted file mode 100644
index bb0e757b..00000000
--- a/game-engine/src/test/java/org/luxons/sevenwonders/game/resources/BestPriceCalculatorTest.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package org.luxons.sevenwonders.game.resources;
-
-import java.util.Arrays;
-
-import org.junit.Test;
-import org.luxons.sevenwonders.game.api.Table;
-import org.luxons.sevenwonders.game.boards.Board;
-import org.luxons.sevenwonders.game.test.TestUtilsKt;
-
-import static org.junit.Assert.assertEquals;
-import static org.luxons.sevenwonders.game.resources.Provider.LEFT_PLAYER;
-import static org.luxons.sevenwonders.game.resources.Provider.RIGHT_PLAYER;
-import static org.luxons.sevenwonders.game.resources.ResourceType.CLAY;
-import static org.luxons.sevenwonders.game.resources.ResourceType.GLASS;
-import static org.luxons.sevenwonders.game.resources.ResourceType.ORE;
-import static org.luxons.sevenwonders.game.resources.ResourceType.STONE;
-import static org.luxons.sevenwonders.game.resources.ResourceType.WOOD;
-
-public class BestPriceCalculatorTest {
-
- @Test
- public void bestPrice_0forEmptyResources() {
- Table table = TestUtilsKt.testTable(3);
- Resources resources = new Resources();
- assertEquals(0, BestPriceCalculator.bestPrice(resources, table, 0));
- assertEquals(new ResourceTransactions(), BestPriceCalculator.bestSolution(resources, table, 0));
- }
-
- @Test
- public void bestPrice_fixedResources_defaultCost() {
- Board left = TestUtilsKt.testBoard(STONE);
- Board main = TestUtilsKt.testBoard(STONE);
- Board right = TestUtilsKt.testBoard(WOOD);
- Table table = new Table(Arrays.asList(main, right, left));
-
- Resources resources = TestUtilsKt.createResources(STONE, STONE);
- assertEquals(2, BestPriceCalculator.bestPrice(resources, table, 0));
- assertEquals(4, BestPriceCalculator.bestPrice(resources, table, 1));
- assertEquals(2, BestPriceCalculator.bestPrice(resources, table, 2));
-
- ResourceTransaction stoneLeftSingle = TestUtilsKt.createTransaction(LEFT_PLAYER, STONE);
- ResourceTransaction stoneRightSingle = TestUtilsKt.createTransaction(RIGHT_PLAYER, STONE);
-
- ResourceTransactions stoneLeft = TestUtilsKt.createTransactions(stoneLeftSingle);
- ResourceTransactions stoneRight = TestUtilsKt.createTransactions(stoneRightSingle);
- ResourceTransactions stoneLeftAndRight = TestUtilsKt.createTransactions(stoneLeftSingle, stoneRightSingle);
-
- assertEquals(stoneLeft, BestPriceCalculator.bestSolution(resources, table, 0));
- assertEquals(stoneLeftAndRight, BestPriceCalculator.bestSolution(resources, table, 1));
- assertEquals(stoneRight, BestPriceCalculator.bestSolution(resources, table, 2));
- }
-
- @Test
- public void bestPrice_fixedResources_overridenCost() {
- Board main = TestUtilsKt.testBoard(STONE);
- main.getTradingRules().setCost(WOOD, RIGHT_PLAYER, 1);
-
- Board left = TestUtilsKt.testBoard(WOOD);
- Board right = TestUtilsKt.testBoard(WOOD);
- Board opposite = TestUtilsKt.testBoard(GLASS);
- Table table = new Table(Arrays.asList(main, right, opposite, left));
-
- Resources resources = TestUtilsKt.createResources(WOOD);
- assertEquals(1, BestPriceCalculator.bestPrice(resources, table, 0));
- assertEquals(0, BestPriceCalculator.bestPrice(resources, table, 1));
- assertEquals(2, BestPriceCalculator.bestPrice(resources, table, 2));
- assertEquals(0, BestPriceCalculator.bestPrice(resources, table, 3));
-
- ResourceTransactions woodLeft = TestUtilsKt.createTransactions(LEFT_PLAYER, WOOD);
- ResourceTransactions woodRight = TestUtilsKt.createTransactions(RIGHT_PLAYER, WOOD);
- assertEquals(woodRight, BestPriceCalculator.bestSolution(resources, table, 0));
- assertEquals(new ResourceTransactions(), BestPriceCalculator.bestSolution(resources, table, 1));
- assertEquals(woodLeft, BestPriceCalculator.bestSolution(resources, table, 2));
- assertEquals(new ResourceTransactions(), BestPriceCalculator.bestSolution(resources, table, 3));
- }
-
- @Test
- public void bestPrice_mixedResources_overridenCost() {
- Board left = TestUtilsKt.testBoard(WOOD);
-
- Board main = TestUtilsKt.testBoard(STONE);
- main.getTradingRules().setCost(WOOD, RIGHT_PLAYER, 1);
-
- Board right = TestUtilsKt.testBoard(ORE);
- right.getProduction().addChoice(WOOD, CLAY);
- right.getPublicProduction().addChoice(WOOD, CLAY);
-
- Table table = new Table(Arrays.asList(main, right, left));
-
- Resources resources = TestUtilsKt.createResources(WOOD);
- assertEquals(1, BestPriceCalculator.bestPrice(resources, table, 0));
- assertEquals(0, BestPriceCalculator.bestPrice(resources, table, 1));
- assertEquals(0, BestPriceCalculator.bestPrice(resources, table, 2));
-
- ResourceTransactions woodRight = TestUtilsKt.createTransactions(RIGHT_PLAYER, WOOD);
-
- assertEquals(woodRight, BestPriceCalculator.bestSolution(resources, table, 0));
- assertEquals(new ResourceTransactions(), BestPriceCalculator.bestSolution(resources, table, 1));
- assertEquals(new ResourceTransactions(), BestPriceCalculator.bestSolution(resources, table, 2));
- }
-
- @Test
- public void bestPrice_chooseCheapest() {
- Board left = TestUtilsKt.testBoard(WOOD);
-
- Board main = TestUtilsKt.testBoard(WOOD);
- main.getProduction().addChoice(CLAY, ORE);
- main.getTradingRules().setCost(CLAY, RIGHT_PLAYER, 1);
-
- Board right = TestUtilsKt.testBoard(WOOD);
- right.getProduction().addFixedResource(ORE, 1);
- right.getProduction().addFixedResource(CLAY, 1);
- right.getPublicProduction().addFixedResource(ORE, 1);
- right.getPublicProduction().addFixedResource(CLAY, 1);
-
- Table table = new Table(Arrays.asList(main, right, left));
-
- Resources resources = TestUtilsKt.createResources(ORE, CLAY);
- assertEquals(1, BestPriceCalculator.bestPrice(resources, table, 0));
- assertEquals(0, BestPriceCalculator.bestPrice(resources, table, 1));
- assertEquals(4, BestPriceCalculator.bestPrice(resources, table, 2));
-
- ResourceTransactions oreAndClayLeft = TestUtilsKt.createTransactions(LEFT_PLAYER, ORE, CLAY);
- ResourceTransactions clayRight = TestUtilsKt.createTransactions(RIGHT_PLAYER, CLAY);
- assertEquals(clayRight, BestPriceCalculator.bestSolution(resources, table, 0));
- assertEquals(new ResourceTransactions(), BestPriceCalculator.bestSolution(resources, table, 1));
- assertEquals(oreAndClayLeft, BestPriceCalculator.bestSolution(resources, table, 2));
- }
-}
diff --git a/game-engine/src/test/java/org/luxons/sevenwonders/game/resources/ProductionTest.java b/game-engine/src/test/java/org/luxons/sevenwonders/game/resources/ProductionTest.java
deleted file mode 100644
index 2247147c..00000000
--- a/game-engine/src/test/java/org/luxons/sevenwonders/game/resources/ProductionTest.java
+++ /dev/null
@@ -1,324 +0,0 @@
-package org.luxons.sevenwonders.game.resources;
-
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-public class ProductionTest {
-
- private Resources emptyResources;
-
- private Resources resources1Wood;
-
- private Resources resources1Stone;
-
- private Resources resources1Stone1Wood;
-
- private Resources resources2Stones;
-
- private Resources resources2Stones3Clay;
-
- @Before
- public void init() {
- emptyResources = new Resources();
-
- resources1Wood = new Resources();
- resources1Wood.add(ResourceType.WOOD, 1);
-
- resources1Stone = new Resources();
- resources1Stone.add(ResourceType.STONE, 1);
-
- resources1Stone1Wood = new Resources();
- resources1Stone1Wood.add(ResourceType.STONE, 1);
- resources1Stone1Wood.add(ResourceType.WOOD, 1);
-
- resources2Stones = new Resources();
- resources2Stones.add(ResourceType.STONE, 2);
-
- resources2Stones3Clay = new Resources();
- resources2Stones3Clay.add(ResourceType.STONE, 2);
- resources2Stones3Clay.add(ResourceType.CLAY, 3);
- }
-
- @Test
- public void contains_newProductionContainsEmpty() {
- Production production = new Production();
- assertTrue(production.contains(emptyResources));
- }
-
- @Test
- public void contains_singleFixedResource_noneAtAll() {
- Production production = new Production();
- assertFalse(production.contains(resources2Stones));
- }
-
- @Test
- public void contains_singleFixedResource_notEnough() {
- Production production = new Production();
- production.addFixedResource(ResourceType.STONE, 1);
- assertFalse(production.contains(resources2Stones));
- }
-
- @Test
- public void contains_singleFixedResource_justEnough() {
- Production production = new Production();
- production.addFixedResource(ResourceType.STONE, 2);
- assertTrue(production.contains(resources2Stones));
- }
-
- @Test
- public void contains_singleFixedResource_moreThanEnough() {
- Production production = new Production();
- production.addFixedResource(ResourceType.STONE, 3);
- assertTrue(production.contains(resources2Stones));
- }
-
- @Test
- public void contains_singleFixedResource_moreThanEnough_amongOthers() {
- Production production = new Production();
- production.addFixedResource(ResourceType.STONE, 3);
- production.addFixedResource(ResourceType.CLAY, 2);
- assertTrue(production.contains(resources2Stones));
- }
-
- @Test
- public void contains_multipleFixedResources_notEnoughOfOne() {
- Production production = new Production();
- production.addFixedResource(ResourceType.STONE, 3);
- production.addFixedResource(ResourceType.CLAY, 1);
- assertFalse(production.contains(resources2Stones3Clay));
- }
-
- @Test
- public void contains_multipleFixedResources_notEnoughOfBoth() {
- Production production = new Production();
- production.addFixedResource(ResourceType.STONE, 1);
- production.addFixedResource(ResourceType.CLAY, 1);
- assertFalse(production.contains(resources2Stones3Clay));
- }
-
- @Test
- public void contains_multipleFixedResources_moreThanEnough() {
- Production production = new Production();
- production.addFixedResource(ResourceType.STONE, 3);
- production.addFixedResource(ResourceType.CLAY, 5);
- assertTrue(production.contains(resources2Stones3Clay));
- }
-
- @Test
- public void contains_singleChoice_containsEmpty() {
- Production production = new Production();
- production.addChoice(ResourceType.STONE, ResourceType.CLAY);
- assertTrue(production.contains(emptyResources));
- }
-
- @Test
- public void contains_singleChoice_enough() {
- Production production = new Production();
- production.addChoice(ResourceType.STONE, ResourceType.WOOD);
- assertTrue(production.contains(resources1Wood));
- assertTrue(production.contains(resources1Stone));
- }
-
- @Test
- public void contains_multipleChoices_notBoth() {
- Production production = new Production();
- production.addChoice(ResourceType.STONE, ResourceType.CLAY);
- production.addChoice(ResourceType.STONE, ResourceType.CLAY);
- production.addChoice(ResourceType.STONE, ResourceType.CLAY);
- assertFalse(production.contains(resources2Stones3Clay));
- }
-
- @Test
- public void contains_multipleChoices_enough() {
- Production production = new Production();
- production.addChoice(ResourceType.STONE, ResourceType.ORE);
- production.addChoice(ResourceType.STONE, ResourceType.WOOD);
- assertTrue(production.contains(resources1Stone1Wood));
- }
-
- @Test
- public void contains_multipleChoices_enoughReverseOrder() {
- Production production = new Production();
- production.addChoice(ResourceType.STONE, ResourceType.WOOD);
- production.addChoice(ResourceType.STONE, ResourceType.ORE);
- assertTrue(production.contains(resources1Stone1Wood));
- }
-
- @Test
- public void contains_multipleChoices_moreThanEnough() {
- Production production = new Production();
- production.addChoice(ResourceType.LOOM, ResourceType.GLASS, ResourceType.PAPYRUS);
- production.addChoice(ResourceType.STONE, ResourceType.ORE);
- production.addChoice(ResourceType.STONE, ResourceType.WOOD);
- assertTrue(production.contains(resources1Stone1Wood));
- }
-
- @Test
- public void contains_mixedFixedAndChoice_enough() {
- Production production = new Production();
- production.addFixedResource(ResourceType.WOOD, 1);
- production.addChoice(ResourceType.STONE, ResourceType.WOOD);
- assertTrue(production.contains(resources1Stone1Wood));
- }
-
- @Test
- public void addAll_empty() {
- Production production = new Production();
- production.addAll(emptyResources);
- assertTrue(production.contains(emptyResources));
- }
-
- @Test
- public void addAll_singleResource() {
- Production production = new Production();
- production.addAll(resources1Stone);
- assertTrue(production.contains(resources1Stone));
- }
-
- @Test
- public void addAll_multipleResources() {
- Production production = new Production();
- production.addAll(resources2Stones3Clay);
- assertTrue(production.contains(resources2Stones3Clay));
- }
-
- @Test
- public void addAll_production_multipleFixedResources() {
- Production production = new Production();
- production.addAll(resources2Stones3Clay);
-
- Production production2 = new Production();
- production2.addAll(production);
-
- assertTrue(production2.contains(resources2Stones3Clay));
- }
-
- @Test
- public void addAll_production_multipleChoices() {
- Production production = new Production();
- production.addChoice(ResourceType.STONE, ResourceType.WOOD);
- production.addChoice(ResourceType.STONE, ResourceType.ORE);
-
- Production production2 = new Production();
- production2.addAll(production);
- assertTrue(production.contains(resources1Stone1Wood));
- }
-
- @Test
- public void addAll_production_mixedFixedResourcesAndChoices() {
- Production production = new Production();
- production.addFixedResource(ResourceType.WOOD, 1);
- production.addChoice(ResourceType.STONE, ResourceType.WOOD);
-
- Production production2 = new Production();
- production2.addAll(production);
-
- assertTrue(production.contains(resources1Stone1Wood));
- }
-
- @Test
- public void asChoices_empty() {
- Production production = new Production();
- assertTrue(production.asChoices().isEmpty());
- }
-
- @Test
- public void asChoices_onlyChoices() {
- Production production = new Production();
- production.addChoice(ResourceType.STONE, ResourceType.WOOD);
- production.addChoice(ResourceType.STONE, ResourceType.ORE);
- production.addChoice(ResourceType.CLAY, ResourceType.LOOM, ResourceType.GLASS);
- assertEquals(production.getAlternativeResources(), production.asChoices());
- }
-
- @Test
- public void asChoices_onlyFixed() {
- Production production = new Production();
- production.addFixedResource(ResourceType.WOOD, 1);
- production.addFixedResource(ResourceType.CLAY, 2);
-
- Set<Set<ResourceType>> expected = new HashSet<>();
- expected.add(EnumSet.of(ResourceType.WOOD));
- expected.add(EnumSet.of(ResourceType.CLAY));
- expected.add(EnumSet.of(ResourceType.CLAY));
-
- assertEquals(expected, production.asChoices());
- }
-
- @Test
- public void asChoices_mixed() {
- Production production = new Production();
- production.addChoice(ResourceType.STONE, ResourceType.ORE);
- production.addChoice(ResourceType.CLAY, ResourceType.LOOM, ResourceType.GLASS);
- production.addFixedResource(ResourceType.WOOD, 1);
- production.addFixedResource(ResourceType.CLAY, 2);
-
- Set<Set<ResourceType>> expected = new HashSet<>();
- expected.add(EnumSet.of(ResourceType.STONE, ResourceType.ORE));
- expected.add(EnumSet.of(ResourceType.CLAY, ResourceType.LOOM, ResourceType.GLASS));
- expected.add(EnumSet.of(ResourceType.WOOD));
- expected.add(EnumSet.of(ResourceType.CLAY));
- expected.add(EnumSet.of(ResourceType.CLAY));
-
- assertEquals(expected, production.asChoices());
- }
-
- @Test
- public void equals_falseWhenNull() {
- Production production = new Production();
- production.addFixedResource(ResourceType.GLASS, 1);
- production.addChoice(ResourceType.ORE, ResourceType.WOOD);
- //noinspection ObjectEqualsNull
- assertFalse(production.equals(null));
- }
-
- @Test
- public void equals_falseWhenDifferentClass() {
- Production production = new Production();
- production.addFixedResource(ResourceType.GLASS, 1);
- Resources resources = new Resources();
- resources.add(ResourceType.GLASS, 1);
- //noinspection EqualsBetweenInconvertibleTypes
- assertFalse(production.equals(resources));
- }
-
- @Test
- public void equals_trueWhenSame() {
- Production production = new Production();
- assertEquals(production, production);
- }
-
- @Test
- public void equals_trueWhenSameContent() {
- Production production1 = new Production();
- Production production2 = new Production();
- assertTrue(production1.equals(production2));
- production1.addFixedResource(ResourceType.GLASS, 1);
- production2.addFixedResource(ResourceType.GLASS, 1);
- assertTrue(production1.equals(production2));
- production1.addChoice(ResourceType.ORE, ResourceType.WOOD);
- production2.addChoice(ResourceType.ORE, ResourceType.WOOD);
- assertTrue(production1.equals(production2));
- }
-
- @Test
- public void hashCode_sameWhenSameContent() {
- Production production1 = new Production();
- Production production2 = new Production();
- assertEquals(production1.hashCode(), production2.hashCode());
- production1.addFixedResource(ResourceType.GLASS, 1);
- production2.addFixedResource(ResourceType.GLASS, 1);
- assertEquals(production1.hashCode(), production2.hashCode());
- production1.addChoice(ResourceType.ORE, ResourceType.WOOD);
- production2.addChoice(ResourceType.ORE, ResourceType.WOOD);
- assertEquals(production1.hashCode(), production2.hashCode());
- }
-}
diff --git a/game-engine/src/test/java/org/luxons/sevenwonders/game/resources/ResourceTransactionsTest.java b/game-engine/src/test/java/org/luxons/sevenwonders/game/resources/ResourceTransactionsTest.java
deleted file mode 100644
index 775973b5..00000000
--- a/game-engine/src/test/java/org/luxons/sevenwonders/game/resources/ResourceTransactionsTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.luxons.sevenwonders.game.resources;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.junit.Test;
-import org.luxons.sevenwonders.game.test.TestUtilsKt;
-
-import static org.junit.Assert.assertEquals;
-
-public class ResourceTransactionsTest {
-
- @Test
- public void toTransactions() {
- List<ResourceTransaction> transactionList = new ArrayList<>();
- transactionList.add(TestUtilsKt.createTransaction(Provider.LEFT_PLAYER, ResourceType.WOOD));
- transactionList.add(TestUtilsKt.createTransaction(Provider.LEFT_PLAYER, ResourceType.CLAY));
- transactionList.add(TestUtilsKt.createTransaction(Provider.RIGHT_PLAYER, ResourceType.WOOD));
-
- ResourceTransactions transactions = new ResourceTransactions(transactionList);
-
- Set<ResourceTransaction> expectedNormalized = new HashSet<>();
- expectedNormalized.add(
- TestUtilsKt.createTransaction(Provider.LEFT_PLAYER, ResourceType.WOOD, ResourceType.CLAY));
- expectedNormalized.add(TestUtilsKt.createTransaction(Provider.RIGHT_PLAYER, ResourceType.WOOD));
-
- assertEquals(expectedNormalized, new HashSet<>(transactions.toTransactions()));
- }
-
- @Test(expected = IllegalStateException.class)
- public void remove_failsIfNoResourceForThatProvider() {
- ResourceTransactions transactions = new ResourceTransactions();
- transactions.remove(Provider.LEFT_PLAYER, Resources.of(ResourceType.WOOD));
- }
-}
diff --git a/game-engine/src/test/java/org/luxons/sevenwonders/game/resources/ResourcesTest.java b/game-engine/src/test/java/org/luxons/sevenwonders/game/resources/ResourcesTest.java
deleted file mode 100644
index 1f260a11..00000000
--- a/game-engine/src/test/java/org/luxons/sevenwonders/game/resources/ResourcesTest.java
+++ /dev/null
@@ -1,485 +0,0 @@
-package org.luxons.sevenwonders.game.resources;
-
-import java.util.NoSuchElementException;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-public class ResourcesTest {
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- @Test
- public void init_shouldBeEmpty() {
- Resources resources = new Resources();
- for (ResourceType resourceType : ResourceType.values()) {
- assertEquals(0, resources.getQuantity(resourceType));
- }
- assertEquals(0, resources.size());
- assertTrue(resources.isEmpty());
- }
-
- @Test
- public void add_zero() {
- Resources resources = new Resources();
- resources.add(ResourceType.CLAY, 0);
- assertEquals(0, resources.getQuantity(ResourceType.CLAY));
- assertEquals(0, resources.size());
- assertTrue(resources.isEmpty());
- }
-
- @Test
- public void add_simple() {
- Resources resources = new Resources();
- resources.add(ResourceType.WOOD, 3);
- assertEquals(3, resources.getQuantity(ResourceType.WOOD));
- assertEquals(3, resources.size());
- assertFalse(resources.isEmpty());
- }
-
- @Test
- public void add_multipleCallsStacked() {
- Resources resources = new Resources();
- resources.add(ResourceType.ORE, 3);
- resources.add(ResourceType.ORE, 2);
- assertEquals(5, resources.getQuantity(ResourceType.ORE));
- assertEquals(5, resources.size());
- assertFalse(resources.isEmpty());
- }
-
- @Test
- public void add_interlaced() {
- Resources resources = new Resources();
- resources.add(ResourceType.GLASS, 3);
- resources.add(ResourceType.STONE, 1);
- resources.add(ResourceType.WOOD, 4);
- resources.add(ResourceType.GLASS, 2);
- assertEquals(5, resources.getQuantity(ResourceType.GLASS));
- assertEquals(10, resources.size());
- assertFalse(resources.isEmpty());
- }
-
- @Test
- public void remove_some() {
- Resources resources = new Resources();
- resources.add(ResourceType.WOOD, 3);
- resources.remove(ResourceType.WOOD, 2);
- assertEquals(1, resources.getQuantity(ResourceType.WOOD));
- assertEquals(1, resources.size());
- assertFalse(resources.isEmpty());
- }
-
- @Test
- public void remove_all() {
- Resources resources = new Resources();
- resources.add(ResourceType.WOOD, 3);
- resources.remove(ResourceType.WOOD, 3);
- assertEquals(0, resources.getQuantity(ResourceType.WOOD));
- assertEquals(0, resources.size());
- assertTrue(resources.isEmpty());
- }
-
- @Test
- public void remove_tooMany() {
- Resources resources = new Resources();
- resources.add(ResourceType.WOOD, 2);
-
- thrown.expect(NoSuchElementException.class);
- resources.remove(ResourceType.WOOD, 3);
- }
-
- @Test
- public void addAll_empty() {
- Resources resources = new Resources();
- resources.add(ResourceType.STONE, 1);
- resources.add(ResourceType.CLAY, 3);
-
- Resources emptyResources = new Resources();
-
- resources.addAll(emptyResources);
- assertEquals(1, resources.getQuantity(ResourceType.STONE));
- assertEquals(3, resources.getQuantity(ResourceType.CLAY));
- assertEquals(0, resources.getQuantity(ResourceType.ORE));
- assertEquals(0, resources.getQuantity(ResourceType.GLASS));
- assertEquals(0, resources.getQuantity(ResourceType.LOOM));
- assertEquals(4, resources.size());
- assertFalse(resources.isEmpty());
- }
-
- @Test
- public void addAll_zeros() {
- Resources resources = new Resources();
- resources.add(ResourceType.STONE, 1);
- resources.add(ResourceType.CLAY, 3);
-
- Resources emptyResources = new Resources();
- emptyResources.add(ResourceType.STONE, 0);
- emptyResources.add(ResourceType.CLAY, 0);
-
- resources.addAll(emptyResources);
- assertEquals(1, resources.getQuantity(ResourceType.STONE));
- assertEquals(3, resources.getQuantity(ResourceType.CLAY));
- assertEquals(0, resources.getQuantity(ResourceType.ORE));
- assertEquals(0, resources.getQuantity(ResourceType.GLASS));
- assertEquals(0, resources.getQuantity(ResourceType.LOOM));
- assertEquals(4, resources.size());
- assertFalse(resources.isEmpty());
- }
-
- @Test
- public void addAll_same() {
- Resources resources = new Resources();
- resources.add(ResourceType.STONE, 1);
- resources.add(ResourceType.CLAY, 3);
-
- Resources resources2 = new Resources();
- resources.add(ResourceType.STONE, 2);
- resources.add(ResourceType.CLAY, 6);
-
- resources.addAll(resources2);
- assertEquals(3, resources.getQuantity(ResourceType.STONE));
- assertEquals(9, resources.getQuantity(ResourceType.CLAY));
- assertEquals(0, resources.getQuantity(ResourceType.ORE));
- assertEquals(0, resources.getQuantity(ResourceType.GLASS));
- assertEquals(0, resources.getQuantity(ResourceType.LOOM));
- assertEquals(12, resources.size());
- assertFalse(resources.isEmpty());
- }
-
- @Test
- public void addAll_overlap() {
- Resources resources = new Resources();
- resources.add(ResourceType.STONE, 1);
- resources.add(ResourceType.CLAY, 3);
-
- Resources resources2 = new Resources();
- resources.add(ResourceType.CLAY, 6);
- resources.add(ResourceType.ORE, 4);
-
- resources.addAll(resources2);
- assertEquals(1, resources.getQuantity(ResourceType.STONE));
- assertEquals(9, resources.getQuantity(ResourceType.CLAY));
- assertEquals(4, resources.getQuantity(ResourceType.ORE));
- assertEquals(0, resources.getQuantity(ResourceType.GLASS));
- assertEquals(0, resources.getQuantity(ResourceType.LOOM));
- assertEquals(14, resources.size());
- assertFalse(resources.isEmpty());
- }
-
- @Test
- public void contains_emptyContainsEmpty() {
- Resources emptyResources = new Resources();
- Resources emptyResources2 = new Resources();
- assertTrue(emptyResources.contains(emptyResources2));
- }
-
- @Test
- public void contains_singleTypeContainsEmpty() {
- Resources resources = new Resources();
- resources.add(ResourceType.STONE, 1);
-
- Resources emptyResources = new Resources();
-
- assertTrue(resources.contains(emptyResources));
- }
-
- @Test
- public void contains_multipleTypesContainsEmpty() {
- Resources resources = new Resources();
- resources.add(ResourceType.STONE, 1);
- resources.add(ResourceType.CLAY, 3);
-
- Resources emptyResources = new Resources();
-
- assertTrue(resources.contains(emptyResources));
- }
-
- @Test
- public void contains_self() {
- Resources resources = new Resources();
- resources.add(ResourceType.STONE, 1);
- resources.add(ResourceType.CLAY, 3);
-
- assertTrue(resources.contains(resources));
- }
-
- @Test
- public void contains_allOfEachType() {
- Resources resources = new Resources();
- resources.add(ResourceType.STONE, 1);
- resources.add(ResourceType.CLAY, 3);
-
- Resources resources2 = new Resources();
- resources2.add(ResourceType.STONE, 1);
- resources2.add(ResourceType.CLAY, 3);
-
- assertTrue(resources.contains(resources2));
- }
-
- @Test
- public void contains_someOfEachType() {
- Resources resources = new Resources();
- resources.add(ResourceType.STONE, 2);
- resources.add(ResourceType.CLAY, 4);
-
- Resources resources2 = new Resources();
- resources2.add(ResourceType.STONE, 1);
- resources2.add(ResourceType.CLAY, 3);
-
- assertTrue(resources.contains(resources2));
- }
-
- @Test
- public void contains_someOfSomeTypes() {
- Resources resources = new Resources();
- resources.add(ResourceType.STONE, 2);
- resources.add(ResourceType.CLAY, 4);
-
- Resources resources2 = new Resources();
- resources2.add(ResourceType.CLAY, 3);
-
- assertTrue(resources.contains(resources2));
- }
-
- @Test
- public void contains_allOfSomeTypes() {
- Resources resources = new Resources();
- resources.add(ResourceType.STONE, 2);
- resources.add(ResourceType.CLAY, 4);
-
- Resources resources2 = new Resources();
- resources2.add(ResourceType.CLAY, 4);
-
- assertTrue(resources.contains(resources2));
- }
-
- @Test
- public void minus_empty() {
- Resources resources = new Resources();
- resources.add(ResourceType.STONE, 1);
- resources.add(ResourceType.CLAY, 3);
-
- Resources emptyResources = new Resources();
-
- Resources diff = resources.minus(emptyResources);
- assertEquals(1, diff.getQuantity(ResourceType.STONE));
- assertEquals(3, diff.getQuantity(ResourceType.CLAY));
- assertEquals(0, diff.getQuantity(ResourceType.ORE));
- assertEquals(0, diff.getQuantity(ResourceType.GLASS));
- assertEquals(0, diff.getQuantity(ResourceType.LOOM));
- }
-
- @Test
- public void minus_self() {
- Resources resources = new Resources();
- resources.add(ResourceType.STONE, 1);
- resources.add(ResourceType.CLAY, 3);
-
- Resources diff = resources.minus(resources);
- assertEquals(0, diff.getQuantity(ResourceType.STONE));
- assertEquals(0, diff.getQuantity(ResourceType.CLAY));
- assertEquals(0, diff.getQuantity(ResourceType.ORE));
- assertEquals(0, diff.getQuantity(ResourceType.GLASS));
- assertEquals(0, diff.getQuantity(ResourceType.LOOM));
- }
-
- @Test
- public void minus_allOfEachType() {
- Resources resources = new Resources();
- resources.add(ResourceType.STONE, 1);
- resources.add(ResourceType.CLAY, 3);
-
- Resources resources2 = new Resources();
- resources2.add(ResourceType.STONE, 1);
- resources2.add(ResourceType.CLAY, 3);
-
- Resources diff = resources.minus(resources2);
- assertEquals(0, diff.getQuantity(ResourceType.STONE));
- assertEquals(0, diff.getQuantity(ResourceType.CLAY));
- assertEquals(0, diff.getQuantity(ResourceType.ORE));
- assertEquals(0, diff.getQuantity(ResourceType.GLASS));
- assertEquals(0, diff.getQuantity(ResourceType.LOOM));
- }
-
- @Test
- public void minus_someOfEachType() {
- Resources resources = new Resources();
- resources.add(ResourceType.STONE, 2);
- resources.add(ResourceType.CLAY, 4);
-
- Resources resources2 = new Resources();
- resources2.add(ResourceType.STONE, 1);
- resources2.add(ResourceType.CLAY, 3);
-
- Resources diff = resources.minus(resources2);
- assertEquals(1, diff.getQuantity(ResourceType.STONE));
- assertEquals(1, diff.getQuantity(ResourceType.CLAY));
- assertEquals(0, diff.getQuantity(ResourceType.ORE));
- assertEquals(0, diff.getQuantity(ResourceType.GLASS));
- assertEquals(0, diff.getQuantity(ResourceType.LOOM));
- }
-
- @Test
- public void minus_someOfSomeTypes() {
- Resources resources = new Resources();
- resources.add(ResourceType.STONE, 2);
- resources.add(ResourceType.CLAY, 4);
-
- Resources resources2 = new Resources();
- resources2.add(ResourceType.CLAY, 3);
-
- Resources diff = resources.minus(resources2);
- assertEquals(2, diff.getQuantity(ResourceType.STONE));
- assertEquals(1, diff.getQuantity(ResourceType.CLAY));
- assertEquals(0, diff.getQuantity(ResourceType.ORE));
- assertEquals(0, diff.getQuantity(ResourceType.GLASS));
- assertEquals(0, diff.getQuantity(ResourceType.LOOM));
- }
-
- @Test
- public void minus_allOfSomeTypes() {
- Resources resources = new Resources();
- resources.add(ResourceType.STONE, 2);
- resources.add(ResourceType.CLAY, 4);
-
- Resources resources2 = new Resources();
- resources2.add(ResourceType.CLAY, 4);
-
- Resources diff = resources.minus(resources2);
- assertEquals(2, diff.getQuantity(ResourceType.STONE));
- assertEquals(0, diff.getQuantity(ResourceType.CLAY));
- assertEquals(0, diff.getQuantity(ResourceType.ORE));
- assertEquals(0, diff.getQuantity(ResourceType.GLASS));
- assertEquals(0, diff.getQuantity(ResourceType.LOOM));
- }
-
- @Test
- public void minus_tooMuchOfExistingType() {
- Resources resources = new Resources();
- resources.add(ResourceType.CLAY, 4);
-
- Resources resources2 = new Resources();
- resources2.add(ResourceType.CLAY, 5);
-
- Resources diff = resources.minus(resources2);
- assertEquals(0, diff.getQuantity(ResourceType.CLAY));
- }
-
- @Test
- public void minus_someOfAnAbsentType() {
- Resources resources = new Resources();
-
- Resources resources2 = new Resources();
- resources2.add(ResourceType.LOOM, 5);
-
- Resources diff = resources.minus(resources2);
- assertEquals(0, diff.getQuantity(ResourceType.LOOM));
- }
-
- @Test
- public void minus_someOfATypeWithZero() {
- Resources resources = new Resources();
- resources.add(ResourceType.LOOM, 0);
-
- Resources resources2 = new Resources();
- resources2.add(ResourceType.LOOM, 5);
-
- Resources diff = resources.minus(resources2);
- assertEquals(0, diff.getQuantity(ResourceType.LOOM));
- }
-
- @Test
- public void isEmpty_noElement() {
- Resources resources = new Resources();
- assertTrue(resources.isEmpty());
- }
-
- @Test
- public void isEmpty_singleZeroElement() {
- Resources resources = new Resources();
- resources.add(ResourceType.LOOM, 0);
- assertTrue(resources.isEmpty());
- }
-
- @Test
- public void isEmpty_multipleZeroElements() {
- Resources resources = new Resources();
- resources.add(ResourceType.WOOD, 0);
- resources.add(ResourceType.ORE, 0);
- resources.add(ResourceType.LOOM, 0);
- assertTrue(resources.isEmpty());
- }
-
- @Test
- public void isEmpty_singleElementMoreThanZero() {
- Resources resources = new Resources();
- resources.add(ResourceType.LOOM, 3);
- assertFalse(resources.isEmpty());
- }
-
- @Test
- public void isEmpty_mixedZeroAndNonZeroElements() {
- Resources resources = new Resources();
- resources.add(ResourceType.WOOD, 0);
- resources.add(ResourceType.LOOM, 3);
- assertFalse(resources.isEmpty());
- }
-
- @Test
- public void isEmpty_mixedZeroAndNonZeroElements_reverseOrder() {
- Resources resources = new Resources();
- resources.add(ResourceType.ORE, 3);
- resources.add(ResourceType.PAPYRUS, 0);
- assertFalse(resources.isEmpty());
- }
-
- @Test
- public void equals_falseWhenNull() {
- Resources resources = new Resources();
- resources.add(ResourceType.GLASS, 1);
- //noinspection ObjectEqualsNull
- assertFalse(resources.equals(null));
- }
-
- @Test
- public void equals_falseWhenDifferentClass() {
- Resources resources = new Resources();
- resources.add(ResourceType.GLASS, 1);
- Production production = new Production();
- production.addFixedResource(ResourceType.GLASS, 1);
- //noinspection EqualsBetweenInconvertibleTypes
- assertFalse(resources.equals(production));
- }
-
- @Test
- public void equals_trueWhenSame() {
- Resources resources = new Resources();
- assertEquals(resources, resources);
- }
-
- @Test
- public void equals_trueWhenSameContent() {
- Resources resources1 = new Resources();
- Resources resources2 = new Resources();
- assertTrue(resources1.equals(resources2));
- resources1.add(ResourceType.GLASS, 1);
- resources2.add(ResourceType.GLASS, 1);
- assertTrue(resources1.equals(resources2));
- }
-
- @Test
- public void hashCode_sameWhenSameContent() {
- Resources resources1 = new Resources();
- Resources resources2 = new Resources();
- assertEquals(resources1.hashCode(), resources2.hashCode());
- resources1.add(ResourceType.GLASS, 1);
- resources2.add(ResourceType.GLASS, 1);
- assertEquals(resources1.hashCode(), resources2.hashCode());
- }
-}
diff --git a/game-engine/src/test/java/org/luxons/sevenwonders/game/resources/TradingRulesTest.java b/game-engine/src/test/java/org/luxons/sevenwonders/game/resources/TradingRulesTest.java
deleted file mode 100644
index 3c447753..00000000
--- a/game-engine/src/test/java/org/luxons/sevenwonders/game/resources/TradingRulesTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package org.luxons.sevenwonders.game.resources;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.junit.experimental.theories.DataPoints;
-import org.junit.experimental.theories.Theories;
-import org.junit.experimental.theories.Theory;
-import org.junit.runner.RunWith;
-import org.luxons.sevenwonders.game.test.TestUtilsKt;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assume.assumeTrue;
-
-@RunWith(Theories.class)
-public class TradingRulesTest {
-
- @DataPoints
- public static int[] costs() {
- return new int[]{0, 1, 2};
- }
-
- @DataPoints
- public static Provider[] providers() {
- return Provider.values();
- }
-
- @DataPoints
- public static ResourceType[] resourceTypes() {
- return ResourceType.values();
- }
-
- @Theory
- public void setCost_overridesCost(int defaultCost, int overriddenCost, Provider overriddenProvider,
- Provider provider, ResourceType type) {
- assumeTrue(defaultCost != overriddenCost);
- assumeTrue(overriddenProvider != provider);
-
- TradingRules rules = new TradingRules(defaultCost);
- rules.setCost(type, overriddenProvider, overriddenCost);
-
- assertEquals(overriddenCost, rules.getCost(type, overriddenProvider));
- assertEquals(defaultCost, rules.getCost(type, provider));
- }
-
- @Theory
- public void computeCost_zeroForNoResources(int defaultCost) {
- TradingRules rules = new TradingRules(defaultCost);
- assertEquals(0, rules.computeCost(new ResourceTransactions()));
- }
-
- @Theory
- public void computeCost_defaultCostWhenNoOverride(int defaultCost, Provider provider, ResourceType type) {
- TradingRules rules = new TradingRules(defaultCost);
- ResourceTransactions transactions = TestUtilsKt.createTransactions(provider, type);
- assertEquals(defaultCost, rules.computeCost(transactions));
- }
-
- @Theory
- public void computeCost_twiceDefaultFor2Resources(int defaultCost, Provider provider, ResourceType type) {
- TradingRules rules = new TradingRules(defaultCost);
- ResourceTransactions transactions = TestUtilsKt.createTransactions(provider, type, type);
- assertEquals(2 * defaultCost, rules.computeCost(transactions));
- }
-
- @Theory
- public void computeCost_overriddenCost(int defaultCost, int overriddenCost, Provider provider, ResourceType type) {
- TradingRules rules = new TradingRules(defaultCost);
- rules.setCost(type, provider, overriddenCost);
- ResourceTransactions transactions = TestUtilsKt.createTransactions(provider, type);
- assertEquals(overriddenCost, rules.computeCost(transactions));
- }
-
- @Theory
- public void computeCost_defaultCostWhenOverrideOnOtherProviderOrType(int defaultCost, int overriddenCost,
- Provider overriddenProvider,
- ResourceType overriddenType, Provider provider,
- ResourceType type) {
- assumeTrue(overriddenProvider != provider || overriddenType != type);
- TradingRules rules = new TradingRules(defaultCost);
- rules.setCost(overriddenType, overriddenProvider, overriddenCost);
- ResourceTransactions transactions = TestUtilsKt.createTransactions(provider, type);
- assertEquals(defaultCost, rules.computeCost(transactions));
- }
-
- @Theory
- public void computeCost_oneDefaultAndOneOverriddenType(int defaultCost, int overriddenCost,
- ResourceType overriddenType, Provider provider,
- ResourceType type) {
- assumeTrue(overriddenType != type);
- TradingRules rules = new TradingRules(defaultCost);
- rules.setCost(overriddenType, provider, overriddenCost);
- ResourceTransactions transactions = TestUtilsKt.createTransactions(provider, overriddenType, type);
- assertEquals(defaultCost + overriddenCost, rules.computeCost(transactions));
- }
-
- @Theory
- public void computeCost_oneDefaultAndOneOverriddenProvider(int defaultCost, int overriddenCost,
- Provider overriddenProvider, Provider provider,
- ResourceType type) {
- assumeTrue(overriddenProvider != provider);
- TradingRules rules = new TradingRules(defaultCost);
- rules.setCost(type, overriddenProvider, overriddenCost);
-
- List<ResourceTransaction> boughtResources = new ArrayList<>(2);
- boughtResources.add(TestUtilsKt.createTransaction(provider, type));
- boughtResources.add(TestUtilsKt.createTransaction(overriddenProvider, type));
-
- assertEquals(defaultCost + overriddenCost, rules.computeCost(new ResourceTransactions(boughtResources)));
- }
-}
diff --git a/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/moves/BuildWonderMoveTest.kt b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/moves/BuildWonderMoveTest.kt
new file mode 100644
index 00000000..ee461e38
--- /dev/null
+++ b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/moves/BuildWonderMoveTest.kt
@@ -0,0 +1,76 @@
+package org.luxons.sevenwonders.game.moves
+
+import org.junit.Assert.assertEquals
+import org.junit.Assert.fail
+import org.junit.Test
+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.test.createMove
+import org.luxons.sevenwonders.game.test.sampleCards
+import org.luxons.sevenwonders.game.test.testCard
+import org.luxons.sevenwonders.game.test.testSettings
+import org.luxons.sevenwonders.game.test.testTable
+
+class BuildWonderMoveTest {
+
+ @Test(expected = InvalidMoveException::class)
+ fun validate_failsWhenCardNotInHand() {
+ val table = testTable(3)
+ val hand = sampleCards(0, 7)
+ val anotherCard = testCard("Card that is not in the hand")
+ val move = createMove(0, anotherCard, MoveType.UPGRADE_WONDER)
+
+ move.validate(table, hand)
+ }
+
+ @Test(expected = InvalidMoveException::class)
+ fun validate_failsWhenWonderIsCompletelyBuilt() {
+ val settings = testSettings(3)
+ val table = testTable(settings)
+ val hand = sampleCards(0, 7)
+
+ fillPlayerWonderLevels(settings, table, hand)
+
+ // should fail because the wonder is already full
+ buildOneWonderLevel(settings, table, hand, 4)
+ }
+
+ private fun fillPlayerWonderLevels(settings: Settings, table: Table, hand: List<Card>) {
+ try {
+ val nbLevels = table.getBoard(0).wonder.stages.size
+ for (i in 0 until nbLevels) {
+ buildOneWonderLevel(settings, table, hand, i)
+ }
+ } catch (e: InvalidMoveException) {
+ fail("Building wonder levels should not fail before being full")
+ }
+ }
+
+ private fun buildOneWonderLevel(settings: Settings, table: Table, hand: List<Card>, cardIndex: Int) {
+ val card = hand[cardIndex]
+ val move = createMove(0, card, MoveType.UPGRADE_WONDER)
+ move.validate(table, hand)
+ move.place(table, mutableListOf(), settings)
+ move.activate(table, emptyList(), settings)
+ }
+
+ @Test
+ fun place_increasesWonderLevel() {
+ val settings = testSettings(3)
+ val table = testTable(settings)
+ val hand = sampleCards(0, 7)
+ val cardToUse = hand[0]
+ val move = createMove(0, cardToUse, MoveType.UPGRADE_WONDER)
+ move.validate(table, hand) // should not fail
+
+ val initialStage = table.getBoard(0).wonder.nbBuiltStages
+
+ move.place(table, mutableListOf(), settings)
+
+ val newStage = table.getBoard(0).wonder.nbBuiltStages
+
+ // we need to see the level increase before activation so that other players
+ assertEquals((initialStage + 1).toLong(), newStage.toLong())
+ }
+}
diff --git a/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/BestPriceCalculatorTest.kt b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/BestPriceCalculatorTest.kt
new file mode 100644
index 00000000..f4cf5294
--- /dev/null
+++ b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/BestPriceCalculatorTest.kt
@@ -0,0 +1,129 @@
+package org.luxons.sevenwonders.game.resources
+
+import java.util.Arrays
+
+import org.junit.Test
+import org.luxons.sevenwonders.game.api.Table
+import org.luxons.sevenwonders.game.boards.Board
+import org.luxons.sevenwonders.game.test.*
+
+import org.junit.Assert.assertEquals
+import org.luxons.sevenwonders.game.resources.Provider.LEFT_PLAYER
+import org.luxons.sevenwonders.game.resources.Provider.RIGHT_PLAYER
+import org.luxons.sevenwonders.game.resources.ResourceType.CLAY
+import org.luxons.sevenwonders.game.resources.ResourceType.GLASS
+import org.luxons.sevenwonders.game.resources.ResourceType.ORE
+import org.luxons.sevenwonders.game.resources.ResourceType.STONE
+import org.luxons.sevenwonders.game.resources.ResourceType.WOOD
+
+class BestPriceCalculatorTest {
+
+ @Test
+ fun bestPrice_0forEmptyResources() {
+ val table = testTable(3)
+ val resources = Resources()
+ assertEquals(0, BestPriceCalculator.bestPrice(resources, table, 0).toLong())
+ assertEquals(ResourceTransactions(), BestPriceCalculator.bestSolution(resources, table, 0))
+ }
+
+ @Test
+ fun bestPrice_fixedResources_defaultCost() {
+ val left = testBoard(STONE)
+ val main = testBoard(STONE)
+ val right = testBoard(WOOD)
+ val table = Table(Arrays.asList(main, right, left))
+
+ val resources = createResources(STONE, STONE)
+ assertEquals(2, BestPriceCalculator.bestPrice(resources, table, 0).toLong())
+ assertEquals(4, BestPriceCalculator.bestPrice(resources, table, 1).toLong())
+ assertEquals(2, BestPriceCalculator.bestPrice(resources, table, 2).toLong())
+
+ val stoneLeftSingle = createTransaction(LEFT_PLAYER, STONE)
+ val stoneRightSingle = createTransaction(RIGHT_PLAYER, STONE)
+
+ val stoneLeft = createTransactions(stoneLeftSingle)
+ val stoneRight = createTransactions(stoneRightSingle)
+ val stoneLeftAndRight = createTransactions(stoneLeftSingle, stoneRightSingle)
+
+ assertEquals(stoneLeft, BestPriceCalculator.bestSolution(resources, table, 0))
+ assertEquals(stoneLeftAndRight, BestPriceCalculator.bestSolution(resources, table, 1))
+ assertEquals(stoneRight, BestPriceCalculator.bestSolution(resources, table, 2))
+ }
+
+ @Test
+ fun bestPrice_fixedResources_overridenCost() {
+ val main = testBoard(STONE)
+ main.tradingRules.setCost(WOOD, RIGHT_PLAYER, 1)
+
+ val left = testBoard(WOOD)
+ val right = testBoard(WOOD)
+ val opposite = testBoard(GLASS)
+ val table = Table(Arrays.asList(main, right, opposite, left))
+
+ val resources = createResources(WOOD)
+ assertEquals(1, BestPriceCalculator.bestPrice(resources, table, 0).toLong())
+ assertEquals(0, BestPriceCalculator.bestPrice(resources, table, 1).toLong())
+ assertEquals(2, BestPriceCalculator.bestPrice(resources, table, 2).toLong())
+ assertEquals(0, BestPriceCalculator.bestPrice(resources, table, 3).toLong())
+
+ val woodLeft = createTransactions(LEFT_PLAYER, WOOD)
+ val woodRight = createTransactions(RIGHT_PLAYER, WOOD)
+ assertEquals(woodRight, BestPriceCalculator.bestSolution(resources, table, 0))
+ assertEquals(ResourceTransactions(), BestPriceCalculator.bestSolution(resources, table, 1))
+ assertEquals(woodLeft, BestPriceCalculator.bestSolution(resources, table, 2))
+ assertEquals(ResourceTransactions(), BestPriceCalculator.bestSolution(resources, table, 3))
+ }
+
+ @Test
+ fun bestPrice_mixedResources_overridenCost() {
+ val left = testBoard(WOOD)
+
+ val main = testBoard(STONE)
+ main.tradingRules.setCost(WOOD, RIGHT_PLAYER, 1)
+
+ val right = testBoard(ORE)
+ right.production.addChoice(WOOD, CLAY)
+ right.publicProduction.addChoice(WOOD, CLAY)
+
+ val table = Table(Arrays.asList(main, right, left))
+
+ val resources = createResources(WOOD)
+ assertEquals(1, BestPriceCalculator.bestPrice(resources, table, 0).toLong())
+ assertEquals(0, BestPriceCalculator.bestPrice(resources, table, 1).toLong())
+ assertEquals(0, BestPriceCalculator.bestPrice(resources, table, 2).toLong())
+
+ val woodRight = createTransactions(RIGHT_PLAYER, WOOD)
+
+ assertEquals(woodRight, BestPriceCalculator.bestSolution(resources, table, 0))
+ assertEquals(ResourceTransactions(), BestPriceCalculator.bestSolution(resources, table, 1))
+ assertEquals(ResourceTransactions(), BestPriceCalculator.bestSolution(resources, table, 2))
+ }
+
+ @Test
+ fun bestPrice_chooseCheapest() {
+ val left = testBoard(WOOD)
+
+ val main = testBoard(WOOD)
+ main.production.addChoice(CLAY, ORE)
+ main.tradingRules.setCost(CLAY, RIGHT_PLAYER, 1)
+
+ val right = testBoard(WOOD)
+ right.production.addFixedResource(ORE, 1)
+ right.production.addFixedResource(CLAY, 1)
+ right.publicProduction.addFixedResource(ORE, 1)
+ right.publicProduction.addFixedResource(CLAY, 1)
+
+ val table = Table(Arrays.asList(main, right, left))
+
+ val resources = createResources(ORE, CLAY)
+ assertEquals(1, BestPriceCalculator.bestPrice(resources, table, 0).toLong())
+ assertEquals(0, BestPriceCalculator.bestPrice(resources, table, 1).toLong())
+ assertEquals(4, BestPriceCalculator.bestPrice(resources, table, 2).toLong())
+
+ val oreAndClayLeft = createTransactions(LEFT_PLAYER, ORE, CLAY)
+ val clayRight = createTransactions(RIGHT_PLAYER, CLAY)
+ assertEquals(clayRight, BestPriceCalculator.bestSolution(resources, table, 0))
+ assertEquals(ResourceTransactions(), BestPriceCalculator.bestSolution(resources, table, 1))
+ assertEquals(oreAndClayLeft, BestPriceCalculator.bestSolution(resources, table, 2))
+ }
+}
diff --git a/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/ProductionTest.kt b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/ProductionTest.kt
new file mode 100644
index 00000000..27f85c1a
--- /dev/null
+++ b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/ProductionTest.kt
@@ -0,0 +1,323 @@
+package org.luxons.sevenwonders.game.resources
+
+import java.util.EnumSet
+import java.util.HashSet
+
+import org.junit.Before
+import org.junit.Test
+
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+
+class ProductionTest {
+
+ private var emptyResources: Resources? = null
+
+ private var resources1Wood: Resources? = null
+
+ private var resources1Stone: Resources? = null
+
+ private var resources1Stone1Wood: Resources? = null
+
+ private var resources2Stones: Resources? = null
+
+ private var resources2Stones3Clay: Resources? = null
+
+ @Before
+ fun init() {
+ emptyResources = Resources()
+
+ resources1Wood = Resources()
+ resources1Wood!!.add(ResourceType.WOOD, 1)
+
+ resources1Stone = Resources()
+ resources1Stone!!.add(ResourceType.STONE, 1)
+
+ resources1Stone1Wood = Resources()
+ resources1Stone1Wood!!.add(ResourceType.STONE, 1)
+ resources1Stone1Wood!!.add(ResourceType.WOOD, 1)
+
+ resources2Stones = Resources()
+ resources2Stones!!.add(ResourceType.STONE, 2)
+
+ resources2Stones3Clay = Resources()
+ resources2Stones3Clay!!.add(ResourceType.STONE, 2)
+ resources2Stones3Clay!!.add(ResourceType.CLAY, 3)
+ }
+
+ @Test
+ fun contains_newProductionContainsEmpty() {
+ val production = Production()
+ assertTrue(production.contains(emptyResources))
+ }
+
+ @Test
+ fun contains_singleFixedResource_noneAtAll() {
+ val production = Production()
+ assertFalse(production.contains(resources2Stones))
+ }
+
+ @Test
+ fun contains_singleFixedResource_notEnough() {
+ val production = Production()
+ production.addFixedResource(ResourceType.STONE, 1)
+ assertFalse(production.contains(resources2Stones))
+ }
+
+ @Test
+ fun contains_singleFixedResource_justEnough() {
+ val production = Production()
+ production.addFixedResource(ResourceType.STONE, 2)
+ assertTrue(production.contains(resources2Stones))
+ }
+
+ @Test
+ fun contains_singleFixedResource_moreThanEnough() {
+ val production = Production()
+ production.addFixedResource(ResourceType.STONE, 3)
+ assertTrue(production.contains(resources2Stones))
+ }
+
+ @Test
+ fun contains_singleFixedResource_moreThanEnough_amongOthers() {
+ val production = Production()
+ production.addFixedResource(ResourceType.STONE, 3)
+ production.addFixedResource(ResourceType.CLAY, 2)
+ assertTrue(production.contains(resources2Stones))
+ }
+
+ @Test
+ fun contains_multipleFixedResources_notEnoughOfOne() {
+ val production = Production()
+ production.addFixedResource(ResourceType.STONE, 3)
+ production.addFixedResource(ResourceType.CLAY, 1)
+ assertFalse(production.contains(resources2Stones3Clay))
+ }
+
+ @Test
+ fun contains_multipleFixedResources_notEnoughOfBoth() {
+ val production = Production()
+ production.addFixedResource(ResourceType.STONE, 1)
+ production.addFixedResource(ResourceType.CLAY, 1)
+ assertFalse(production.contains(resources2Stones3Clay))
+ }
+
+ @Test
+ fun contains_multipleFixedResources_moreThanEnough() {
+ val production = Production()
+ production.addFixedResource(ResourceType.STONE, 3)
+ production.addFixedResource(ResourceType.CLAY, 5)
+ assertTrue(production.contains(resources2Stones3Clay))
+ }
+
+ @Test
+ fun contains_singleChoice_containsEmpty() {
+ val production = Production()
+ production.addChoice(ResourceType.STONE, ResourceType.CLAY)
+ assertTrue(production.contains(emptyResources))
+ }
+
+ @Test
+ fun contains_singleChoice_enough() {
+ val production = Production()
+ production.addChoice(ResourceType.STONE, ResourceType.WOOD)
+ assertTrue(production.contains(resources1Wood))
+ assertTrue(production.contains(resources1Stone))
+ }
+
+ @Test
+ fun contains_multipleChoices_notBoth() {
+ val production = Production()
+ production.addChoice(ResourceType.STONE, ResourceType.CLAY)
+ production.addChoice(ResourceType.STONE, ResourceType.CLAY)
+ production.addChoice(ResourceType.STONE, ResourceType.CLAY)
+ assertFalse(production.contains(resources2Stones3Clay))
+ }
+
+ @Test
+ fun contains_multipleChoices_enough() {
+ val production = Production()
+ production.addChoice(ResourceType.STONE, ResourceType.ORE)
+ production.addChoice(ResourceType.STONE, ResourceType.WOOD)
+ assertTrue(production.contains(resources1Stone1Wood))
+ }
+
+ @Test
+ fun contains_multipleChoices_enoughReverseOrder() {
+ val production = Production()
+ production.addChoice(ResourceType.STONE, ResourceType.WOOD)
+ production.addChoice(ResourceType.STONE, ResourceType.ORE)
+ assertTrue(production.contains(resources1Stone1Wood))
+ }
+
+ @Test
+ fun contains_multipleChoices_moreThanEnough() {
+ val production = Production()
+ production.addChoice(ResourceType.LOOM, ResourceType.GLASS, ResourceType.PAPYRUS)
+ production.addChoice(ResourceType.STONE, ResourceType.ORE)
+ production.addChoice(ResourceType.STONE, ResourceType.WOOD)
+ assertTrue(production.contains(resources1Stone1Wood))
+ }
+
+ @Test
+ fun contains_mixedFixedAndChoice_enough() {
+ val production = Production()
+ production.addFixedResource(ResourceType.WOOD, 1)
+ production.addChoice(ResourceType.STONE, ResourceType.WOOD)
+ assertTrue(production.contains(resources1Stone1Wood))
+ }
+
+ @Test
+ fun addAll_empty() {
+ val production = Production()
+ production.addAll(emptyResources)
+ assertTrue(production.contains(emptyResources))
+ }
+
+ @Test
+ fun addAll_singleResource() {
+ val production = Production()
+ production.addAll(resources1Stone)
+ assertTrue(production.contains(resources1Stone))
+ }
+
+ @Test
+ fun addAll_multipleResources() {
+ val production = Production()
+ production.addAll(resources2Stones3Clay)
+ assertTrue(production.contains(resources2Stones3Clay))
+ }
+
+ @Test
+ fun addAll_production_multipleFixedResources() {
+ val production = Production()
+ production.addAll(resources2Stones3Clay)
+
+ val production2 = Production()
+ production2.addAll(production)
+
+ assertTrue(production2.contains(resources2Stones3Clay))
+ }
+
+ @Test
+ fun addAll_production_multipleChoices() {
+ val production = Production()
+ production.addChoice(ResourceType.STONE, ResourceType.WOOD)
+ production.addChoice(ResourceType.STONE, ResourceType.ORE)
+
+ val production2 = Production()
+ production2.addAll(production)
+ assertTrue(production.contains(resources1Stone1Wood))
+ }
+
+ @Test
+ fun addAll_production_mixedFixedResourcesAndChoices() {
+ val production = Production()
+ production.addFixedResource(ResourceType.WOOD, 1)
+ production.addChoice(ResourceType.STONE, ResourceType.WOOD)
+
+ val production2 = Production()
+ production2.addAll(production)
+
+ assertTrue(production.contains(resources1Stone1Wood))
+ }
+
+ @Test
+ fun asChoices_empty() {
+ val production = Production()
+ assertTrue(production.asChoices().isEmpty())
+ }
+
+ @Test
+ fun asChoices_onlyChoices() {
+ val production = Production()
+ production.addChoice(ResourceType.STONE, ResourceType.WOOD)
+ production.addChoice(ResourceType.STONE, ResourceType.ORE)
+ production.addChoice(ResourceType.CLAY, ResourceType.LOOM, ResourceType.GLASS)
+ assertEquals(production.alternativeResources, production.asChoices())
+ }
+
+ @Test
+ fun asChoices_onlyFixed() {
+ val production = Production()
+ production.addFixedResource(ResourceType.WOOD, 1)
+ production.addFixedResource(ResourceType.CLAY, 2)
+
+ val expected = HashSet<Set<ResourceType>>()
+ expected.add(EnumSet.of(ResourceType.WOOD))
+ expected.add(EnumSet.of(ResourceType.CLAY))
+ expected.add(EnumSet.of(ResourceType.CLAY))
+
+ assertEquals(expected, production.asChoices())
+ }
+
+ @Test
+ fun asChoices_mixed() {
+ val production = Production()
+ production.addChoice(ResourceType.STONE, ResourceType.ORE)
+ production.addChoice(ResourceType.CLAY, ResourceType.LOOM, ResourceType.GLASS)
+ production.addFixedResource(ResourceType.WOOD, 1)
+ production.addFixedResource(ResourceType.CLAY, 2)
+
+ val expected = HashSet<Set<ResourceType>>()
+ expected.add(EnumSet.of(ResourceType.STONE, ResourceType.ORE))
+ expected.add(EnumSet.of(ResourceType.CLAY, ResourceType.LOOM, ResourceType.GLASS))
+ expected.add(EnumSet.of(ResourceType.WOOD))
+ expected.add(EnumSet.of(ResourceType.CLAY))
+ expected.add(EnumSet.of(ResourceType.CLAY))
+
+ assertEquals(expected, production.asChoices())
+ }
+
+ @Test
+ fun equals_falseWhenNull() {
+ val production = Production()
+ production.addFixedResource(ResourceType.GLASS, 1)
+ production.addChoice(ResourceType.ORE, ResourceType.WOOD)
+
+ assertFalse(production == null)
+ }
+
+ @Test
+ fun equals_falseWhenDifferentClass() {
+ val production = Production()
+ production.addFixedResource(ResourceType.GLASS, 1)
+ val resources = Resources()
+ resources.add(ResourceType.GLASS, 1)
+
+ assertFalse(production == resources)
+ }
+
+ @Test
+ fun equals_trueWhenSame() {
+ val production = Production()
+ assertEquals(production, production)
+ }
+
+ @Test
+ fun equals_trueWhenSameContent() {
+ val production1 = Production()
+ val production2 = Production()
+ assertTrue(production1 == production2)
+ production1.addFixedResource(ResourceType.GLASS, 1)
+ production2.addFixedResource(ResourceType.GLASS, 1)
+ assertTrue(production1 == production2)
+ production1.addChoice(ResourceType.ORE, ResourceType.WOOD)
+ production2.addChoice(ResourceType.ORE, ResourceType.WOOD)
+ assertTrue(production1 == production2)
+ }
+
+ @Test
+ fun hashCode_sameWhenSameContent() {
+ val production1 = Production()
+ val production2 = Production()
+ assertEquals(production1.hashCode().toLong(), production2.hashCode().toLong())
+ production1.addFixedResource(ResourceType.GLASS, 1)
+ production2.addFixedResource(ResourceType.GLASS, 1)
+ assertEquals(production1.hashCode().toLong(), production2.hashCode().toLong())
+ production1.addChoice(ResourceType.ORE, ResourceType.WOOD)
+ production2.addChoice(ResourceType.ORE, ResourceType.WOOD)
+ assertEquals(production1.hashCode().toLong(), production2.hashCode().toLong())
+ }
+}
diff --git a/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/ResourceTransactionsTest.kt b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/ResourceTransactionsTest.kt
new file mode 100644
index 00000000..11a03cd4
--- /dev/null
+++ b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/ResourceTransactionsTest.kt
@@ -0,0 +1,36 @@
+package org.luxons.sevenwonders.game.resources
+
+import java.util.ArrayList
+import java.util.HashSet
+
+import org.junit.Test
+import org.luxons.sevenwonders.game.test.*
+
+import org.junit.Assert.assertEquals
+
+class ResourceTransactionsTest {
+
+ @Test
+ fun toTransactions() {
+ val transactionList = ArrayList<ResourceTransaction>()
+ transactionList.add(createTransaction(Provider.LEFT_PLAYER, ResourceType.WOOD))
+ transactionList.add(createTransaction(Provider.LEFT_PLAYER, ResourceType.CLAY))
+ transactionList.add(createTransaction(Provider.RIGHT_PLAYER, ResourceType.WOOD))
+
+ val transactions = ResourceTransactions(transactionList)
+
+ val expectedNormalized = HashSet<ResourceTransaction>()
+ expectedNormalized.add(
+ createTransaction(Provider.LEFT_PLAYER, ResourceType.WOOD, ResourceType.CLAY)
+ )
+ expectedNormalized.add(createTransaction(Provider.RIGHT_PLAYER, ResourceType.WOOD))
+
+ assertEquals(expectedNormalized, HashSet(transactions.toTransactions()))
+ }
+
+ @Test(expected = IllegalStateException::class)
+ fun remove_failsIfNoResourceForThatProvider() {
+ val transactions = ResourceTransactions()
+ transactions.remove(Provider.LEFT_PLAYER, Resources.of(ResourceType.WOOD))
+ }
+}
diff --git a/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/ResourcesTest.kt b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/ResourcesTest.kt
new file mode 100644
index 00000000..72419fe3
--- /dev/null
+++ b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/ResourcesTest.kt
@@ -0,0 +1,482 @@
+package org.luxons.sevenwonders.game.resources
+
+import org.junit.Assert.*
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.ExpectedException
+import java.util.NoSuchElementException
+
+class ResourcesTest {
+
+ @JvmField
+ @Rule
+ var thrown = ExpectedException.none()
+
+ @Test
+ fun init_shouldBeEmpty() {
+ val resources = Resources()
+ for (resourceType in ResourceType.values()) {
+ assertEquals(0, resources.getQuantity(resourceType).toLong())
+ }
+ assertEquals(0, resources.size().toLong())
+ assertTrue(resources.isEmpty)
+ }
+
+ @Test
+ fun add_zero() {
+ val resources = Resources()
+ resources.add(ResourceType.CLAY, 0)
+ assertEquals(0, resources.getQuantity(ResourceType.CLAY).toLong())
+ assertEquals(0, resources.size().toLong())
+ assertTrue(resources.isEmpty)
+ }
+
+ @Test
+ fun add_simple() {
+ val resources = Resources()
+ resources.add(ResourceType.WOOD, 3)
+ assertEquals(3, resources.getQuantity(ResourceType.WOOD).toLong())
+ assertEquals(3, resources.size().toLong())
+ assertFalse(resources.isEmpty)
+ }
+
+ @Test
+ fun add_multipleCallsStacked() {
+ val resources = Resources()
+ resources.add(ResourceType.ORE, 3)
+ resources.add(ResourceType.ORE, 2)
+ assertEquals(5, resources.getQuantity(ResourceType.ORE).toLong())
+ assertEquals(5, resources.size().toLong())
+ assertFalse(resources.isEmpty)
+ }
+
+ @Test
+ fun add_interlaced() {
+ val resources = Resources()
+ resources.add(ResourceType.GLASS, 3)
+ resources.add(ResourceType.STONE, 1)
+ resources.add(ResourceType.WOOD, 4)
+ resources.add(ResourceType.GLASS, 2)
+ assertEquals(5, resources.getQuantity(ResourceType.GLASS).toLong())
+ assertEquals(10, resources.size().toLong())
+ assertFalse(resources.isEmpty)
+ }
+
+ @Test
+ fun remove_some() {
+ val resources = Resources()
+ resources.add(ResourceType.WOOD, 3)
+ resources.remove(ResourceType.WOOD, 2)
+ assertEquals(1, resources.getQuantity(ResourceType.WOOD).toLong())
+ assertEquals(1, resources.size().toLong())
+ assertFalse(resources.isEmpty)
+ }
+
+ @Test
+ fun remove_all() {
+ val resources = Resources()
+ resources.add(ResourceType.WOOD, 3)
+ resources.remove(ResourceType.WOOD, 3)
+ assertEquals(0, resources.getQuantity(ResourceType.WOOD).toLong())
+ assertEquals(0, resources.size().toLong())
+ assertTrue(resources.isEmpty)
+ }
+
+ @Test
+ fun remove_tooMany() {
+ val resources = Resources()
+ resources.add(ResourceType.WOOD, 2)
+
+ thrown.expect(NoSuchElementException::class.java)
+ resources.remove(ResourceType.WOOD, 3)
+ }
+
+ @Test
+ fun addAll_empty() {
+ val resources = Resources()
+ resources.add(ResourceType.STONE, 1)
+ resources.add(ResourceType.CLAY, 3)
+
+ val emptyResources = Resources()
+
+ resources.addAll(emptyResources)
+ assertEquals(1, resources.getQuantity(ResourceType.STONE).toLong())
+ assertEquals(3, resources.getQuantity(ResourceType.CLAY).toLong())
+ assertEquals(0, resources.getQuantity(ResourceType.ORE).toLong())
+ assertEquals(0, resources.getQuantity(ResourceType.GLASS).toLong())
+ assertEquals(0, resources.getQuantity(ResourceType.LOOM).toLong())
+ assertEquals(4, resources.size().toLong())
+ assertFalse(resources.isEmpty)
+ }
+
+ @Test
+ fun addAll_zeros() {
+ val resources = Resources()
+ resources.add(ResourceType.STONE, 1)
+ resources.add(ResourceType.CLAY, 3)
+
+ val emptyResources = Resources()
+ emptyResources.add(ResourceType.STONE, 0)
+ emptyResources.add(ResourceType.CLAY, 0)
+
+ resources.addAll(emptyResources)
+ assertEquals(1, resources.getQuantity(ResourceType.STONE).toLong())
+ assertEquals(3, resources.getQuantity(ResourceType.CLAY).toLong())
+ assertEquals(0, resources.getQuantity(ResourceType.ORE).toLong())
+ assertEquals(0, resources.getQuantity(ResourceType.GLASS).toLong())
+ assertEquals(0, resources.getQuantity(ResourceType.LOOM).toLong())
+ assertEquals(4, resources.size().toLong())
+ assertFalse(resources.isEmpty)
+ }
+
+ @Test
+ fun addAll_same() {
+ val resources = Resources()
+ resources.add(ResourceType.STONE, 1)
+ resources.add(ResourceType.CLAY, 3)
+
+ val resources2 = Resources()
+ resources.add(ResourceType.STONE, 2)
+ resources.add(ResourceType.CLAY, 6)
+
+ resources.addAll(resources2)
+ assertEquals(3, resources.getQuantity(ResourceType.STONE).toLong())
+ assertEquals(9, resources.getQuantity(ResourceType.CLAY).toLong())
+ assertEquals(0, resources.getQuantity(ResourceType.ORE).toLong())
+ assertEquals(0, resources.getQuantity(ResourceType.GLASS).toLong())
+ assertEquals(0, resources.getQuantity(ResourceType.LOOM).toLong())
+ assertEquals(12, resources.size().toLong())
+ assertFalse(resources.isEmpty)
+ }
+
+ @Test
+ fun addAll_overlap() {
+ val resources = Resources()
+ resources.add(ResourceType.STONE, 1)
+ resources.add(ResourceType.CLAY, 3)
+
+ val resources2 = Resources()
+ resources.add(ResourceType.CLAY, 6)
+ resources.add(ResourceType.ORE, 4)
+
+ resources.addAll(resources2)
+ assertEquals(1, resources.getQuantity(ResourceType.STONE).toLong())
+ assertEquals(9, resources.getQuantity(ResourceType.CLAY).toLong())
+ assertEquals(4, resources.getQuantity(ResourceType.ORE).toLong())
+ assertEquals(0, resources.getQuantity(ResourceType.GLASS).toLong())
+ assertEquals(0, resources.getQuantity(ResourceType.LOOM).toLong())
+ assertEquals(14, resources.size().toLong())
+ assertFalse(resources.isEmpty)
+ }
+
+ @Test
+ fun contains_emptyContainsEmpty() {
+ val emptyResources = Resources()
+ val emptyResources2 = Resources()
+ assertTrue(emptyResources.contains(emptyResources2))
+ }
+
+ @Test
+ fun contains_singleTypeContainsEmpty() {
+ val resources = Resources()
+ resources.add(ResourceType.STONE, 1)
+
+ val emptyResources = Resources()
+
+ assertTrue(resources.contains(emptyResources))
+ }
+
+ @Test
+ fun contains_multipleTypesContainsEmpty() {
+ val resources = Resources()
+ resources.add(ResourceType.STONE, 1)
+ resources.add(ResourceType.CLAY, 3)
+
+ val emptyResources = Resources()
+
+ assertTrue(resources.contains(emptyResources))
+ }
+
+ @Test
+ fun contains_self() {
+ val resources = Resources()
+ resources.add(ResourceType.STONE, 1)
+ resources.add(ResourceType.CLAY, 3)
+
+ assertTrue(resources.contains(resources))
+ }
+
+ @Test
+ fun contains_allOfEachType() {
+ val resources = Resources()
+ resources.add(ResourceType.STONE, 1)
+ resources.add(ResourceType.CLAY, 3)
+
+ val resources2 = Resources()
+ resources2.add(ResourceType.STONE, 1)
+ resources2.add(ResourceType.CLAY, 3)
+
+ assertTrue(resources.contains(resources2))
+ }
+
+ @Test
+ fun contains_someOfEachType() {
+ val resources = Resources()
+ resources.add(ResourceType.STONE, 2)
+ resources.add(ResourceType.CLAY, 4)
+
+ val resources2 = Resources()
+ resources2.add(ResourceType.STONE, 1)
+ resources2.add(ResourceType.CLAY, 3)
+
+ assertTrue(resources.contains(resources2))
+ }
+
+ @Test
+ fun contains_someOfSomeTypes() {
+ val resources = Resources()
+ resources.add(ResourceType.STONE, 2)
+ resources.add(ResourceType.CLAY, 4)
+
+ val resources2 = Resources()
+ resources2.add(ResourceType.CLAY, 3)
+
+ assertTrue(resources.contains(resources2))
+ }
+
+ @Test
+ fun contains_allOfSomeTypes() {
+ val resources = Resources()
+ resources.add(ResourceType.STONE, 2)
+ resources.add(ResourceType.CLAY, 4)
+
+ val resources2 = Resources()
+ resources2.add(ResourceType.CLAY, 4)
+
+ assertTrue(resources.contains(resources2))
+ }
+
+ @Test
+ fun minus_empty() {
+ val resources = Resources()
+ resources.add(ResourceType.STONE, 1)
+ resources.add(ResourceType.CLAY, 3)
+
+ val emptyResources = Resources()
+
+ val diff = resources.minus(emptyResources)
+ assertEquals(1, diff.getQuantity(ResourceType.STONE).toLong())
+ assertEquals(3, diff.getQuantity(ResourceType.CLAY).toLong())
+ assertEquals(0, diff.getQuantity(ResourceType.ORE).toLong())
+ assertEquals(0, diff.getQuantity(ResourceType.GLASS).toLong())
+ assertEquals(0, diff.getQuantity(ResourceType.LOOM).toLong())
+ }
+
+ @Test
+ fun minus_self() {
+ val resources = Resources()
+ resources.add(ResourceType.STONE, 1)
+ resources.add(ResourceType.CLAY, 3)
+
+ val diff = resources.minus(resources)
+ assertEquals(0, diff.getQuantity(ResourceType.STONE).toLong())
+ assertEquals(0, diff.getQuantity(ResourceType.CLAY).toLong())
+ assertEquals(0, diff.getQuantity(ResourceType.ORE).toLong())
+ assertEquals(0, diff.getQuantity(ResourceType.GLASS).toLong())
+ assertEquals(0, diff.getQuantity(ResourceType.LOOM).toLong())
+ }
+
+ @Test
+ fun minus_allOfEachType() {
+ val resources = Resources()
+ resources.add(ResourceType.STONE, 1)
+ resources.add(ResourceType.CLAY, 3)
+
+ val resources2 = Resources()
+ resources2.add(ResourceType.STONE, 1)
+ resources2.add(ResourceType.CLAY, 3)
+
+ val diff = resources.minus(resources2)
+ assertEquals(0, diff.getQuantity(ResourceType.STONE).toLong())
+ assertEquals(0, diff.getQuantity(ResourceType.CLAY).toLong())
+ assertEquals(0, diff.getQuantity(ResourceType.ORE).toLong())
+ assertEquals(0, diff.getQuantity(ResourceType.GLASS).toLong())
+ assertEquals(0, diff.getQuantity(ResourceType.LOOM).toLong())
+ }
+
+ @Test
+ fun minus_someOfEachType() {
+ val resources = Resources()
+ resources.add(ResourceType.STONE, 2)
+ resources.add(ResourceType.CLAY, 4)
+
+ val resources2 = Resources()
+ resources2.add(ResourceType.STONE, 1)
+ resources2.add(ResourceType.CLAY, 3)
+
+ val diff = resources.minus(resources2)
+ assertEquals(1, diff.getQuantity(ResourceType.STONE).toLong())
+ assertEquals(1, diff.getQuantity(ResourceType.CLAY).toLong())
+ assertEquals(0, diff.getQuantity(ResourceType.ORE).toLong())
+ assertEquals(0, diff.getQuantity(ResourceType.GLASS).toLong())
+ assertEquals(0, diff.getQuantity(ResourceType.LOOM).toLong())
+ }
+
+ @Test
+ fun minus_someOfSomeTypes() {
+ val resources = Resources()
+ resources.add(ResourceType.STONE, 2)
+ resources.add(ResourceType.CLAY, 4)
+
+ val resources2 = Resources()
+ resources2.add(ResourceType.CLAY, 3)
+
+ val diff = resources.minus(resources2)
+ assertEquals(2, diff.getQuantity(ResourceType.STONE).toLong())
+ assertEquals(1, diff.getQuantity(ResourceType.CLAY).toLong())
+ assertEquals(0, diff.getQuantity(ResourceType.ORE).toLong())
+ assertEquals(0, diff.getQuantity(ResourceType.GLASS).toLong())
+ assertEquals(0, diff.getQuantity(ResourceType.LOOM).toLong())
+ }
+
+ @Test
+ fun minus_allOfSomeTypes() {
+ val resources = Resources()
+ resources.add(ResourceType.STONE, 2)
+ resources.add(ResourceType.CLAY, 4)
+
+ val resources2 = Resources()
+ resources2.add(ResourceType.CLAY, 4)
+
+ val diff = resources.minus(resources2)
+ assertEquals(2, diff.getQuantity(ResourceType.STONE).toLong())
+ assertEquals(0, diff.getQuantity(ResourceType.CLAY).toLong())
+ assertEquals(0, diff.getQuantity(ResourceType.ORE).toLong())
+ assertEquals(0, diff.getQuantity(ResourceType.GLASS).toLong())
+ assertEquals(0, diff.getQuantity(ResourceType.LOOM).toLong())
+ }
+
+ @Test
+ fun minus_tooMuchOfExistingType() {
+ val resources = Resources()
+ resources.add(ResourceType.CLAY, 4)
+
+ val resources2 = Resources()
+ resources2.add(ResourceType.CLAY, 5)
+
+ val diff = resources.minus(resources2)
+ assertEquals(0, diff.getQuantity(ResourceType.CLAY).toLong())
+ }
+
+ @Test
+ fun minus_someOfAnAbsentType() {
+ val resources = Resources()
+
+ val resources2 = Resources()
+ resources2.add(ResourceType.LOOM, 5)
+
+ val diff = resources.minus(resources2)
+ assertEquals(0, diff.getQuantity(ResourceType.LOOM).toLong())
+ }
+
+ @Test
+ fun minus_someOfATypeWithZero() {
+ val resources = Resources()
+ resources.add(ResourceType.LOOM, 0)
+
+ val resources2 = Resources()
+ resources2.add(ResourceType.LOOM, 5)
+
+ val diff = resources.minus(resources2)
+ assertEquals(0, diff.getQuantity(ResourceType.LOOM).toLong())
+ }
+
+ @Test
+ fun isEmpty_noElement() {
+ val resources = Resources()
+ assertTrue(resources.isEmpty)
+ }
+
+ @Test
+ fun isEmpty_singleZeroElement() {
+ val resources = Resources()
+ resources.add(ResourceType.LOOM, 0)
+ assertTrue(resources.isEmpty)
+ }
+
+ @Test
+ fun isEmpty_multipleZeroElements() {
+ val resources = Resources()
+ resources.add(ResourceType.WOOD, 0)
+ resources.add(ResourceType.ORE, 0)
+ resources.add(ResourceType.LOOM, 0)
+ assertTrue(resources.isEmpty)
+ }
+
+ @Test
+ fun isEmpty_singleElementMoreThanZero() {
+ val resources = Resources()
+ resources.add(ResourceType.LOOM, 3)
+ assertFalse(resources.isEmpty)
+ }
+
+ @Test
+ fun isEmpty_mixedZeroAndNonZeroElements() {
+ val resources = Resources()
+ resources.add(ResourceType.WOOD, 0)
+ resources.add(ResourceType.LOOM, 3)
+ assertFalse(resources.isEmpty)
+ }
+
+ @Test
+ fun isEmpty_mixedZeroAndNonZeroElements_reverseOrder() {
+ val resources = Resources()
+ resources.add(ResourceType.ORE, 3)
+ resources.add(ResourceType.PAPYRUS, 0)
+ assertFalse(resources.isEmpty)
+ }
+
+ @Test
+ fun equals_falseWhenNull() {
+ val resources = Resources()
+ resources.add(ResourceType.GLASS, 1)
+
+ assertFalse(resources == null)
+ }
+
+ @Test
+ fun equals_falseWhenDifferentClass() {
+ val resources = Resources()
+ resources.add(ResourceType.GLASS, 1)
+ val production = Production()
+ production.addFixedResource(ResourceType.GLASS, 1)
+
+ assertFalse(resources == production)
+ }
+
+ @Test
+ fun equals_trueWhenSame() {
+ val resources = Resources()
+ assertEquals(resources, resources)
+ }
+
+ @Test
+ fun equals_trueWhenSameContent() {
+ val resources1 = Resources()
+ val resources2 = Resources()
+ assertTrue(resources1 == resources2)
+ resources1.add(ResourceType.GLASS, 1)
+ resources2.add(ResourceType.GLASS, 1)
+ assertTrue(resources1 == resources2)
+ }
+
+ @Test
+ fun hashCode_sameWhenSameContent() {
+ val resources1 = Resources()
+ val resources2 = Resources()
+ assertEquals(resources1.hashCode().toLong(), resources2.hashCode().toLong())
+ resources1.add(ResourceType.GLASS, 1)
+ resources2.add(ResourceType.GLASS, 1)
+ assertEquals(resources1.hashCode().toLong(), resources2.hashCode().toLong())
+ }
+}
diff --git a/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/TradingRulesTest.kt b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/TradingRulesTest.kt
new file mode 100644
index 00000000..859c997a
--- /dev/null
+++ b/game-engine/src/test/kotlin/org/luxons/sevenwonders/game/resources/TradingRulesTest.kt
@@ -0,0 +1,127 @@
+package org.luxons.sevenwonders.game.resources
+
+import java.util.ArrayList
+
+import org.junit.experimental.theories.DataPoints
+import org.junit.experimental.theories.Theories
+import org.junit.experimental.theories.Theory
+import org.junit.runner.RunWith
+import org.luxons.sevenwonders.game.test.*
+
+import org.junit.Assert.assertEquals
+import org.junit.Assume.assumeTrue
+
+@RunWith(Theories::class)
+class TradingRulesTest {
+
+ @Theory
+ fun setCost_overridesCost(
+ defaultCost: Int, overriddenCost: Int, overriddenProvider: Provider,
+ provider: Provider, type: ResourceType
+ ) {
+ assumeTrue(defaultCost != overriddenCost)
+ assumeTrue(overriddenProvider != provider)
+
+ val rules = TradingRules(defaultCost)
+ rules.setCost(type, overriddenProvider, overriddenCost)
+
+ assertEquals(overriddenCost.toLong(), rules.getCost(type, overriddenProvider).toLong())
+ assertEquals(defaultCost.toLong(), rules.getCost(type, provider).toLong())
+ }
+
+ @Theory
+ fun computeCost_zeroForNoResources(defaultCost: Int) {
+ val rules = TradingRules(defaultCost)
+ assertEquals(0, rules.computeCost(ResourceTransactions()).toLong())
+ }
+
+ @Theory
+ fun computeCost_defaultCostWhenNoOverride(defaultCost: Int, provider: Provider, type: ResourceType) {
+ val rules = TradingRules(defaultCost)
+ val transactions = createTransactions(provider, type)
+ assertEquals(defaultCost.toLong(), rules.computeCost(transactions).toLong())
+ }
+
+ @Theory
+ fun computeCost_twiceDefaultFor2Resources(defaultCost: Int, provider: Provider, type: ResourceType) {
+ val rules = TradingRules(defaultCost)
+ val transactions = createTransactions(provider, type, type)
+ assertEquals((2 * defaultCost).toLong(), rules.computeCost(transactions).toLong())
+ }
+
+ @Theory
+ fun computeCost_overriddenCost(defaultCost: Int, overriddenCost: Int, provider: Provider, type: ResourceType) {
+ val rules = TradingRules(defaultCost)
+ rules.setCost(type, provider, overriddenCost)
+ val transactions = createTransactions(provider, type)
+ assertEquals(overriddenCost.toLong(), rules.computeCost(transactions).toLong())
+ }
+
+ @Theory
+ fun computeCost_defaultCostWhenOverrideOnOtherProviderOrType(
+ defaultCost: Int, overriddenCost: Int,
+ overriddenProvider: Provider,
+ overriddenType: ResourceType, provider: Provider,
+ type: ResourceType
+ ) {
+ assumeTrue(overriddenProvider != provider || overriddenType != type)
+ val rules = TradingRules(defaultCost)
+ rules.setCost(overriddenType, overriddenProvider, overriddenCost)
+ val transactions = createTransactions(provider, type)
+ assertEquals(defaultCost.toLong(), rules.computeCost(transactions).toLong())
+ }
+
+ @Theory
+ fun computeCost_oneDefaultAndOneOverriddenType(
+ defaultCost: Int, overriddenCost: Int,
+ overriddenType: ResourceType, provider: Provider,
+ type: ResourceType
+ ) {
+ assumeTrue(overriddenType != type)
+ val rules = TradingRules(defaultCost)
+ rules.setCost(overriddenType, provider, overriddenCost)
+ val transactions = createTransactions(provider, overriddenType, type)
+ assertEquals((defaultCost + overriddenCost).toLong(), rules.computeCost(transactions).toLong())
+ }
+
+ @Theory
+ fun computeCost_oneDefaultAndOneOverriddenProvider(
+ defaultCost: Int, overriddenCost: Int,
+ overriddenProvider: Provider, provider: Provider,
+ type: ResourceType
+ ) {
+ assumeTrue(overriddenProvider != provider)
+ val rules = TradingRules(defaultCost)
+ rules.setCost(type, overriddenProvider, overriddenCost)
+
+ val boughtResources = ArrayList<ResourceTransaction>(2)
+ boughtResources.add(createTransaction(provider, type))
+ boughtResources.add(createTransaction(overriddenProvider, type))
+
+ assertEquals(
+ (defaultCost + overriddenCost).toLong(),
+ rules.computeCost(ResourceTransactions(boughtResources)).toLong()
+ )
+ }
+
+ companion object {
+
+ @JvmStatic
+ @DataPoints
+ fun costs(): IntArray {
+ return intArrayOf(0, 1, 2)
+ }
+
+ @JvmStatic
+ @DataPoints
+ fun providers(): Array<Provider> {
+ return Provider.values()
+ }
+
+ @JvmStatic
+ @DataPoints
+ fun resourceTypes(): Array<ResourceType> {
+ return ResourceType.values()
+ }
+ }
+}
bgstack15