Document code

This commit is contained in:
Arne Keller 2020-03-14 23:03:47 +01:00
parent cf7cd5ffaf
commit 9e75ca37a3
5 changed files with 97 additions and 14 deletions

View File

@ -10,13 +10,34 @@ import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/**
* Card game.
*
* @author Arne Keller
* @version 1.0
*/
public class CardGame { public class CardGame {
/**
* Copy of the card stack used to start the game.
*/
private Deque<Card> cardStack; private Deque<Card> cardStack;
/**
* Currently active card stack.
*/
private Deque<Card> currentCardStack; private Deque<Card> currentCardStack;
/**
* Resources collected by the player.
*/
private final Deque<Card> resources = new ArrayDeque<>(); private final Deque<Card> resources = new ArrayDeque<>();
/**
* Items built by the player.
*/
private final List<Item> items = new ArrayList<>(); private final List<Item> items = new ArrayList<>();
private Integer awaitedDiceSize = null; private Integer awaitedDiceSize = null;
private Integer minimumDiceRoll = null; private Integer minimumDiceRoll = null;
/**
* Current game phase.
*/
private Phase phase = null; private Phase phase = null;
/** /**
@ -116,6 +137,9 @@ public class CardGame {
} }
} }
/**
* Clear player resources, keeping a few items in the shack if one is built.
*/
private 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) {
@ -140,6 +164,7 @@ public class CardGame {
} else if (canBuild(item)) { } else if (canBuild(item)) {
// remove used resources // remove used resources
for (final Card resource : item.resourcesNeeded()) { for (final Card resource : item.resourcesNeeded()) {
// resources picked up last get used up first
resources.removeLastOccurrence(resource); resources.removeLastOccurrence(resource);
} }
items.add(item); items.add(item);
@ -168,11 +193,19 @@ public class CardGame {
} }
} }
/**
* Check whether the player can build the specified item with the currently available resources and items.
*
* @param item item to build
* @return whether that item can be built
*/
private boolean canBuild(Item item) { private boolean canBuild(Item item) {
if (!items.containsAll(item.itemsNeededToBuild())) { // check whether item is already built
if (items.contains(item)) {
return false; return false;
} }
if (items.contains(item)) { // make sure all of the required items are already built
if (!items.containsAll(item.itemsNeededToBuild())) {
return false; return false;
} }
final Card[] resourcesNeeded = item.resourcesNeeded(); final Card[] resourcesNeeded = item.resourcesNeeded();
@ -187,18 +220,28 @@ public class CardGame {
return Arrays.stream(resourcesNeeded).allMatch(Objects::isNull); return Arrays.stream(resourcesNeeded).allMatch(Objects::isNull);
} }
/**
* @return whether the game was ever started
*/
private boolean gameStarted() { private boolean gameStarted() {
return phase != null; return phase != null;
} }
/**
* @return whether the game is currently active
*/
private boolean gameActive() { private boolean gameActive() {
return gameStarted() && phase != Phase.WON && phase != Phase.LOST; return gameStarted() && phase != Phase.WON && phase != Phase.LOST;
} }
/**
* Check whether the player lost, updating the game state accordingly.
*
* @see CardGame#gameLost
*/
private void checkLost() { private void checkLost() {
if (phase != Phase.LOST // can not draw new cards
// can not draw new cards if (currentCardStack != null && currentCardStack.isEmpty()
&& currentCardStack != null && currentCardStack.isEmpty()
// can not roll dice // can not roll dice
&& phase != Phase.ENCOUNTER && phase != Phase.ENDEAVOR && phase != Phase.ENCOUNTER && phase != Phase.ENDEAVOR
// can not build item // can not build item

View File

@ -1,6 +1,5 @@
package edu.kit.informatik.cardgame.model; package edu.kit.informatik.cardgame.model;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -25,7 +24,7 @@ public enum Item {
*/ */
CLUB, CLUB,
/** /**
* Shack. Can save the last five items. * Shack. Can save the last five items in case of animal attacks or catastrophic events.
*/ */
SHACK, SHACK,
/** /**
@ -87,7 +86,7 @@ public enum Item {
switch (this) { switch (this) {
case BALLON: case BALLON:
case STEAMBOAT: case STEAMBOAT:
return Arrays.asList(FIREPLACE); return Collections.singletonList(FIREPLACE);
default: default:
return Collections.emptyList(); return Collections.emptyList();
} }
@ -109,10 +108,20 @@ public enum Item {
} }
} }
/**
* Get the amount of resources this item can save in case of an animal attack or a catastrophic event.
*
* @return amount of resources this item protects
*/
public int itemsSecured() { public int itemsSecured() {
return this == Item.SHACK ? 5 : 0; return this == Item.SHACK ? 5 : 0;
} }
/**
* Check whether this item requires rolling a dice to take effect.
*
* @return whether the player has to roll a dice after building this item
*/
public boolean requiresDice() { public boolean requiresDice() {
switch (this) { switch (this) {
case HANG_GLIDER: case HANG_GLIDER:
@ -123,6 +132,11 @@ public enum Item {
} }
} }
/**
* Get the size of the dice to roll after building this item.
*
* @return size of the dice to roll, or 0 if not necessary
*/
public int diceSizeNeeded() { public int diceSizeNeeded() {
switch (this) { switch (this) {
case HANG_GLIDER: case HANG_GLIDER:
@ -133,6 +147,11 @@ public enum Item {
} }
} }
/**
* Get the minimum dice roll needed to activate this item if it needs a dice roll.
*
* @return minimum dice roll needed to use this item
*/
public int minimumDiceRollNeeded() { public int minimumDiceRollNeeded() {
switch (this) { switch (this) {
case HANG_GLIDER: case HANG_GLIDER:
@ -143,6 +162,11 @@ public enum Item {
} }
} }
/**
* Get the category of this item.
*
* @return category of this item
*/
public ItemCategory category() { public ItemCategory category() {
switch (this) { switch (this) {
case BALLON: case BALLON:

View File

@ -1,6 +1,17 @@
package edu.kit.informatik.cardgame.model; package edu.kit.informatik.cardgame.model;
/**
* Thrown on semantically invalid user input.
*
* @author Arne Keller
* @version 1.0
*/
public class LogicException extends Exception { public class LogicException extends Exception {
/**
* Construct a new {@link LogicException} with the specified message.
*
* @param message error message
*/
public LogicException(String message) { public LogicException(String message) {
super(message); super(message);
} }

View File

@ -38,12 +38,6 @@ public final class CommandLine {
while (true) { while (true) {
String input = Terminal.readLine(); String input = Terminal.readLine();
if (input.startsWith("startn")) {
// TODO remove
StringJoiner j = new StringJoiner(",");
IntStream.range(0, 64).mapToObj(x -> Terminal.readLine()).forEach(j::add);
input = "start " + j.toString();
}
if (input.startsWith(QUIT)) { if (input.startsWith(QUIT)) {
if (input.length() != QUIT.length()) { if (input.length() != QUIT.length()) {

View File

@ -1,6 +1,17 @@
package edu.kit.informatik.cardgame.ui; package edu.kit.informatik.cardgame.ui;
/**
* Thrown on syntactically invalid user input.
*
* @author Arne Keller
* @version 1.0
*/
public class InvalidInputException extends Exception { public class InvalidInputException extends Exception {
/**
* Construct a new {@link InvalidInputException} with the specified message.
*
* @param message error message
*/
public InvalidInputException(String message) { public InvalidInputException(String message) {
super(message); super(message);
} }