diff --git a/src/edu/kit/informatik/cardgame/model/Card.java b/src/edu/kit/informatik/cardgame/model/Card.java index 020dcce..c8edb9a 100644 --- a/src/edu/kit/informatik/cardgame/model/Card.java +++ b/src/edu/kit/informatik/cardgame/model/Card.java @@ -77,20 +77,18 @@ public enum Card implements RequireDice { } @Override - public String activate(CardGame game, int diceSize, int roll) throws LogicException { - if (!this.minimumDiceRollNeeded().isPresent()) { + public Optional activate(CardGame game, int diceSize, int roll) { + if (!this.diceSizeNeeded().isPresent()) { throw new IllegalStateException("can not process dice roll"); - } else if (this.diceSizeNeeded().get() != diceSize) { - throw new LogicException("unexpected dice size"); - } else if (roll > diceSize || roll < 1) { - throw new LogicException("impossible roll"); + } else if (this.diceSizeNeeded().get() != diceSize || roll > diceSize || roll < 1) { + return Optional.empty(); } if (roll + game.getFightingBonus() >= this.minimumDiceRollNeeded().get()) { - return SURVIVED; + return Optional.of(SURVIVED); } else { game.deletePlayerResources(); - return LOSE; + return Optional.of(LOSE); } } diff --git a/src/edu/kit/informatik/cardgame/model/CardGame.java b/src/edu/kit/informatik/cardgame/model/CardGame.java index 9a4b7b8..f64a322 100644 --- a/src/edu/kit/informatik/cardgame/model/CardGame.java +++ b/src/edu/kit/informatik/cardgame/model/CardGame.java @@ -2,8 +2,8 @@ package edu.kit.informatik.cardgame.model; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -59,10 +59,6 @@ public class CardGame { // do not start a new game if one is active already return false; } - if (!Arrays.stream(Card.values()) - .allMatch(card -> Collections.frequency(cardStack, card) == card.requiredAmount())) { - throw new LogicException("invalid deck: missing or surplus cards"); - } this.cardStack = new CardStack(cardStack); this.inventory = new Inventory(); this.phase = Phase.SCAVENGE; @@ -72,7 +68,7 @@ public class CardGame { } /** - * Draw a new card. Will not process the card action ({@link Card#activate}). + * Draw a new card. Will automatically process the card action ({@link Card#activate}). * * @return the card * @throws LogicException if no card to draw exists or phase is not scavenge @@ -83,7 +79,9 @@ public class CardGame { } else if (phase != Phase.SCAVENGE) { throw new LogicException("can only draw cards in scavenge phase"); } - return cardStack.draw().orElseThrow(() -> new LogicException("no card to draw exists")); + final Card card = cardStack.draw().orElseThrow(() -> new LogicException("no card to draw exists")); + card.activate(this); + return card; } /** @@ -137,20 +135,23 @@ public class CardGame { * @throws LogicException if not expecting dice roll or dice roll is invalid */ public String rollDice(int size, int roll) throws LogicException { - if (requireDice == null) { + if (phase != Phase.AWAITING_DICE_ROLL) { throw new LogicException("not expecting dice roll"); - } else if (requireDice.diceSizeNeeded().get() != size) { - throw new LogicException("unexpected dice size"); - } else if (roll > size || roll < 1) { - throw new LogicException("impossible roll"); } - // leave encounter/endeavor phase - phase = Phase.SCAVENGE; // compute the result of the dice roll - final String result = requireDice.activate(this, size, roll); - // no longer waiting - requireDice = null; - return result; + final Optional result = requireDice.activate(this, size, roll); + if (result.isPresent()) { + // leave encounter/endeavor phase (only if player didn't win) + if (phase == Phase.AWAITING_DICE_ROLL) { + phase = Phase.SCAVENGE; + } + // no longer waiting + requireDice = null; + return result.get(); + } else { + // invalid user input + throw new LogicException("invalid dice input"); + } } /** @@ -182,14 +183,6 @@ public class CardGame { } } - /** - * End the game by forcing the player to win. - */ - public void winGame() { - endGame(); - phase = Phase.WON; - } - /** * Check whether this game ever received a {@link #start start} command. * @@ -228,6 +221,22 @@ public class CardGame { } } + /** + * End the game by forcing the player to win. + */ + public void winGame() { + endGame(); + phase = Phase.WON; + } + + /** + * End the current game, deleting the active card stack. + * Player resources and items are not deleted. + */ + private void endGame() { + cardStack.clearActiveStack(); + } + /** * Check whether the active game is lost. * A game is lost if no more player actions ({@link #draw}, {@link #build}, {@link #rollDice}) are possible and @@ -281,14 +290,6 @@ public class CardGame { return Arrays.stream(Item.values()).filter(inventory::canBuild).collect(Collectors.toSet()); } - /** - * End the current game, deleting the active card stack. - * Player resources and items are not deleted. - */ - private void endGame() { - cardStack.clearActiveStack(); - } - /** * Reset the game, restoring the {@link #cardStack original card stack} and clearing the player's inventory. * diff --git a/src/edu/kit/informatik/cardgame/model/CardStack.java b/src/edu/kit/informatik/cardgame/model/CardStack.java index 4041f13..3a68765 100644 --- a/src/edu/kit/informatik/cardgame/model/CardStack.java +++ b/src/edu/kit/informatik/cardgame/model/CardStack.java @@ -1,7 +1,9 @@ package edu.kit.informatik.cardgame.model; import java.util.ArrayDeque; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.Deque; import java.util.Optional; @@ -28,8 +30,13 @@ public class CardStack { * The first element will be {@link #draw drawn} first. * * @param cards (ordered) card collection + * @throws LogicException if card stack has wrong distribution of cards */ - public CardStack(Collection cards) { + public CardStack(Collection cards) throws LogicException { + if (!Arrays.stream(Card.values()) + .allMatch(card -> Collections.frequency(cards, card) == card.requiredAmount())) { + throw new LogicException("invalid deck: missing or surplus cards"); + } this.stack = new ArrayDeque<>(cards); reset(); } diff --git a/src/edu/kit/informatik/cardgame/model/Item.java b/src/edu/kit/informatik/cardgame/model/Item.java index b9fd322..b7cd7e7 100644 --- a/src/edu/kit/informatik/cardgame/model/Item.java +++ b/src/edu/kit/informatik/cardgame/model/Item.java @@ -91,20 +91,18 @@ public enum Item implements RequireDice { } @Override - public String activate(CardGame game, int diceSize, int roll) throws LogicException { - if (!this.minimumDiceRollNeeded().isPresent()) { + public Optional activate(CardGame game, int diceSize, int roll) { + if (!this.diceSizeNeeded().isPresent()) { throw new IllegalStateException("can not process dice roll"); - } else if (this.diceSizeNeeded().get() != diceSize) { - throw new LogicException("unexpected dice size"); - } else if (roll > diceSize || roll < 1) { - throw new LogicException("impossible roll"); + } else if (this.diceSizeNeeded().get() != diceSize || roll > diceSize || roll < 1) { + return Optional.empty(); } if (roll >= this.minimumDiceRollNeeded().get()) { game.winGame(); - return WIN; + return Optional.of(WIN); } else { - return LOSE; + return Optional.of(LOSE); } } diff --git a/src/edu/kit/informatik/cardgame/model/RequireDice.java b/src/edu/kit/informatik/cardgame/model/RequireDice.java index 9cc0c23..350d063 100644 --- a/src/edu/kit/informatik/cardgame/model/RequireDice.java +++ b/src/edu/kit/informatik/cardgame/model/RequireDice.java @@ -28,9 +28,8 @@ public interface RequireDice { * * @param game card game to use * @param diceSize size of the dice rolled - * @param rolled result of the dice roll - * @return activation result - * @throws LogicException if dice roll is incorrect + * @param roll result of the dice roll + * @return activation result (empty if dice roll is incorrect) */ - String activate(CardGame game, int diceSize, int rolled) throws LogicException; + Optional activate(CardGame game, int diceSize, int roll); } diff --git a/src/edu/kit/informatik/cardgame/ui/CommandLine.java b/src/edu/kit/informatik/cardgame/ui/CommandLine.java index 3742d4b..f7fa61c 100644 --- a/src/edu/kit/informatik/cardgame/ui/CommandLine.java +++ b/src/edu/kit/informatik/cardgame/ui/CommandLine.java @@ -40,9 +40,9 @@ public final class CommandLine { if (input.startsWith(QUIT)) { if (input.length() != QUIT.length()) { Terminal.printError("input after quit command"); - continue; + continue; // skip invalid quit command } else { - return; + return; // quit main loop otherwise } } diff --git a/src/edu/kit/informatik/cardgame/ui/command/Draw.java b/src/edu/kit/informatik/cardgame/ui/command/Draw.java index cdc09db..301a571 100644 --- a/src/edu/kit/informatik/cardgame/ui/command/Draw.java +++ b/src/edu/kit/informatik/cardgame/ui/command/Draw.java @@ -1,7 +1,6 @@ package edu.kit.informatik.cardgame.ui.command; import edu.kit.informatik.Terminal; -import edu.kit.informatik.cardgame.model.Card; import edu.kit.informatik.cardgame.model.CardGame; import edu.kit.informatik.cardgame.model.LogicException; import edu.kit.informatik.cardgame.ui.InvalidInputException; @@ -20,9 +19,7 @@ public final class Draw extends Command { @Override public void apply(CardGame game) throws LogicException { - final Card card = game.draw(); - Terminal.printLine(card); - card.activate(game); + Terminal.printLine(game.draw()); } @Override