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.Set;
import java.util.stream.Collectors; 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 { public class CardGame {
private Deque<Card> cardStack; private Deque<Card> cardStack;
private Deque<Card> currentCardStack; private Deque<Card> currentCardStack;
@ -60,7 +53,7 @@ public class CardGame {
phase = Phase.ENCOUNTER; phase = Phase.ENCOUNTER;
} else if (card.isCatastrophe()) { } else if (card.isCatastrophe()) {
clearResources(); clearResources();
items.remove(FIREPLACE); items.remove(Item.FIREPLACE);
} }
if (currentCardStack.isEmpty() && getBuildableItems().isEmpty()) { if (currentCardStack.isEmpty() && getBuildableItems().isEmpty()) {
endGame(); endGame();
@ -103,7 +96,7 @@ public class CardGame {
} }
public void clearResources() { public void clearResources() {
final int keepLastResources = items.contains(SHACK) ? 5 : 0; final int keepLastResources = items.stream().mapToInt(Item::itemsSecured).sum();
while (resources.size() > keepLastResources) { while (resources.size() > keepLastResources) {
resources.removeFirst(); resources.removeFirst();
} }
@ -122,20 +115,28 @@ public class CardGame {
resources.removeLastOccurrence(resource); resources.removeLastOccurrence(resource);
} }
items.add(item); items.add(item);
if (item.equals(STEAMBOAT) || item.equals(BALLON)) { 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 // player won
endGame(); endGame();
phase = Phase.WON; phase = Phase.WON;
return "win"; return "win";
} else if (item.equals(SAILING_RAFT) || item.equals(HANG_GLIDER)) { }
// need at least a 4/d6 break;
awaitedDiceSize = 6; case DEFAULT:
minimumDiceRoll = 4; if (currentCardStack != null && currentCardStack.isEmpty() && getBuildableItems().isEmpty()) {
phase = Phase.ENDEAVOR;
} else if (currentCardStack != null && currentCardStack.isEmpty() && getBuildableItems().isEmpty()) {
endGame(); endGame();
phase = Phase.LOST; phase = Phase.LOST;
} }
break;
}
return "OK"; return "OK";
} else { } else {
return null; return null;
@ -174,7 +175,7 @@ public class CardGame {
} }
public Deque<Card> getResources() throws LogicException { public Deque<Card> getResources() throws LogicException {
if (!gameStarted()) { if (!gameActive()) {
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
@ -182,7 +183,7 @@ public class CardGame {
} }
public List<Item> getItems() throws LogicException { public List<Item> getItems() throws LogicException {
if (!gameStarted()) { if (!gameActive()) {
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 // 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. * Parse a single word and return the item represented by the input.
* Fun fact: Item.parse(item.toString()) == item is true for all items. * 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;
}