From 0b913bf943479601d23653d381ca2619c49eb9e7 Mon Sep 17 00:00:00 2001 From: Arne Keller Date: Thu, 12 Mar 2020 09:18:45 +0100 Subject: [PATCH] Simplify game phase logic --- game_over_no_materials_output.txt | 1 + .../informatik/cardgame/model/CardGame.java | 57 ++++++++++++------- .../informatik/cardgame/ui/CommandLine.java | 5 ++ 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/game_over_no_materials_output.txt b/game_over_no_materials_output.txt index 50736e4..7ae34c0 100644 --- a/game_over_no_materials_output.txt +++ b/game_over_no_materials_output.txt @@ -78,5 +78,6 @@ thunderstorm wood wood wood +OK lost Error, can not get resources: game not started diff --git a/src/edu/kit/informatik/cardgame/model/CardGame.java b/src/edu/kit/informatik/cardgame/model/CardGame.java index 917222f..733eec6 100644 --- a/src/edu/kit/informatik/cardgame/model/CardGame.java +++ b/src/edu/kit/informatik/cardgame/model/CardGame.java @@ -22,9 +22,9 @@ public class CardGame { private Deque currentCardStack; private final Deque resources = new ArrayDeque<>(); private final List items = new ArrayList<>(); - private boolean fightingAnimal = false; private Integer awaitedDiceSize = null; private Integer minimumDiceRoll = null; + private Phase phase = null; /** * Start a new game with the specified stack of cards. @@ -33,7 +33,7 @@ public class CardGame { * @return whether the game could be successfully started */ public boolean start(Deque cardStack) throws LogicException { - if (gameStarted()) { + if (gameActive()) { return false; } if (!Arrays.stream(Card.values()) @@ -48,28 +48,29 @@ public class CardGame { public Card draw() throws LogicException { if (currentCardStack == null || currentCardStack.isEmpty()) { throw new LogicException("no card to draw exists"); - } else if (awaitingDiceRoll()) { - throw new LogicException("roll dice, please"); + } else if (phase != Phase.SCAVENGE) { + throw new LogicException("can only draw cards in scavenge phase"); } final Card card = currentCardStack.removeFirst(); if (card.isResource()) { resources.add(card); } else if (card.needsDiceRoll()) { - fightingAnimal = true; awaitedDiceSize = card.diceSizeNeeded(); minimumDiceRoll = card.minimumDiceRollNeeded(); + phase = Phase.ENCOUNTER; } else if (card.isCatastrophe()) { clearResources(); items.remove(FIREPLACE); } if (currentCardStack.isEmpty() && getBuildableItems().isEmpty()) { - endGame(); // TODO: somehow print "lost" ??? (after the card!) [awaiting ILIAS..] + endGame(); + this.phase = Phase.LOST; } return card; } public String rollDice(int size, int roll) throws LogicException { - if (!awaitingDiceRoll()) { + if (phase != Phase.ENDEAVOR && phase != Phase.ENCOUNTER) { throw new LogicException("not expecting dice roll"); } else if (awaitedDiceSize != size) { throw new LogicException("unexpected dice size"); @@ -79,8 +80,9 @@ public class CardGame { awaitedDiceSize = null; final int minimumNeeded = minimumDiceRoll; minimumDiceRoll = null; - if (fightingAnimal) { + if (phase == Phase.ENCOUNTER) { final int bonus = items.stream().mapToInt(Item::fightingBonus).max().orElse(0); + phase = Phase.SCAVENGE; if (roll + bonus >= minimumNeeded) { return "survived"; } else { @@ -92,8 +94,10 @@ public class CardGame { items.remove(items.size() - 1); if (roll >= minimumNeeded) { endGame(); + phase = Phase.WON; return "win"; } else { + phase = Phase.SCAVENGE; return "lose"; } } @@ -109,8 +113,8 @@ public class CardGame { public String build(Item item) throws LogicException { if (item == null) { throw new LogicException("can not build item"); - } else if (awaitingDiceRoll()) { - throw new LogicException("awaiting dice roll, can not build"); + } else if (phase != Phase.SCAVENGE) { + throw new LogicException("can only build in scavenge phase"); } else if (items.contains(item)) { throw new LogicException("already built"); } else if (canBuild(item)) { @@ -122,15 +126,16 @@ public class CardGame { if (item.equals(STEAMBOAT) || item.equals(BALLON)) { // player won endGame(); + phase = Phase.WON; return "win"; } else if (item.equals(SAILING_RAFT) || item.equals(HANG_GLIDER)) { // need at least a 4/d6 - fightingAnimal = false; awaitedDiceSize = 6; minimumDiceRoll = 4; + phase = Phase.ENDEAVOR; } else if (currentCardStack != null && currentCardStack.isEmpty() && getBuildableItems().isEmpty()) { endGame(); - return "lost"; + phase = Phase.LOST; } return "OK"; } else { @@ -158,15 +163,19 @@ public class CardGame { } private boolean gameStarted() { - return currentCardStack != null; + return phase != null; } - private boolean awaitingDiceRoll() { - return awaitedDiceSize != null; + private boolean gameActive() { + return gameStarted() && phase != Phase.WON && phase != Phase.LOST; + } + + public boolean gameLost() { + return phase == Phase.LOST; } public Deque getResources() throws LogicException { - if (!gameStarted()) { + if (!gameActive()) { throw new LogicException("can not get resources: game not started"); } // do not allow caller to modify internal queue @@ -174,7 +183,7 @@ public class CardGame { } public List getItems() throws LogicException { - if (!gameStarted()) { + if (!gameActive()) { throw new LogicException("can not get buildings: game not started"); } // do not allow caller to modify internal list @@ -182,10 +191,10 @@ public class CardGame { } public Set getBuildableItems() throws LogicException { - if (!gameStarted()) { + if (!gameActive()) { throw new LogicException("can not get buildable items: game not started"); } - if (awaitingDiceRoll()) { + if (phase != Phase.SCAVENGE) { throw new LogicException("can not get buildable items: awaiting dice roll"); } return Arrays.stream(Item.values()).filter(this::canBuild).collect(Collectors.toSet()); @@ -203,8 +212,16 @@ public class CardGame { } this.resources.clear(); this.items.clear(); - this.fightingAnimal = false; this.awaitedDiceSize = null; this.minimumDiceRoll = null; + this.phase = Phase.SCAVENGE; + } + + enum Phase { + SCAVENGE, + ENCOUNTER, + ENDEAVOR, + WON, + LOST } } diff --git a/src/edu/kit/informatik/cardgame/ui/CommandLine.java b/src/edu/kit/informatik/cardgame/ui/CommandLine.java index 1de445b..8b04ecd 100644 --- a/src/edu/kit/informatik/cardgame/ui/CommandLine.java +++ b/src/edu/kit/informatik/cardgame/ui/CommandLine.java @@ -34,6 +34,7 @@ public final class CommandLine { public static void startInteractive() { // create a new simulation CardGame simulation = new CardGame(); + boolean lost = false; while (true) { String input = Terminal.readLine(); @@ -67,6 +68,10 @@ public final class CommandLine { } catch (LogicException e) { Terminal.printError(e.getMessage()); } + if (lost != simulation.gameLost() && simulation.gameLost()) { + Terminal.printLine("lost"); + } + lost = simulation.gameLost(); } } }