diff options
Diffstat (limited to 'src/main')
7 files changed, 68 insertions, 29 deletions
diff --git a/src/main/java/org/luxons/sevenwonders/game/Game.java b/src/main/java/org/luxons/sevenwonders/game/Game.java index 1f7a13c2..7a2f72d2 100644 --- a/src/main/java/org/luxons/sevenwonders/game/Game.java +++ b/src/main/java/org/luxons/sevenwonders/game/Game.java @@ -85,7 +85,7 @@ public class Game { throw new InvalidMoveException( "Player " + move.getPlayerIndex() + " does not have the card " + move.getCardName()); } - if (!move.isValid(table)) { + if (!move.isValid(table, card)) { throw new InvalidMoveException( "Player " + move.getPlayerIndex() + " cannot play the card " + move.getCardName()); } diff --git a/src/main/java/org/luxons/sevenwonders/game/api/Move.java b/src/main/java/org/luxons/sevenwonders/game/api/Move.java index 55af635e..abf0e27d 100644 --- a/src/main/java/org/luxons/sevenwonders/game/api/Move.java +++ b/src/main/java/org/luxons/sevenwonders/game/api/Move.java @@ -3,6 +3,7 @@ package org.luxons.sevenwonders.game.api; import java.util.ArrayList; import java.util.List; +import org.luxons.sevenwonders.game.cards.Card; import org.luxons.sevenwonders.game.resources.BoughtResources; public class Move { @@ -47,11 +48,8 @@ public class Move { this.boughtResources = boughtResources; } - public boolean isValid(Table table) { - if (type == MoveType.DISCARD) { - return true; - } - // TODO create a version of the Move class with actual card data? - return false; + public boolean isValid(Table table, Card resolvedCard) { + return type == MoveType.DISCARD || resolvedCard.getRequirements() + .isAffordedBy(table, playerIndex, boughtResources); } } diff --git a/src/main/java/org/luxons/sevenwonders/game/boards/Board.java b/src/main/java/org/luxons/sevenwonders/game/boards/Board.java index 0295b09a..7734ec83 100644 --- a/src/main/java/org/luxons/sevenwonders/game/boards/Board.java +++ b/src/main/java/org/luxons/sevenwonders/game/boards/Board.java @@ -88,6 +88,9 @@ public class Board { } public void removeGold(int amount) { + if (gold < amount) { + throw new InsufficientFundsException(gold, amount); + } this.gold -= amount; } @@ -106,4 +109,10 @@ public class Board { public void setNbDefeatTokens(int nbDefeatTokens) { this.nbDefeatTokens= nbDefeatTokens; } + + private static class InsufficientFundsException extends RuntimeException { + InsufficientFundsException(int current, int required) { + super(String.format("Current balance is %d gold, but %d are required", current, required)); + } + } } diff --git a/src/main/java/org/luxons/sevenwonders/game/cards/Card.java b/src/main/java/org/luxons/sevenwonders/game/cards/Card.java index 2dbf5cba..de674011 100644 --- a/src/main/java/org/luxons/sevenwonders/game/cards/Card.java +++ b/src/main/java/org/luxons/sevenwonders/game/cards/Card.java @@ -86,15 +86,13 @@ public class Card { if (board.isPlayed(name)) { return false; // cannot play twice the same card } - return isChainableOn(board) || requirements.isAffordedBy(table, playerIndex); + return isChainableOn(board) || requirements.couldBeAffordedBy(table, playerIndex); } public void applyTo(Table table, int playerIndex, List<BoughtResources> boughtResources) { - // TODO add paid resources cost deduction Board playerBoard = table.getBoard(playerIndex); if (!isChainableOn(playerBoard)) { - // TODO add paid resources exemption - requirements.pay(playerBoard); + requirements.pay(table, playerIndex, boughtResources); } effects.forEach(e -> e.apply(table, playerIndex)); } diff --git a/src/main/java/org/luxons/sevenwonders/game/cards/Requirements.java b/src/main/java/org/luxons/sevenwonders/game/cards/Requirements.java index 8fc6241a..f6d7934c 100644 --- a/src/main/java/org/luxons/sevenwonders/game/cards/Requirements.java +++ b/src/main/java/org/luxons/sevenwonders/game/cards/Requirements.java @@ -2,9 +2,10 @@ package org.luxons.sevenwonders.game.cards; import java.util.List; -import org.luxons.sevenwonders.game.resources.BoughtResources; import org.luxons.sevenwonders.game.api.Table; import org.luxons.sevenwonders.game.boards.Board; +import org.luxons.sevenwonders.game.boards.RelativeBoardPosition; +import org.luxons.sevenwonders.game.resources.BoughtResources; import org.luxons.sevenwonders.game.resources.Resources; public class Requirements { @@ -33,13 +34,17 @@ public class Requirements { return board.getGold() >= gold && board.getProduction().contains(resources); } - public boolean isAffordedBy(Table table, int playerIndex) { + public boolean couldBeAffordedBy(Table table, int playerIndex) { Board board = table.getBoard(playerIndex); - if (isAffordedBy(board)) { + if (board.getGold() < gold) { + return false; + } + if (board.getProduction().contains(resources)) { return true; } + Resources leftToPay = resources.minus(board.getProduction().getFixedResources()); // TODO take into account resources buyable from neighbours - return false; + return true; } public boolean isAffordedBy(Table table, int playerIndex, List<BoughtResources> boughtResources) { @@ -47,21 +52,37 @@ public class Requirements { if (isAffordedBy(board)) { return true; } - // TODO take into account resources buyable from neighbours - return false; + int totalPrice = board.getTradingRules().computeCost(boughtResources); + if (board.getGold() < totalPrice) { + return false; + } + Resources totalBoughtResources = getTotalResources(boughtResources); + Resources remainingResources = this.resources.minus(totalBoughtResources); + return board.getProduction().contains(remainingResources); } - void pay(Board board) { - int newBalance = board.getGold() - gold; - if (newBalance < 0) { - throw new InsufficientFundsException(board.getGold(), gold); - } - board.setGold(newBalance); + private Resources getTotalResources(List<BoughtResources> boughtResources) { + return boughtResources.stream().map(BoughtResources::getResources).reduce(new Resources(), (r1, r2) -> { + r1.addAll(r2); + return r1; + }); } - private class InsufficientFundsException extends RuntimeException { - InsufficientFundsException(int current, int required) { - super(String.format("Current balance is %d gold, but %d are required", current, required)); - } + void pay(Table table, int playerIndex, List<BoughtResources> boughtResources) { + table.getBoard(playerIndex).removeGold(gold); + payBoughtResources(table, playerIndex, boughtResources); + } + + private void payBoughtResources(Table table, int playerIndex, List<BoughtResources> boughtResourcesList) { + boughtResourcesList.forEach(res -> payBoughtResources(table, playerIndex, res)); + } + + private void payBoughtResources(Table table, int playerIndex, BoughtResources boughtResources) { + Board board = table.getBoard(playerIndex); + int price = board.getTradingRules().computeCost(boughtResources); + board.removeGold(price); + RelativeBoardPosition providerPosition = boughtResources.getProvider().getBoardPosition(); + Board providerBoard = table.getBoard(playerIndex, providerPosition); + providerBoard.addGold(price); } } diff --git a/src/main/java/org/luxons/sevenwonders/game/resources/Provider.java b/src/main/java/org/luxons/sevenwonders/game/resources/Provider.java index 9a105725..9c4aa3f9 100644 --- a/src/main/java/org/luxons/sevenwonders/game/resources/Provider.java +++ b/src/main/java/org/luxons/sevenwonders/game/resources/Provider.java @@ -1,5 +1,18 @@ package org.luxons.sevenwonders.game.resources; +import org.luxons.sevenwonders.game.boards.RelativeBoardPosition; + public enum Provider { - LEFT_PLAYER, RIGHT_PLAYER + LEFT_PLAYER(RelativeBoardPosition.LEFT), + RIGHT_PLAYER(RelativeBoardPosition.RIGHT); + + private final RelativeBoardPosition boardPosition; + + Provider(RelativeBoardPosition boardPosition) { + this.boardPosition = boardPosition; + } + + public RelativeBoardPosition getBoardPosition() { + return boardPosition; + } } diff --git a/src/main/java/org/luxons/sevenwonders/game/resources/TradingRules.java b/src/main/java/org/luxons/sevenwonders/game/resources/TradingRules.java index 4965c00e..19409844 100644 --- a/src/main/java/org/luxons/sevenwonders/game/resources/TradingRules.java +++ b/src/main/java/org/luxons/sevenwonders/game/resources/TradingRules.java @@ -27,7 +27,7 @@ public class TradingRules { return boughtResources.stream().mapToInt(this::computeCost).sum(); } - private int computeCost(BoughtResources boughtResources) { + public int computeCost(BoughtResources boughtResources) { Resources resources = boughtResources.getResources(); int total = 0; for (Entry<ResourceType, Integer> entry : resources.getQuantities().entrySet()) { |