Refactor game logic to handle items in generic way

This commit is contained in:
Arne Keller 2020-03-12 22:02:03 +01:00
parent d2ddd3cad9
commit 5535692596
3 changed files with 77 additions and 24 deletions

View File

@ -10,13 +10,6 @@ import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import static edu.kit.informatik.cardgame.model.Item.BALLON;
import static edu.kit.informatik.cardgame.model.Item.FIREPLACE;
import static edu.kit.informatik.cardgame.model.Item.HANG_GLIDER;
import static edu.kit.informatik.cardgame.model.Item.SAILING_RAFT;
import static edu.kit.informatik.cardgame.model.Item.SHACK;
import static edu.kit.informatik.cardgame.model.Item.STEAMBOAT;
public class CardGame {
private Deque<Card> cardStack;
private Deque<Card> currentCardStack;
@ -60,7 +53,7 @@ public class CardGame {
phase = Phase.ENCOUNTER;
} else if (card.isCatastrophe()) {
clearResources();
items.remove(FIREPLACE);
items.remove(Item.FIREPLACE);
}
if (currentCardStack.isEmpty() && getBuildableItems().isEmpty()) {
endGame();
@ -103,7 +96,7 @@ public class CardGame {
}
public void clearResources() {
final int keepLastResources = items.contains(SHACK) ? 5 : 0;
final int keepLastResources = items.stream().mapToInt(Item::itemsSecured).sum();
while (resources.size() > keepLastResources) {
resources.removeFirst();
}
@ -122,19 +115,27 @@ public class CardGame {
resources.removeLastOccurrence(resource);
}
items.add(item);
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
awaitedDiceSize = 6;
minimumDiceRoll = 4;
phase = Phase.ENDEAVOR;
} else if (currentCardStack != null && currentCardStack.isEmpty() && getBuildableItems().isEmpty()) {
endGame();
phase = Phase.LOST;
switch (item.category()) {
case ESCAPE:
if (item.requiresDice()) {
// need at least a 4/d6
awaitedDiceSize = item.diceSizeNeeded();
minimumDiceRoll = item.minimumDiceRollNeeded();
phase = Phase.ENDEAVOR;
} else {
// player won
endGame();
phase = Phase.WON;
return "win";
}
break;
case DEFAULT:
if (currentCardStack != null && currentCardStack.isEmpty() && getBuildableItems().isEmpty()) {
endGame();
phase = Phase.LOST;
}
break;
}
return "OK";
} else {
@ -174,7 +175,7 @@ public class CardGame {
}
public Deque<Card> 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
@ -182,7 +183,7 @@ public class CardGame {
}
public List<Item> 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

View File

@ -102,6 +102,52 @@ public enum Item {
}
}
public int itemsSecured() {
return this == Item.SHACK ? 5 : 0;
}
public boolean requiresDice() {
switch (this) {
case HANG_GLIDER:
case SAILING_RAFT:
return true;
default:
return false;
}
}
public int diceSizeNeeded() {
switch (this) {
case HANG_GLIDER:
case SAILING_RAFT:
return 6;
default:
return 0;
}
}
public int minimumDiceRollNeeded() {
switch (this) {
case HANG_GLIDER:
case SAILING_RAFT:
return 4;
default:
return 0;
}
}
public ItemCategory category() {
switch (this) {
case BALLON:
case HANG_GLIDER:
case SAILING_RAFT:
case STEAMBOAT:
return ItemCategory.ESCAPE;
default:
return ItemCategory.DEFAULT;
}
}
/**
* Parse a single word and return the item represented by the input.
* Fun fact: Item.parse(item.toString()) == item is true for all items.

View File

@ -0,0 +1,6 @@
package edu.kit.informatik.cardgame.model;
public enum ItemCategory {
DEFAULT,
ESCAPE;
}