Javadoc + allow various command during game end phase

This commit is contained in:
Arne Keller 2020-03-13 09:30:26 +01:00
parent 40370b8c80
commit 6d4db9f12b
5 changed files with 124 additions and 9 deletions

View File

@ -1,5 +1,12 @@
package edu.kit.informatik.cardgame.model; package edu.kit.informatik.cardgame.model;
/**
* Game card.
*
* @see CardCategory
* @author Arne Keller
* @version 1.0
*/
public enum Card { public enum Card {
/** /**
* Wood. Basic resource. * Wood. Basic resource.

View File

@ -1,7 +1,23 @@
package edu.kit.informatik.cardgame.model; package edu.kit.informatik.cardgame.model;
/**
* Card category. Game cards are categorized into three categories depending on their properties.
*
* @see Card
* @author Arne Keller
* @version 1.0
*/
public enum CardCategory { public enum CardCategory {
/**
* Basic resource card, harmless.
*/
RESOURCE, RESOURCE,
/**
* Animal card, can attack player.
*/
ANIMAL, ANIMAL,
/**
* Catastrophic card, can not harm player.
*/
CATASTROPHE CATASTROPHE
} }

View File

@ -21,6 +21,7 @@ public class CardGame {
/** /**
* Start a new game with the specified stack of cards. * Start a new game with the specified stack of cards.
*
* @param cardStack stack of cards to use, where the first element is the first to take * @param cardStack stack of cards to use, where the first element is the first to take
* @throws LogicException if card stack has wrong distribution of cards * @throws LogicException if card stack has wrong distribution of cards
* @return whether the game could be successfully started * @return whether the game could be successfully started
@ -38,6 +39,13 @@ public class CardGame {
return true; return true;
} }
/**
* Draw a new card. Will automatically add the card to the players resources, start an encounter or let the
* thunderstorm do its work.
*
* @return the card
* @throws LogicException if no card to draw exists or phase is not scavenge
*/
public Card draw() throws LogicException { public Card draw() throws LogicException {
if (currentCardStack == null || currentCardStack.isEmpty()) { if (currentCardStack == null || currentCardStack.isEmpty()) {
throw new LogicException("no card to draw exists"); throw new LogicException("no card to draw exists");
@ -65,6 +73,14 @@ public class CardGame {
return card; return card;
} }
/**
* Roll a dice with the specified size and result.
*
* @param size dice size
* @param roll dice result
* @return result of the throw (survived, lose or win)
* @throws LogicException if not expecting dice roll or dice roll is invalid
*/
public String rollDice(int size, int roll) throws LogicException { public String rollDice(int size, int roll) throws LogicException {
if (phase != Phase.ENDEAVOR && phase != Phase.ENCOUNTER) { if (phase != Phase.ENDEAVOR && phase != Phase.ENCOUNTER) {
throw new LogicException("not expecting dice roll"); throw new LogicException("not expecting dice roll");
@ -100,13 +116,20 @@ public class CardGame {
} }
} }
public void clearResources() { private void clearResources() {
final int keepLastResources = items.stream().mapToInt(Item::itemsSecured).sum(); final int keepLastResources = items.stream().mapToInt(Item::itemsSecured).sum();
while (resources.size() > keepLastResources) { while (resources.size() > keepLastResources) {
resources.removeFirst(); resources.removeFirst();
} }
} }
/**
* Attempt to build the specified item.
*
* @param item item to build
* @return building result (OK or win), or null if item can not be built
* @throws LogicException if in wrong phase or item already built
*/
public String build(Item item) throws LogicException { public String build(Item item) throws LogicException {
if (item == null) { if (item == null) {
throw new LogicException("can not build item"); throw new LogicException("can not build item");
@ -134,7 +157,7 @@ public class CardGame {
return "win"; return "win";
} }
break; break;
case DEFAULT: default:
checkLost(); checkLost();
break; break;
@ -174,39 +197,65 @@ public class CardGame {
private void checkLost() { private void checkLost() {
if (phase != Phase.LOST if (phase != Phase.LOST
// can not draw new cards
&& currentCardStack != null && currentCardStack.isEmpty() && currentCardStack != null && currentCardStack.isEmpty()
// can not roll dice
&& phase != Phase.ENCOUNTER && phase != Phase.ENDEAVOR && phase != Phase.ENCOUNTER && phase != Phase.ENDEAVOR
&& !Arrays.stream(Item.values()).anyMatch(this::canBuild)) { // can not build item
&& Arrays.stream(Item.values()).noneMatch(this::canBuild)) {
endGame(); endGame();
phase = Phase.LOST; phase = Phase.LOST;
} }
} }
/**
* Check whether the active game is lost. The game is lost if no cards to draw exist and no further actions are
* possible.
*
* @return whether the active game is lost
*/
public boolean gameLost() { public boolean gameLost() {
return phase == Phase.LOST; return phase == Phase.LOST;
} }
/**
* Get the resources available for building.
*
* @return resources available
* @throws LogicException if no game is active
*/
public Deque<Card> getResources() throws LogicException { public Deque<Card> getResources() throws LogicException {
if (!gameActive()) { if (!gameStarted()) {
throw new LogicException("can not get resources: game not started"); throw new LogicException("can not get resources: game not started");
} }
// do not allow caller to modify internal queue // do not allow caller to modify internal queue
return new ArrayDeque<>(resources); return new ArrayDeque<>(resources);
} }
/**
* Get the items already built.
*
* @return items owned by the player
* @throws LogicException if no game is active
*/
public List<Item> getItems() throws LogicException { public List<Item> getItems() throws LogicException {
if (!gameActive()) { if (!gameStarted()) {
throw new LogicException("can not get buildings: game not started"); throw new LogicException("can not get buildings: game not started");
} }
// do not allow caller to modify internal list // have to copy here: caller does not expect an auto-updating list
return new ArrayList<>(items); return new ArrayList<>(items);
} }
/**
* Get the currently buildable items.
*
* @return set of items currently buildable
* @throws LogicException if game not in scavenge phase
*/
public Set<Item> getBuildableItems() throws LogicException { public Set<Item> getBuildableItems() throws LogicException {
if (!gameActive()) { if (!gameStarted()) {
throw new LogicException("can not get buildable items: game not started"); throw new LogicException("can not get buildable items: game not started");
} } else if (phase != Phase.SCAVENGE) {
if (phase != Phase.SCAVENGE) {
throw new LogicException("can not get buildable items: awaiting dice roll"); throw new LogicException("can not get buildable items: awaiting dice roll");
} }
return Arrays.stream(Item.values()).filter(this::canBuild).collect(Collectors.toSet()); return Arrays.stream(Item.values()).filter(this::canBuild).collect(Collectors.toSet());
@ -216,6 +265,11 @@ public class CardGame {
currentCardStack = null; currentCardStack = null;
} }
/**
* Reset the game, restoring the original card stack.
*
* @throws LogicException if game was never started
*/
public void reset() throws LogicException { public void reset() throws LogicException {
if (cardStack == null) { if (cardStack == null) {
throw new LogicException("can not reset a game that is not started!"); throw new LogicException("can not reset a game that is not started!");
@ -229,11 +283,29 @@ public class CardGame {
this.phase = Phase.SCAVENGE; this.phase = Phase.SCAVENGE;
} }
/**
* Game phase.
*/
enum Phase { enum Phase {
/**
* Player can draw cards and build.
*/
SCAVENGE, SCAVENGE,
/**
* Player has to fight an animal.
*/
ENCOUNTER, ENCOUNTER,
/**
* Player is attempting to escape.
*/
ENDEAVOR, ENDEAVOR,
/**
* Player won.
*/
WON, WON,
/**
* Player lost.
*/
LOST LOST
} }
} }

View File

@ -8,6 +8,13 @@ import static edu.kit.informatik.cardgame.model.Card.METAL;
import static edu.kit.informatik.cardgame.model.Card.PLASTIC; import static edu.kit.informatik.cardgame.model.Card.PLASTIC;
import static edu.kit.informatik.cardgame.model.Card.WOOD; import static edu.kit.informatik.cardgame.model.Card.WOOD;
/**
* Game item.
*
* @see ItemCategory
* @author Arne Keller
* @version 1.0
*/
public enum Item { public enum Item {
/** /**
* Axe. Provides an attack bonus of two. * Axe. Provides an attack bonus of two.

View File

@ -1,6 +1,19 @@
package edu.kit.informatik.cardgame.model; package edu.kit.informatik.cardgame.model;
/**
* Item category. Game items are categorized into two categories: normal items and items used to escape.
*
* @see Item
* @author Arne Keller
* @version 1.0
*/
public enum ItemCategory { public enum ItemCategory {
/**
* Normal item, can not be used to escape.
*/
DEFAULT, DEFAULT,
/**
* Item that can be used to escape.
*/
ESCAPE; ESCAPE;
} }